From 29b887939af1f39a70677514b5169c1c0b376e1a Mon Sep 17 00:00:00 2001 From: "Achim D. Brucker" Date: Sat, 6 Jun 2015 20:17:20 +0200 Subject: [PATCH] Initial import from git@github.com:GenericBreakGlass/GenericBreakGlass-XACML.git (34c2ebc0cc). --- GenericBreakGlass-XACML/LICENSE | 202 +++ GenericBreakGlass-XACML/README.md | 6 + GenericBreakGlass-XACML/src/.gitignore | 5 + .../src/com.sun.xacml.support/pom.xml | 41 + .../com/sun/xacml/support/DOMLinesParser.java | 134 ++ .../java/com/sun/xacml/support/SimplePDP.java | 236 +++ .../finder/BasicPolicyFinderModule.java | 253 +++ .../support/finder/FilePolicyModule.java | 328 ++++ .../support/finder/PolicyCollection.java | 376 +++++ .../xacml/support/finder/PolicyReader.java | 429 +++++ .../finder/StaticPolicyFinderModule.java | 320 ++++ .../finder/StaticRefPolicyFinderModule.java | 226 +++ .../finder/TopLevelPolicyException.java | 132 ++ .../support/finder/URLPolicyFinderModule.java | 209 +++ .../java/com/sun/xacml/support/AppTest.java | 73 + .../src/com.sun.xacml/pom.xml | 65 + .../java/com/sun/xacml/AbstractPolicy.java | 820 ++++++++++ .../com/sun/xacml/BasicEvaluationCtx.java | 1154 ++++++++++++++ .../com/sun/xacml/ConfigurationStore.java | 1408 +++++++++++++++++ .../main/java/com/sun/xacml/Constants.java | 262 +++ .../java/com/sun/xacml/EvaluationCtx.java | 342 ++++ .../src/main/java/com/sun/xacml/Indenter.java | 139 ++ .../main/java/com/sun/xacml/MatchElement.java | 11 + .../main/java/com/sun/xacml/MatchResult.java | 130 ++ .../main/java/com/sun/xacml/Obligation.java | 369 +++++ .../src/main/java/com/sun/xacml/PDP.java | 480 ++++++ .../main/java/com/sun/xacml/PDPConfig.java | 185 +++ .../java/com/sun/xacml/ParsingException.java | 105 ++ .../src/main/java/com/sun/xacml/Policy.java | 819 ++++++++++ .../java/com/sun/xacml/PolicyMetaData.java | 306 ++++ .../java/com/sun/xacml/PolicyReference.java | 647 ++++++++ .../main/java/com/sun/xacml/PolicySet.java | 696 ++++++++ .../java/com/sun/xacml/PolicyTreeElement.java | 149 ++ .../com/sun/xacml/ProcessingException.java | 107 ++ .../src/main/java/com/sun/xacml/Rule.java | 509 ++++++ .../src/main/java/com/sun/xacml/Target.java | 390 +++++ .../main/java/com/sun/xacml/TargetMatch.java | 537 +++++++ .../java/com/sun/xacml/TargetMatchGroup.java | 330 ++++ .../java/com/sun/xacml/TargetSection.java | 382 +++++ .../sun/xacml/UnknownIdentifierException.java | 71 + .../com/sun/xacml/VersionConstraints.java | 241 +++ .../com/sun/xacml/attr/AnyURIAttribute.java | 201 +++ .../sun/xacml/attr/AttributeDesignator.java | 552 +++++++ .../com/sun/xacml/attr/AttributeFactory.java | 401 +++++ .../sun/xacml/attr/AttributeFactoryProxy.java | 58 + .../com/sun/xacml/attr/AttributeProxy.java | 80 + .../com/sun/xacml/attr/AttributeSelector.java | 421 +++++ .../com/sun/xacml/attr/AttributeValue.java | 254 +++ .../java/com/sun/xacml/attr/BagAttribute.java | 265 ++++ .../main/java/com/sun/xacml/attr/Base64.java | 379 +++++ .../sun/xacml/attr/Base64BinaryAttribute.java | 251 +++ .../sun/xacml/attr/BaseAttributeFactory.java | 267 ++++ .../com/sun/xacml/attr/BooleanAttribute.java | 308 ++++ .../com/sun/xacml/attr/DNSNameAttribute.java | 292 ++++ .../com/sun/xacml/attr/DateAttribute.java | 714 +++++++++ .../com/sun/xacml/attr/DateTimeAttribute.java | 754 +++++++++ .../xacml/attr/DayTimeDurationAttribute.java | 585 +++++++ .../com/sun/xacml/attr/DecisionAttribute.java | 99 ++ .../com/sun/xacml/attr/DoubleAttribute.java | 218 +++ .../sun/xacml/attr/HexBinaryAttribute.java | 326 ++++ .../sun/xacml/attr/IPAddressAttribute.java | 269 ++++ .../sun/xacml/attr/IPv4AddressAttribute.java | 179 +++ .../sun/xacml/attr/IPv6AddressAttribute.java | 170 ++ .../com/sun/xacml/attr/IntegerAttribute.java | 202 +++ .../java/com/sun/xacml/attr/PortRange.java | 264 ++++ .../sun/xacml/attr/RFC822NameAttribute.java | 199 +++ .../xacml/attr/StandardAttributeFactory.java | 265 ++++ .../com/sun/xacml/attr/StringAttribute.java | 228 +++ .../com/sun/xacml/attr/TimeAttribute.java | 522 ++++++ .../xacml/attr/TypeIdentifierConstants.java | 78 + .../com/sun/xacml/attr/X500NameAttribute.java | 203 +++ .../attr/YearMonthDurationAttribute.java | 428 +++++ .../main/java/com/sun/xacml/attr/package.html | 7 + .../attr/proxy/AnyURIAttributeProxy.java | 70 + .../proxy/Base64BinaryAttributeProxy.java | 64 + .../attr/proxy/BooleanAttributeProxy.java | 64 + .../attr/proxy/DNSNameAttributeProxy.java | 65 + .../xacml/attr/proxy/DateAttributeProxy.java | 64 + .../attr/proxy/DateTimeAttributeProxy.java | 64 + .../proxy/DayTimeDurationAttributeProxy.java | 64 + .../attr/proxy/DoubleAttributeProxy.java | 64 + .../attr/proxy/HexBinaryAttributeProxy.java | 64 + .../attr/proxy/IPAddressAttributeProxy.java | 66 + .../attr/proxy/IntegerAttributeProxy.java | 64 + .../attr/proxy/RFC822NameAttributeProxy.java | 64 + .../attr/proxy/StringAttributeProxy.java | 65 + .../xacml/attr/proxy/TimeAttributeProxy.java | 64 + .../attr/proxy/X500NameAttributeProxy.java | 64 + .../YearMonthDurationAttributeProxy.java | 64 + .../com/sun/xacml/attr/proxy/package.html | 8 + .../combine/BaseCombiningAlgFactory.java | 156 ++ .../sun/xacml/combine/CombinerElement.java | 130 ++ .../sun/xacml/combine/CombinerParameter.java | 204 +++ .../xacml/combine/CombiningAlgFactory.java | 273 ++++ .../combine/CombiningAlgFactoryProxy.java | 58 + .../sun/xacml/combine/CombiningAlgorithm.java | 161 ++ .../xacml/combine/DenyOverridesPolicyAlg.java | 179 +++ .../xacml/combine/DenyOverridesRuleAlg.java | 184 +++ .../combine/FirstApplicablePolicyAlg.java | 152 ++ .../xacml/combine/FirstApplicableRuleAlg.java | 128 ++ .../combine/OnlyOneApplicablePolicyAlg.java | 175 ++ .../OrderedDenyOverridesPolicyAlg.java | 85 + .../combine/OrderedDenyOverridesRuleAlg.java | 85 + .../OrderedPermitOverridesPolicyAlg.java | 85 + .../OrderedPermitOverridesRuleAlg.java | 85 + .../combine/PermitOverridesPolicyAlg.java | 195 +++ .../xacml/combine/PermitOverridesRuleAlg.java | 184 +++ .../xacml/combine/PolicyCombinerElement.java | 167 ++ .../combine/PolicyCombiningAlgorithm.java | 93 ++ .../xacml/combine/RuleCombinerElement.java | 134 ++ .../xacml/combine/RuleCombiningAlgorithm.java | 81 + .../combine/StandardCombiningAlgFactory.java | 209 +++ .../java/com/sun/xacml/combine/package.html | 7 + .../java/com/sun/xacml/cond/AbsFunction.java | 168 ++ .../java/com/sun/xacml/cond/AddFunction.java | 187 +++ .../main/java/com/sun/xacml/cond/Apply.java | 459 ++++++ .../java/com/sun/xacml/cond/BagFunction.java | 289 ++++ .../sun/xacml/cond/BaseFunctionFactory.java | 418 +++++ .../xacml/cond/BasicFunctionFactoryProxy.java | 81 + .../sun/xacml/cond/ComparisonFunction.java | 711 +++++++++ .../java/com/sun/xacml/cond/Condition.java | 409 +++++ .../sun/xacml/cond/ConditionBagFunction.java | 167 ++ .../sun/xacml/cond/ConditionSetFunction.java | 269 ++++ .../com/sun/xacml/cond/DateMathFunction.java | 373 +++++ .../com/sun/xacml/cond/DivideFunction.java | 179 +++ .../com/sun/xacml/cond/EqualFunction.java | 299 ++++ .../java/com/sun/xacml/cond/Evaluatable.java | 75 + .../com/sun/xacml/cond/EvaluationResult.java | 195 +++ .../java/com/sun/xacml/cond/Expression.java | 108 ++ .../com/sun/xacml/cond/ExpressionHandler.java | 138 ++ .../com/sun/xacml/cond/FloorFunction.java | 122 ++ .../java/com/sun/xacml/cond/Function.java | 169 ++ .../java/com/sun/xacml/cond/FunctionBase.java | 763 +++++++++ .../com/sun/xacml/cond/FunctionFactory.java | 566 +++++++ .../sun/xacml/cond/FunctionFactoryProxy.java | 76 + .../com/sun/xacml/cond/FunctionProxy.java | 70 + .../sun/xacml/cond/FunctionTypeException.java | 107 ++ .../sun/xacml/cond/GeneralBagFunction.java | 371 +++++ .../sun/xacml/cond/GeneralSetFunction.java | 245 +++ .../sun/xacml/cond/HigherOrderFunction.java | 715 +++++++++ .../com/sun/xacml/cond/LogicalFunction.java | 165 ++ .../java/com/sun/xacml/cond/MapFunction.java | 420 +++++ .../com/sun/xacml/cond/MapFunctionProxy.java | 63 + .../com/sun/xacml/cond/MatchFunction.java | 441 ++++++ .../java/com/sun/xacml/cond/ModFunction.java | 122 ++ .../com/sun/xacml/cond/MultiplyFunction.java | 170 ++ .../java/com/sun/xacml/cond/NOfFunction.java | 229 +++ .../java/com/sun/xacml/cond/NotFunction.java | 121 ++ .../xacml/cond/NumericConvertFunction.java | 182 +++ .../com/sun/xacml/cond/RoundFunction.java | 136 ++ .../java/com/sun/xacml/cond/SetFunction.java | 291 ++++ .../xacml/cond/StandardFunctionFactory.java | 424 +++++ .../com/sun/xacml/cond/StringFunction.java | 123 ++ .../xacml/cond/StringNormalizeFunction.java | 166 ++ .../com/sun/xacml/cond/SubtractFunction.java | 170 ++ .../sun/xacml/cond/TimeInRangeFunction.java | 203 +++ .../sun/xacml/cond/URIStringCatFunction.java | 171 ++ .../sun/xacml/cond/VariableDefinition.java | 213 +++ .../com/sun/xacml/cond/VariableManager.java | 373 +++++ .../com/sun/xacml/cond/VariableReference.java | 351 ++++ .../cond/cluster/AbsFunctionCluster.java | 67 + .../cond/cluster/AddFunctionCluster.java | 66 + .../cluster/ComparisonFunctionCluster.java | 66 + .../cluster/ConditionBagFunctionCluster.java | 67 + .../cluster/ConditionSetFunctionCluster.java | 67 + .../cond/cluster/DateMathFunctionCluster.java | 68 + .../cond/cluster/DivideFunctionCluster.java | 66 + .../cond/cluster/EqualFunctionCluster.java | 66 + .../cond/cluster/FloorFunctionCluster.java | 66 + .../xacml/cond/cluster/FunctionCluster.java | 72 + .../cluster/GeneralBagFunctionCluster.java | 66 + .../cluster/GeneralSetFunctionCluster.java | 66 + .../cluster/HigherOrderFunctionCluster.java | 66 + .../cond/cluster/LogicalFunctionCluster.java | 66 + .../cond/cluster/MatchFunctionCluster.java | 66 + .../cond/cluster/ModFunctionCluster.java | 66 + .../cond/cluster/MultiplyFunctionCluster.java | 66 + .../cond/cluster/NOfFunctionCluster.java | 66 + .../cond/cluster/NotFunctionCluster.java | 66 + .../NumericConvertFunctionCluster.java | 67 + .../cond/cluster/RoundFunctionCluster.java | 66 + .../cond/cluster/StringFunctionCluster.java | 71 + .../StringNormalizeFunctionCluster.java | 67 + .../cond/cluster/SubtractFunctionCluster.java | 66 + .../com/sun/xacml/cond/cluster/package.html | 7 + .../main/java/com/sun/xacml/cond/package.html | 19 + .../java/com/sun/xacml/ctx/Attribute.java | 449 ++++++ .../java/com/sun/xacml/ctx/InputParser.java | 212 +++ .../java/com/sun/xacml/ctx/PolicyIssuer.java | 118 ++ .../java/com/sun/xacml/ctx/RequestCtx.java | 412 +++++ .../com/sun/xacml/ctx/RequestElement.java | 626 ++++++++ .../java/com/sun/xacml/ctx/ResponseCtx.java | 224 +++ .../main/java/com/sun/xacml/ctx/Result.java | 723 +++++++++ .../main/java/com/sun/xacml/ctx/Status.java | 404 +++++ .../java/com/sun/xacml/ctx/StatusDetail.java | 209 +++ .../main/java/com/sun/xacml/ctx/package.html | 8 + .../sun/xacml/debug/IndirectLocatable.java | 36 + .../java/com/sun/xacml/debug/Locatable.java | 28 + .../java/com/sun/xacml/debug/RuntimeInfo.java | 306 ++++ .../com/sun/xacml/finder/AttributeFinder.java | 300 ++++ .../xacml/finder/AttributeFinderModule.java | 201 +++ .../com/sun/xacml/finder/PolicyFinder.java | 314 ++++ .../sun/xacml/finder/PolicyFinderModule.java | 169 ++ .../sun/xacml/finder/PolicyFinderResult.java | 130 ++ .../finder/RequiredAttributesModule.java | 13 + .../com/sun/xacml/finder/ResourceFinder.java | 301 ++++ .../xacml/finder/ResourceFinderModule.java | 200 +++ .../xacml/finder/ResourceFinderResult.java | 159 ++ .../sun/xacml/finder/RevocationFinder.java | 136 ++ .../xacml/finder/RevocationFinderModule.java | 86 + .../xacml/finder/impl/CurrentEnvModule.java | 208 +++ .../impl/CurrentRequiredAttributeModule.java | 44 + .../sun/xacml/finder/impl/SelectorModule.java | 241 +++ .../com/sun/xacml/finder/impl/package.html | 8 + .../java/com/sun/xacml/finder/package.html | 11 + .../src/main/java/com/sun/xacml/package.html | 9 + .../com/sun/xacml/reduction/EdgeExplorer.java | 346 ++++ .../sun/xacml/reduction/ReductionGraph.java | 369 +++++ .../xacml/reduction/ReductionGraphEdge.java | 207 +++ .../xacml/reduction/ReductionGraphNode.java | 387 +++++ .../src/test/java/com/sun/xacml/AppTest.java | 66 + .../eu.aniketos.securebpmn.xacml.api/pom.xml | 76 + .../pom_pdpwsdl_gen.xml | 61 + .../securebpmn/xacml/api/ErrorType.java | 29 + .../securebpmn/xacml/api/ReasonType.java | 39 + .../securebpmn/xacml/api/SecurityError.java | 199 +++ .../xacml/api/autho/AttributeIdentifier.java | 99 ++ .../xacml/api/autho/AuthoAttribute.java | 83 + .../securebpmn/xacml/api/autho/AuthoInfo.java | 46 + .../xacml/api/autho/AuthoObligation.java | 56 + .../xacml/api/autho/AuthoResult.java | 155 ++ .../securebpmn/xacml/api/autho/Decision.java | 52 + .../xacml/api/autho/DesignatorAttribute.java | 75 + .../xacml/api/autho/IAuthoManager.java | 24 + .../xacml/api/autho/IContextProvider.java | 36 + .../xacml/api/autho/IObligationService.java | 28 + .../securebpmn/xacml/api/autho/IPDP.java | 42 + .../xacml/api/autho/IPDPManagement.java | 37 + .../xacml/api/autho/IPDPStateManagement.java | 35 + .../securebpmn/xacml/api/idm/AuthInfo.java | 63 + .../securebpmn/xacml/api/idm/IIDProvider.java | 38 + .../xacml/api/idm/IIDProviderFactory.java | 23 + .../xacml/api/idm/IIDProviderProxy.java | 26 + .../xacml/api/idm/ITicketProvider.java | 55 + .../xacml/api/idm/ITicketProviderFactory.java | 22 + .../securebpmn/xacml/api/idm/IdInfo.java | 94 ++ .../xacml/api/log/AccessControlRequest.java | 216 +++ .../xacml/api/log/EventNotification.java | 59 + .../securebpmn/xacml/api/log/ILogStore.java | 42 + .../securebpmn/xacml/api/log/LogEntry.java | 49 + .../xacml/api/pep/IObligationContext.java | 22 + .../securebpmn/xacml/api/pep/IPEP.java | 29 + .../securebpmn/xacml/api/pep/IPEPProxy.java | 22 + .../securebpmn/xacml/api/AppTest.java | 53 + .../pom.xml | 56 + .../analysis-pdp.pom.xml | 136 ++ .../doc/AnalysisClasses.zargo | Bin 0 -> 7199 bytes .../doc/policy-config.xml | 164 ++ .../doc/svn-config.xml | 12 + .../local-pdp.pom.xml | 145 ++ .../eu.aniketos.securebpmn.xacml.pdp/pom.xml | 132 ++ .../securebpmn/xacml/AnalysisConfig.java | 177 +++ .../securebpmn/xacml/AnalysisCtx.java | 58 + .../securebpmn/xacml/SVNPDPConfig.java | 269 ++++ .../combine/AnalysisCombiningAlgFactory.java | 164 ++ .../AnalysisCombiningAlgFactoryProxy.java | 34 + .../AnalysisDenyOverridesPolicyAlg.java | 134 ++ .../combine/AnalysisDenyOverridesRuleAlg.java | 131 ++ .../AnalysisFirstApplicablePolicyAlg.java | 117 ++ .../AnalysisFirstApplicableRuleAlg.java | 77 + .../AnalysisOnlyOneApplicablePolicyAlg.java | 134 ++ ...AnalysisOrderedDenyOverridesPolicyAlg.java | 52 + .../AnalysisOrderedDenyOverridesRuleAlg.java | 52 + ...alysisOrderedPermitOverridesPolicyAlg.java | 49 + ...AnalysisOrderedPermitOverridesRuleAlg.java | 52 + .../AnalysisPermitOverridesPolicyAlg.java | 139 ++ .../AnalysisPermitOverridesRuleAlg.java | 135 ++ .../xacml/cond/AnalysisLogicalFunction.java | 108 ++ .../xacml/cond/CustomCompareFunction.java | 135 ++ .../xacml/cond/CustomFunctionCluster.java | 49 + .../securebpmn/xacml/finder/MySVNClient.java | 198 +++ .../xacml/finder/SVNPolicyFinderModule.java | 294 ++++ .../finder/SVNStatePolicyFinderModule.java | 188 +++ .../xacml/finder/impl/PDPStateModule.java | 29 + .../finder/impl/RoleFinderFileModule.java | 227 +++ .../pdp/AttributeFinderModuleObserver.aj | 42 + .../xacml/pdp/EvaluationEventObserver.aj | 214 +++ .../securebpmn/xacml/pdp/PDPServer.java | 676 ++++++++ .../xacml/pdp/idHandler/IDHandler.java | 59 + .../xacml/pdp/idHandler/IDInfoCache.java | 69 + .../xacml/pdp/idHandler/IDInfoCacheEntry.java | 27 + .../AnalysisFinderModule.java | 99 ++ .../ConditionTargetCapture.java | 224 +++ .../xacml/pdp/runtimeEvaluation/EvalInfo.java | 77 + .../runtimeEvaluation/EvalInfoProvider.java | 185 +++ .../runtimeEvaluation/EvaluationEventHub.java | 304 ++++ .../EvaluationEventRegistry.java | 134 ++ .../runtimeEvaluation/EvaluationEvents.java | 88 ++ .../pdp/runtimeEvaluation/ExtToolEncoder.java | 54 + .../runtimeEvaluation/ExtToolTypeEncoder.java | 57 + .../pdp/runtimeEvaluation/HOLEncoder.java | 445 ++++++ .../xacml/pdp/runtimeEvaluation/InfoTree.java | 144 ++ .../pdp/runtimeEvaluation/KnownAttrStore.java | 40 + .../runtimeEvaluation/MissingAttrCapture.java | 205 +++ .../pdp/runtimeEvaluation/PraefixEncoder.java | 219 +++ .../pdp/runtimeEvaluation/PrettyPrinter.java | 135 ++ .../runtimeEvaluation/ReportGenerator.java | 117 ++ .../RuntimeAttrCollector.java | 53 + .../pdp/runtimeEvaluation/XACMLTree.java | 134 ++ .../attributes/AbstractAttribute.java | 26 + .../attributes/AbstractAttributeResolver.java | 65 + .../attributes/AnalysisAttributeResolver.java | 50 + .../attributes/AttributeHelper.java | 175 ++ .../attributes/KnownAttributeResolver.java | 96 ++ .../src/main/resources/policy-config.xml | 20 + .../src/main/webapp/WEB-INF/cxf-servlet.xml | 23 + .../src/main/webapp/WEB-INF/log4j.properties | 13 + .../main/webapp/WEB-INF/policies/test4.xacml | 114 ++ .../src/main/webapp/WEB-INF/policy-config.xml | 21 + .../src/main/webapp/WEB-INF/svn-config.xml | 8 + .../src/main/webapp/WEB-INF/web.xml | 20 + .../test/abstractEval/abstractEval-config.xml | 28 + .../abstractEval/abstractEval_andortest.xacml | 56 + .../abstractEval_policy2011.xacml | 103 ++ .../abstractEval_xacmlv1test.xacml | 54 + .../src/test/abstractEval/roles.config | 5 + .../src/test/analysis-config.xml | 49 + .../test/becker/nhs-becker-healthrecord.xacml | 228 +++ .../src/test/becker/nhs-becker-p_reg.xacml | 11 + .../src/test/becker/nhs-becker.xacml | 23 + .../src/test/becker/nhs_agents.xacml | 41 + .../src/test/becker/nhs_relationship.xacml | 200 +++ .../securebpmn/xacml/pdp/AnalysisPDPTest.java | 183 +++ .../securebpmn/xacml/pdp/AppTest.java | 102 ++ .../securebpmn/xacml/pdp/PDPState.java | 60 + .../securebpmn/xacml/pdp/PlainPDPTest.java | 139 ++ .../xacml/pdp/ProductiveSVNTest.java | 75 + .../securebpmn/xacml/pdp/ProductiveTest.java | 122 ++ .../xacml/pdp/abtractEval/AndOr.java | 205 +++ .../xacml/pdp/abtractEval/HolTestGen.java | 288 ++++ .../xacml/pdp/runEx/DenyPoliciesExample.java | 74 + .../xacml/pdp/runEx/RunningExample.java | 73 + .../xacml/pdp/state/PDPStateMgt.java | 215 +++ .../src/test/log4j.properties | 19 + .../src/test/pdpState-config.xml | 32 + .../src/test/policy1.xacml | 82 + .../src/test/policy2.xacml | 188 +++ .../src/test/policy3.xacml | 94 ++ .../src/test/productive-config.xml | 46 + .../src/test/roles.config | 5 + .../src/test/test1.xacml | 116 ++ .../src/test/test2.xacml | 220 +++ .../src/test/test3.xacml | 214 +++ .../src/test/test4.xacml | 114 ++ .../pom.xml | 71 + .../xacml/pdpstate/DemoPDPStateMgt.java | 168 ++ .../securebpmn/xacml/pdpstate/Dependency.java | 327 ++++ .../pdpstate/InvalidAssignmentException.java | 51 + .../securebpmn/xacml/pdpstate/PDPState.java | 490 ++++++ .../xacml/pdpstate/PDPStateManagement.java | 239 +++ .../xacml/pdpstate/SyntaxError.java | 31 + .../pdpstate/db/AttributeAssignment.java | 121 ++ .../pdpstate/db/AttributeDBIdentifier.java | 73 + .../xacml/pdpstate/db/AttributeType.java | 83 + .../xacml/pdpstate/db/ContextAttribute.java | 75 + .../db/ContextAttributeAssignment.java | 123 ++ .../xacml/pdpstate/db/HibernateUtil.java | 210 +++ .../xacml/pdpstate/xacml/PDPStateModule.java | 157 ++ .../main/resources/eu.aniketos.pdpState.xml | 103 ++ .../main/resources/hibernate.pdpState.cfg.xml | 29 + .../main/resources/pdpStateDependencies.conf | 180 +++ .../xacml/pdpstate/PDPStateManagementFoo.java | 79 + .../xacml/pdpstate/PDPStateStartup.java | 209 +++ .../src/test/log4j.properties | 19 + .../pom.xml | 50 + .../xacml/support/AttributeResolver.java | 80 + .../securebpmn/xacml/support/Category.java | 104 ++ .../xacml/support/CtxInfoExtension.java | 24 + .../xacml/support/EvaluationIdContext.java | 42 + .../xacml/support/RecordAttributeFinder.java | 45 + .../support/RecordEvaluationContext.java | 141 ++ .../xacml/support/XACML2APIMapper.java | 86 + .../xacml/support/XACMLDecoder.java | 168 ++ .../xacml/support/XACMLEncoder.java | 86 + .../support/attr/EvaluationIdAttribute.java | 113 ++ .../proxy/EvaluationIdAttributeProxy.java | 44 + .../comb/LatticeCombiningAlgorithm.java | 297 ++++ .../xacml/support/comb/LatticeElem.java | 223 +++ .../xacml/support/comb/PolicyLattice.java | 105 ++ .../support/comb/PolicyLatticeIterator.java | 95 ++ .../support/finder/FilePolicyModule.java | 283 ++++ .../support/finder/FolderPolicyModule.java | 29 + .../support/finder/IEvaluationIdContext.java | 20 + .../finder/IPDPStateEvaluationContext.java | 34 + .../finder/IRecordEvaluationContext.java | 26 + .../support/helper/DefaultElementCreator.java | 62 + .../xacml/support/helper/ElementCreator.java | 77 + .../xacml/support/helper/IElementCreator.java | 33 + .../xacml/support/helper/LogPreparer.java | 56 + .../xacml/support/helper/ResourceCreator.java | 75 + .../securebpmn/xacml/support/AppTest.java | 53 + 401 files changed, 67683 insertions(+) create mode 100644 GenericBreakGlass-XACML/LICENSE create mode 100644 GenericBreakGlass-XACML/README.md create mode 100644 GenericBreakGlass-XACML/src/.gitignore create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml.support/pom.xml create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/DOMLinesParser.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/SimplePDP.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/BasicPolicyFinderModule.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/FilePolicyModule.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/PolicyCollection.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/PolicyReader.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/StaticPolicyFinderModule.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/StaticRefPolicyFinderModule.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/TopLevelPolicyException.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/URLPolicyFinderModule.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml.support/src/test/java/com/sun/xacml/support/AppTest.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/pom.xml create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/AbstractPolicy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/BasicEvaluationCtx.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ConfigurationStore.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Constants.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/EvaluationCtx.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Indenter.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/MatchElement.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/MatchResult.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Obligation.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PDP.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PDPConfig.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ParsingException.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Policy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PolicyMetaData.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PolicyReference.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PolicySet.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PolicyTreeElement.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ProcessingException.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Rule.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Target.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/TargetMatch.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/TargetMatchGroup.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/TargetSection.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/UnknownIdentifierException.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/VersionConstraints.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/AnyURIAttribute.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/AttributeDesignator.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/AttributeFactory.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/AttributeFactoryProxy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/AttributeProxy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/AttributeSelector.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/AttributeValue.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/BagAttribute.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/Base64.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/Base64BinaryAttribute.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/BaseAttributeFactory.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/BooleanAttribute.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DNSNameAttribute.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DateAttribute.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DateTimeAttribute.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DayTimeDurationAttribute.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DecisionAttribute.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DoubleAttribute.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/HexBinaryAttribute.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/IPAddressAttribute.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/IPv4AddressAttribute.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/IPv6AddressAttribute.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/IntegerAttribute.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/PortRange.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/RFC822NameAttribute.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/StandardAttributeFactory.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/StringAttribute.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/TimeAttribute.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/TypeIdentifierConstants.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/X500NameAttribute.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/YearMonthDurationAttribute.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/package.html create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/AnyURIAttributeProxy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/Base64BinaryAttributeProxy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/BooleanAttributeProxy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/DNSNameAttributeProxy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/DateAttributeProxy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/DateTimeAttributeProxy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/DayTimeDurationAttributeProxy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/DoubleAttributeProxy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/HexBinaryAttributeProxy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/IPAddressAttributeProxy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/IntegerAttributeProxy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/RFC822NameAttributeProxy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/StringAttributeProxy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/TimeAttributeProxy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/X500NameAttributeProxy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/YearMonthDurationAttributeProxy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/package.html create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/BaseCombiningAlgFactory.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/CombinerElement.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/CombinerParameter.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/CombiningAlgFactory.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/CombiningAlgFactoryProxy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/CombiningAlgorithm.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/DenyOverridesPolicyAlg.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/DenyOverridesRuleAlg.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/FirstApplicablePolicyAlg.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/FirstApplicableRuleAlg.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/OnlyOneApplicablePolicyAlg.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/OrderedDenyOverridesPolicyAlg.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/OrderedDenyOverridesRuleAlg.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/OrderedPermitOverridesPolicyAlg.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/OrderedPermitOverridesRuleAlg.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/PermitOverridesPolicyAlg.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/PermitOverridesRuleAlg.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/PolicyCombinerElement.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/PolicyCombiningAlgorithm.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/RuleCombinerElement.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/RuleCombiningAlgorithm.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/StandardCombiningAlgFactory.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/package.html create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/AbsFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/AddFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/Apply.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/BagFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/BaseFunctionFactory.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/BasicFunctionFactoryProxy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/ComparisonFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/Condition.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/ConditionBagFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/ConditionSetFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/DateMathFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/DivideFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/EqualFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/Evaluatable.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/EvaluationResult.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/Expression.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/ExpressionHandler.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FloorFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/Function.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FunctionBase.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FunctionFactory.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FunctionFactoryProxy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FunctionProxy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FunctionTypeException.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/GeneralBagFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/GeneralSetFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/HigherOrderFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/LogicalFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/MapFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/MapFunctionProxy.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/MatchFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/ModFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/MultiplyFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/NOfFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/NotFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/NumericConvertFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/RoundFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/SetFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/StandardFunctionFactory.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/StringFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/StringNormalizeFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/SubtractFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/TimeInRangeFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/URIStringCatFunction.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/VariableDefinition.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/VariableManager.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/VariableReference.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/AbsFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/AddFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/ComparisonFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/ConditionBagFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/ConditionSetFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/DateMathFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/DivideFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/EqualFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/FloorFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/FunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/GeneralBagFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/GeneralSetFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/HigherOrderFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/LogicalFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/MatchFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/ModFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/MultiplyFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/NOfFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/NotFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/NumericConvertFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/RoundFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/StringFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/StringNormalizeFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/SubtractFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/package.html create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/package.html create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/Attribute.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/InputParser.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/PolicyIssuer.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/RequestCtx.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/RequestElement.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/ResponseCtx.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/Result.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/Status.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/StatusDetail.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/package.html create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/debug/IndirectLocatable.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/debug/Locatable.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/debug/RuntimeInfo.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/AttributeFinder.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/AttributeFinderModule.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/PolicyFinder.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/PolicyFinderModule.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/PolicyFinderResult.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/RequiredAttributesModule.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/ResourceFinder.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/ResourceFinderModule.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/ResourceFinderResult.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/RevocationFinder.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/RevocationFinderModule.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/impl/CurrentEnvModule.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/impl/CurrentRequiredAttributeModule.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/impl/SelectorModule.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/impl/package.html create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/package.html create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/package.html create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/reduction/EdgeExplorer.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/reduction/ReductionGraph.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/reduction/ReductionGraphEdge.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/reduction/ReductionGraphNode.java create mode 100644 GenericBreakGlass-XACML/src/com.sun.xacml/src/test/java/com/sun/xacml/AppTest.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/pom.xml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/pom_pdpwsdl_gen.xml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/ErrorType.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/ReasonType.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/SecurityError.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/AttributeIdentifier.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/AuthoAttribute.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/AuthoInfo.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/AuthoObligation.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/AuthoResult.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/Decision.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/DesignatorAttribute.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IAuthoManager.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IContextProvider.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IObligationService.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IPDP.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IPDPManagement.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IPDPStateManagement.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/AuthInfo.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/IIDProvider.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/IIDProviderFactory.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/IIDProviderProxy.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/ITicketProvider.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/ITicketProviderFactory.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/IdInfo.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/log/AccessControlRequest.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/log/EventNotification.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/log/ILogStore.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/log/LogEntry.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/pep/IObligationContext.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/pep/IPEP.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/pep/IPEPProxy.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/test/java/eu/aniketos/securebpmn/xacml/api/AppTest.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.parent/pom.xml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/analysis-pdp.pom.xml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/doc/AnalysisClasses.zargo create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/doc/policy-config.xml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/doc/svn-config.xml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/local-pdp.pom.xml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/pom.xml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/AnalysisConfig.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/AnalysisCtx.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/SVNPDPConfig.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisCombiningAlgFactory.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisCombiningAlgFactoryProxy.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisDenyOverridesPolicyAlg.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisDenyOverridesRuleAlg.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisFirstApplicablePolicyAlg.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisFirstApplicableRuleAlg.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisOnlyOneApplicablePolicyAlg.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisOrderedDenyOverridesPolicyAlg.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisOrderedDenyOverridesRuleAlg.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisOrderedPermitOverridesPolicyAlg.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisOrderedPermitOverridesRuleAlg.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisPermitOverridesPolicyAlg.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisPermitOverridesRuleAlg.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/cond/AnalysisLogicalFunction.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/cond/CustomCompareFunction.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/cond/CustomFunctionCluster.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/finder/MySVNClient.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/finder/SVNPolicyFinderModule.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/finder/SVNStatePolicyFinderModule.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/finder/impl/PDPStateModule.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/finder/impl/RoleFinderFileModule.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/AttributeFinderModuleObserver.aj create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/EvaluationEventObserver.aj create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/PDPServer.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/idHandler/IDHandler.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/idHandler/IDInfoCache.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/idHandler/IDInfoCacheEntry.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/AnalysisFinderModule.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/ConditionTargetCapture.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/EvalInfo.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/EvalInfoProvider.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/EvaluationEventHub.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/EvaluationEventRegistry.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/EvaluationEvents.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/ExtToolEncoder.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/ExtToolTypeEncoder.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/HOLEncoder.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/InfoTree.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/KnownAttrStore.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/MissingAttrCapture.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/PraefixEncoder.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/PrettyPrinter.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/ReportGenerator.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/RuntimeAttrCollector.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/XACMLTree.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/attributes/AbstractAttribute.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/attributes/AbstractAttributeResolver.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/attributes/AnalysisAttributeResolver.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/attributes/AttributeHelper.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/attributes/KnownAttributeResolver.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/resources/policy-config.xml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/cxf-servlet.xml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/log4j.properties create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/policies/test4.xacml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/policy-config.xml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/svn-config.xml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/web.xml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/abstractEval/abstractEval-config.xml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/abstractEval/abstractEval_andortest.xacml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/abstractEval/abstractEval_policy2011.xacml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/abstractEval/abstractEval_xacmlv1test.xacml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/abstractEval/roles.config create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/analysis-config.xml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/becker/nhs-becker-healthrecord.xacml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/becker/nhs-becker-p_reg.xacml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/becker/nhs-becker.xacml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/becker/nhs_agents.xacml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/becker/nhs_relationship.xacml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/AnalysisPDPTest.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/AppTest.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/PDPState.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/PlainPDPTest.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/ProductiveSVNTest.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/ProductiveTest.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/abtractEval/AndOr.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/abtractEval/HolTestGen.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/runEx/DenyPoliciesExample.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/runEx/RunningExample.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/state/PDPStateMgt.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/log4j.properties create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/pdpState-config.xml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/policy1.xacml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/policy2.xacml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/policy3.xacml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/productive-config.xml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/roles.config create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/test1.xacml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/test2.xacml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/test3.xacml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/test4.xacml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/pom.xml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/DemoPDPStateMgt.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/Dependency.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/InvalidAssignmentException.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/PDPState.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/PDPStateManagement.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/SyntaxError.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/AttributeAssignment.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/AttributeDBIdentifier.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/AttributeType.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/ContextAttribute.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/ContextAttributeAssignment.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/HibernateUtil.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/xacml/PDPStateModule.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/resources/eu.aniketos.pdpState.xml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/resources/hibernate.pdpState.cfg.xml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/resources/pdpStateDependencies.conf create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/test/java/eu/aniketos/securebpmn/xacml/pdpstate/PDPStateManagementFoo.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/test/java/eu/aniketos/securebpmn/xacml/pdpstate/PDPStateStartup.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/test/log4j.properties create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/pom.xml create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/AttributeResolver.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/Category.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/CtxInfoExtension.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/EvaluationIdContext.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/RecordAttributeFinder.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/RecordEvaluationContext.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/XACML2APIMapper.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/XACMLDecoder.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/XACMLEncoder.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/attr/EvaluationIdAttribute.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/attr/proxy/EvaluationIdAttributeProxy.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/comb/LatticeCombiningAlgorithm.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/comb/LatticeElem.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/comb/PolicyLattice.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/comb/PolicyLatticeIterator.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/finder/FilePolicyModule.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/finder/FolderPolicyModule.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/finder/IEvaluationIdContext.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/finder/IPDPStateEvaluationContext.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/finder/IRecordEvaluationContext.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/helper/DefaultElementCreator.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/helper/ElementCreator.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/helper/IElementCreator.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/helper/LogPreparer.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/helper/ResourceCreator.java create mode 100644 GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/test/java/eu/aniketos/securebpmn/xacml/support/AppTest.java diff --git a/GenericBreakGlass-XACML/LICENSE b/GenericBreakGlass-XACML/LICENSE new file mode 100644 index 0000000..8f71f43 --- /dev/null +++ b/GenericBreakGlass-XACML/LICENSE @@ -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. + diff --git a/GenericBreakGlass-XACML/README.md b/GenericBreakGlass-XACML/README.md new file mode 100644 index 0000000..43e4818 --- /dev/null +++ b/GenericBreakGlass-XACML/README.md @@ -0,0 +1,6 @@ +# GenericBreakGlass: XACML Reference Implementation + +## Team +Main developers: +* [Achim D. Brucker](http://www.brucker.ch/) +* Helmut Petritsch diff --git a/GenericBreakGlass-XACML/src/.gitignore b/GenericBreakGlass-XACML/src/.gitignore new file mode 100644 index 0000000..16cd310 --- /dev/null +++ b/GenericBreakGlass-XACML/src/.gitignore @@ -0,0 +1,5 @@ +*/target/ +*/bin/ +*/.classpath +*/.project +*/.settings diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml.support/pom.xml b/GenericBreakGlass-XACML/src/com.sun.xacml.support/pom.xml new file mode 100644 index 0000000..7c64940 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml.support/pom.xml @@ -0,0 +1,41 @@ + + 4.0.0 + + eu.aniketos.securebpmn.xacml + eu.aniketos.securebpmn.xacml.parent + 1.0 + ../eu.aniketos.securebpmn.xacml.parent/pom.xml + + com.sun.xacml.support + jar + 0.1 + SecureBPMN XACML - com.sun.xacml support utilities + http://maven.apache.org + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.0.2 + + 1.5 + 1.5 + + + + + + + junit + junit + [4.8,) + test + + + eu.aniketos.securebpmn.xacml + com.sun.xacml + 0.1 + + + diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/DOMLinesParser.java b/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/DOMLinesParser.java new file mode 100644 index 0000000..e1a71b1 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/DOMLinesParser.java @@ -0,0 +1,134 @@ +package com.sun.xacml.support; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.apache.log4j.Logger; +import org.w3c.dom.Node; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import com.sun.org.apache.xerces.internal.parsers.DOMParser; +import com.sun.org.apache.xerces.internal.xni.Augmentations; +import com.sun.org.apache.xerces.internal.xni.NamespaceContext; +import com.sun.org.apache.xerces.internal.xni.QName; +import com.sun.org.apache.xerces.internal.xni.XMLAttributes; +import com.sun.org.apache.xerces.internal.xni.XMLLocator; +import com.sun.org.apache.xerces.internal.xni.XNIException; +import com.sun.xacml.Constants; + +/** + * + * Class which is able to keep track of the line numbers + * + * + */ +public class DOMLinesParser extends DOMParser { + + private XMLLocator locator; + private boolean curEleNodeError = false; + private static Logger logger = Logger.getLogger(DOMLinesParser.class); + + private String currentFile = null; + + public DOMLinesParser() { + + } + + public void parse (File file) throws SAXException, IOException { + parse(new InputSource(new FileInputStream(file)), file.getPath()); + } + + public void parse (InputStream input, String fileName) throws SAXException, IOException { + parse(new InputSource(input), fileName); + } + + public void parse (InputStream input) throws SAXException, IOException { + parse(new InputSource(input), null); + } + + public void parse (InputSource input) throws SAXException, IOException { + parse(input, null); + } + + public static boolean checkFeatureAvailable() { + try { + DOMParser tmpParser = new DOMParser(); + tmpParser.setFeature( "http://apache.org/xml/features/dom/defer-node-expansion", false ); + return true; + } catch (Exception e) { + return false; + } + } + + + public void parse (InputSource input, String fileName) throws SAXException, IOException { + logger.debug("Start parsing policy file " + fileName + " with line numbers"); + this.currentFile = fileName; + try { + this.setFeature( "http://apache.org/xml/features/dom/defer-node-expansion", false ); + curEleNodeError = false; + } catch (Exception e) { + logger.error("Could not set feature required for keeping track of line numbers!"); + curEleNodeError = true; + } + super.parse(input); + } + + + + + @Override + public void startElement(QName elementQName, XMLAttributes attrList, Augmentations augs) + throws XNIException { + super.startElement(elementQName, attrList, augs); + + Node node = null; + try { + node = (Node) this.getProperty( "http://apache.org/xml/properties/dom/current-element-node" ); + } + catch( SAXException ex ) + { + if ( ! curEleNodeError ) { + curEleNodeError = true; + logger.error("Could not retreive node for setting current start line: " + ex.getMessage(), ex); + } + } + + if( node != null ) { + node.setUserData( Constants.LINE_NUMBER, new Integer( locator.getLineNumber() ), null ); // Save location String into node + if ( this.currentFile != null) { + node.setUserData( Constants.SOURCE_FILE, this.currentFile, null); + } + } + } //startElement + + /* We override startDocument callback from DocumentHandler */ + + public void startDocument(XMLLocator locator, String encoding, + NamespaceContext namespaceContext, Augmentations augs) throws XNIException { + super.startDocument(locator, encoding, namespaceContext, augs); + + this.locator = locator; + Node node = null ; + try { + node = (Node) this.getProperty( "http://apache.org/xml/properties/dom/current-element-node" ); + } + catch( org.xml.sax.SAXException ex ) + { + if ( ! curEleNodeError ) { + curEleNodeError = true; + logger.error("Could not retreive node for setting current start line: " + ex.getMessage(), ex); + } + } + + if( node != null ) { + node.setUserData( Constants.LINE_NUMBER, new Integer(locator.getLineNumber() ), null ); // Save location String into node + if ( this.currentFile != null) { + node.setUserData( Constants.SOURCE_FILE, this.currentFile, null); + } + } + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/SimplePDP.java b/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/SimplePDP.java new file mode 100644 index 0000000..82cd7ea --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/SimplePDP.java @@ -0,0 +1,236 @@ + +/* + * @(#)SimplePDP.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.support; + +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.Indenter; +import com.sun.xacml.ParsingException; +import com.sun.xacml.PDP; +import com.sun.xacml.PDPConfig; + +import com.sun.xacml.combine.PermitOverridesPolicyAlg; + +import com.sun.xacml.ctx.RequestCtx; +import com.sun.xacml.ctx.ResponseCtx; + +import com.sun.xacml.finder.AttributeFinder; +import com.sun.xacml.finder.AttributeFinderModule; +import com.sun.xacml.finder.PolicyFinder; +import com.sun.xacml.finder.PolicyFinderModule; + +import com.sun.xacml.finder.impl.CurrentEnvModule; +import com.sun.xacml.finder.impl.SelectorModule; + +import com.sun.xacml.support.finder.StaticPolicyFinderModule; +import com.sun.xacml.support.finder.StaticRefPolicyFinderModule; +import com.sun.xacml.support.finder.URLPolicyFinderModule; + +import java.io.FileInputStream; +import java.io.IOException; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +/** + * This is a simple, command-line driven XACML PDP. It acts both as an example + * of how to write a full-featured PDP and as a sample program that lets you + * evaluate requests against policies. See the comments for the main() method + * for correct usage. + *

+ * As of the 2.0 release, this has been moved into the new support tree of the + * codebase. It has also been updated to use several of the new finder + * modules provided in the support tree codebase, so that static and dynamic + * references are supported, policies can be loaded from URLs, top-level + * policies are wrapped in a policy set when more than one applies, etc. + *

+ * If you don't use a configuration file, then the default modules can all + * optionally support schema validation. To turn this on, provide the filename + * of the schema file in the property "com.sun.xacml.PolicySchema". You can + * also turn this on if you use a configuration file and it includes the + * modules provided in the support package. + * + * @since 1.1 + * @author Seth Proctor + */ +public class SimplePDP +{ + + // this is the actual PDP object we'll use for evaluation + private PDP pdp = null; + + /** + * Default constructor. This creates a SimplePDP with a + * PDP based on the configuration defined by the runtime + * property com.sun.xcaml.PDPConfigFile. + * + * @throws Exception + */ + public SimplePDP() throws Exception { + // load the configuration + ConfigurationStore store = new ConfigurationStore(); + + // use the default factories from the configuration + store.useDefaultFactories(); + + // get the PDP configuration's and setup the PDP + this.pdp = new PDP(store.getDefaultPDPConfig()); + } + + /** + * Constructor that takes an array of filenames and URLs, each of which + * points to an XACML policy, and sets up a PDP with access + * to these policies only. These policies may be accessed based on + * context matching or by reference (based on their policy identifiers). + * The PDP is also setup to support dynamic URL references. + * + * @param policies an arry of filenames and URLs that specify policies + * + * @throws Exception + */ + public SimplePDP(String [] policies) throws Exception { + // Create the two static modules with the given policies so that + // we have context-based and reference-based access to all the + // policies provided on the command-line + List policyList = Arrays.asList(policies); + StaticPolicyFinderModule staticModule = + new StaticPolicyFinderModule(PermitOverridesPolicyAlg.algId, + policyList); + StaticRefPolicyFinderModule staticRefModule = + new StaticRefPolicyFinderModule(policyList); + + // also create a module that lets us get at URL-based policies + URLPolicyFinderModule urlModule = new URLPolicyFinderModule(); + + // next, setup the PolicyFinder that this PDP will use + PolicyFinder policyFinder = new PolicyFinder(); + Set policyModules = new HashSet(); + policyModules.add(staticModule); + policyModules.add(staticRefModule); + policyModules.add(urlModule); + policyFinder.setModules(policyModules); + + // now setup attribute finder modules for the current date/time and + // AttributeSelectors (selectors are optional, but this project does + // support a basic implementation) + CurrentEnvModule envAttributeModule = new CurrentEnvModule(); + SelectorModule selectorAttributeModule = new SelectorModule(); + + // Setup the AttributeFinder just like we setup the PolicyFinder. Note + // that unlike with the policy finder, the order matters here. See the + // the javadocs for more details. + AttributeFinder attributeFinder = new AttributeFinder(); + List attributeModules = new ArrayList(); + attributeModules.add(envAttributeModule); + attributeModules.add(selectorAttributeModule); + attributeFinder.setModules(attributeModules); + + // finally, initialize our pdp + this.pdp = new PDP(new PDPConfig(attributeFinder, policyFinder, + null, null)); + } + + /** + * Evaluates the given request and returns the Response that the PDP + * will hand back to the PEP. + * + * @param requestFile the name of a file that contains a Request + * + * @return the result of the evaluation + * + * @throws IOException if there is a problem accessing the file + * @throws ParsingException if the Request is invalid + */ + public ResponseCtx evaluate(String requestFile) + throws IOException, ParsingException + { + // setup the request based on the file + RequestCtx request = + RequestCtx.getInstance(new FileInputStream(requestFile)); + + // evaluate the request + return this.pdp.evaluate(request); + } + + /** + * Main-line driver for this sample code. This method lets you invoke + * the PDP directly from the command-line. + * + * @param args the input arguments to the class. They are either the + * flag "-config" followed by a request file, or a request + * file followed by one or more policy files. In the case + * that the configuration flag is used, the configuration + * file must be specified in the standard java property, + * com.sun.xacml.PDPConfigFile. + * + * @throws Exception + */ + public static void main(String [] args) throws Exception { + if (args.length < 2) { + System.out.println("Usage: -config "); + System.out.println(" [policies]"); + System.exit(1); + } + + SimplePDP simplePDP = null; + String requestFile = null; + + if (args[0].equals("-config")) { + requestFile = args[1]; + simplePDP = new SimplePDP(); + } else { + requestFile = args[0]; + String [] policyFiles = new String[args.length - 1]; + + for (int i = 1; i < args.length; i++) { + policyFiles[i-1] = args[i]; + } + + simplePDP = new SimplePDP(policyFiles); + } + + // evaluate the request + ResponseCtx response = simplePDP.evaluate(requestFile); + + // for this sample program, we'll just print out the response + response.encode(System.out, "UTF-8", new Indenter()); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/BasicPolicyFinderModule.java b/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/BasicPolicyFinderModule.java new file mode 100644 index 0000000..c33b012 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/BasicPolicyFinderModule.java @@ -0,0 +1,253 @@ + +/* + * @(#)BasicPolicyFinderModule.java + * + * Copyright 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.support.finder; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.PolicyMetaData; +import com.sun.xacml.VersionConstraints; + +import com.sun.xacml.combine.PolicyCombiningAlgorithm; + +import com.sun.xacml.finder.PolicyFinder; +import com.sun.xacml.finder.PolicyFinderModule; +import com.sun.xacml.finder.PolicyFinderResult; + +import java.net.URI; + +import java.util.logging.Level; +import java.util.logging.Logger; + + +/** + * This is a basic implementation of PolicyFinderModule that + * accepts already created AbstractPolicys and supports + * finding by context and reference. All policies are held forever once + * added to this module, and cannot be refreshed or removed. New policies + * may be added at any point. You may optionally specify a combining + * algorithm to use when more than one applicable policy is found, and then + * a new PolicySet is wrapped around the policies using this algorithm. If + * no combining algorithm is provided, then an error is returned if more + * than one policy matches. + *

+ * This module is provided as an example, but is still fully functional, and + * should be useful for many simple applications. This is provided in the + * support package rather than the core codebase because it + * implements non-standard behavior. + * + * @since 2.0 + * @author Seth Proctor + */ +public class BasicPolicyFinderModule extends PolicyFinderModule +{ + + // the collections used to handle both kinds of policies + private PolicyCollection ctxPolicies; + private PolicyCollection refPolicies; + + // the policy identifier for any policy sets we dynamically create + private static final String POLICY_ID = + "urn:com:sun:xacml:support:finder:dynamic-policy-set"; + private static URI policyId = null; + + // the logger we'll use for all messages + private static final Logger logger = + Logger.getLogger(BasicPolicyFinderModule.class.getName()); + + static { + try { + policyId = new URI(POLICY_ID); + } catch (Exception e) { + // this can't actually happen, but just in case... + if (logger.isLoggable(Level.SEVERE)) { + logger.log(Level.SEVERE, "couldn't assign default policy id"); + } + } + } + + /** + * Creates a BasicPolicyFinderModule. + */ + public BasicPolicyFinderModule() { + this.ctxPolicies = new PolicyCollection(); + this.refPolicies = new PolicyCollection(); + } + + /** + * Creates a BasicPolicyFinderModule that can combine + * multiple applicable policies under a single, dynamic PolicySet. + * + * @param combiningAlg the algorithm to use in a new PolicySet when more + * than one policy applies + */ + public BasicPolicyFinderModule(PolicyCombiningAlgorithm combiningAlg) { + this.ctxPolicies = new PolicyCollection(combiningAlg, policyId); + this.refPolicies = new PolicyCollection(combiningAlg, policyId); + } + + /** + * Adds a policy that will be available both by reference and by + * matching to a context. The policy's identifier is used for finding + * by reference. If a policy with the same identifier and version is + * already handled by this module, then the policy is not added. + * + * @param policy the policy to add + * + * @return true if the policy was added, false otherwise + */ + public synchronized boolean addPolicy(AbstractPolicy policy) { + if (this.ctxPolicies.addPolicy(policy)) { + return this.refPolicies.addPolicy(policy); + } + return false; + } + + /** + * Adds a policy that will be available only by matching to a context. + * If a policy with the same identifier and version is already handled + * by this module, then the policy is not added. + * + * @param policy the policy to add + * + * @return true if the policy was added, false otherwise + */ + public synchronized boolean addPolicyNoRef(AbstractPolicy policy) { + return this.ctxPolicies.addPolicy(policy); + } + + /** + * Adds a policy that will be available only by reference. The policy's + * identifier is used for finding by reference. If a policy with the + * same identifier and version is already handled by this module, then + * the policy is not added. + * + * @param policy the policy to add + * + * @return true if the policy was added, false otherwise + */ + public synchronized boolean addPolicyOnlyRef(AbstractPolicy policy) { + return this.refPolicies.addPolicy(policy); + } + + /** + * Always returns true since this module does support + * finding policies based on context matching. + * + * @return true + */ + public boolean isRequestSupported() { + return true; + } + + /** + * Always returns true since this module does support + * finding policies based on reference. + * + * @return true + */ + public boolean isIdReferenceSupported() { + return true; + } + + /** + * Initialize this module. Typically this is called by + * PolicyFinder when a PDP is created. + * + * @param finder the PolicyFinder using this module + */ + public void init(PolicyFinder finder) { + // we don't need to do anything here + } + + /** + * Finds a policy based on a request's context. If more than one policy + * matches, then this either returns an error or a new policy wrapping + * the multiple policies (depending on which constructor was used to + * construct this instance). + * + * @param context the representation of the request data + * + * @return the result of trying to find an applicable policy + */ + public PolicyFinderResult findPolicy(EvaluationCtx context) { + context.newEvent(this); + try { + AbstractPolicy policy = this.ctxPolicies.getPolicy(context); + + if (policy == null) { + context.closeCurrentEvent(); + return new PolicyFinderResult(); + } + context.closeCurrentEvent(policy.getId().toString()); + return new PolicyFinderResult(policy); + } catch (TopLevelPolicyException tlpe) { + context.closeCurrentEvent(); + return new PolicyFinderResult(tlpe.getStatus()); + } + } + + /** + * Attempts to find a policy by reference, based on the provided + * parameters. + * + * @param idReference an identifier specifying some policy + * @param type type of reference (policy or policySet) as identified by + * the fields in PolicyReference + * @param constraints any optional constraints on the version of the + * referenced policy (this will never be null, but + * it may impose no constraints, and in fact will + * never impose constraints when used from a pre-2.0 + * XACML policy) + * @param parentMetaData the meta-data from the parent policy, which + * provides XACML version, factories, etc. + * + * @return the result of looking for a matching policy + */ + public PolicyFinderResult findPolicy(URI idReference, int type, + VersionConstraints constraints, + PolicyMetaData parentMetaData) { + AbstractPolicy policy = + this.refPolicies.getPolicy(idReference.toString(), type, + constraints); + + if (policy == null) { + return new PolicyFinderResult(); + } + return new PolicyFinderResult(policy); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/FilePolicyModule.java b/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/FilePolicyModule.java new file mode 100644 index 0000000..4319809 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/FilePolicyModule.java @@ -0,0 +1,328 @@ + +/* + * @(#)FilePolicyModule.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.support.finder; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.ParsingException; + +import com.sun.xacml.finder.PolicyFinder; +import com.sun.xacml.finder.PolicyFinderModule; +import com.sun.xacml.finder.PolicyFinderResult; + + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import java.util.logging.Level; +import java.util.logging.Logger; + + +/** + * This module represents a collection of files containing polices, + * each of which will be searched through when trying to find a + * policy that is applicable to a specific request. It does not support + * policy references. + *

+ * Note that this class used to be provided in the + * com.sun.xacml.finder.impl package with a warning that it + * would move out of the core packages eventually. This is partly because + * this class doesn't represent standard functionality, and partly because + * it isn't designed to be generally useful as anything more than an + * example. Because so many people have used this class, however, it stayed + * in place until the 2.0 release. + *

+ * As of the 2.0 release, you may still use this class (in its new location), + * but you are encouraged to migrate to the new support modules that are + * much richer and designed for general-purpose use. Also, note that the + * loadPolicy methods that used to be available from this class + * have been removed. That functionality has been replaced by the much more + * useful PolicyReader class. If you need to load policies + * directly, you should consider that new class. + * + * @since 1.0 + * @author Seth Proctor + */ +public class FilePolicyModule extends PolicyFinderModule { + + // the schema file we're using, if any + private File schemaFile = null; + + // the filenames for the files we'll load + private Set fileNames; + + // the actual loaded policies + protected PolicyCollection policies; + + // the logger we'll use for all messages + private static final Logger logger = + Logger.getLogger(FilePolicyModule.class.getName()); + + // configuration: keep track of lines when loadig policies (slow! use only for debugging!) + protected boolean useLines = false, enf_useLines = false; + + + + protected Map confParams = new HashMap(); + + protected static final String CONF_PREFIX = "conf:", + FILE_PREFIX = "file:", + CONF_USELINES = "useLines"; + + /** + * Constructor which retrieves the schema file to validate policies against + * from the PolicyReader.POLICY_SCHEMA_PROPERTY. If the + * retrieved property is null, then no schema validation will occur. + */ + public FilePolicyModule() { + this.fileNames = new HashSet(); + this.policies = new PolicyCollection(); + + String schemaName = + System.getProperty(PolicyReader.POLICY_SCHEMA_PROPERTY); + + if (schemaName != null) { + this.schemaFile = new File(schemaName); + } + } + + /** + * Constructor that uses the specified File as the schema + * file for XML validation. If schema validation is not desired, a null + * value should be used. + * + * @param schemaFile the schema file to validate policies against, + * or null if schema validation is not desired. + */ + public FilePolicyModule(File schemaFile) { + this.fileNames = new HashSet(); + this.policies = new PolicyCollection(); + + this.schemaFile = schemaFile; + } + + /** + * Constructor that uses the specified String as the schema + * file for XML validation. If schema validation is not desired, a null + * value should be used. + * + * @param schemaFile the schema file to validate policies against, + * or null if schema validation is not desired. + */ + public FilePolicyModule(String schemaFile) { + this((schemaFile != null) ? new File(schemaFile) : null); + } + + /** + * Constructor that specifies a set of initial policy files to use. This + * retrieves the schema file to validate policies against from the + * PolicyReader.POLICY_SCHEMA_PROPERTY. If the retrieved + * property is null, then no schema validation will occur. + * + * @param fileNames a List of Strings that + * identify policy files + */ + public FilePolicyModule(List fileNames) { + this(); + + if (fileNames != null) { + for ( String fileName : fileNames ) { + if ( fileName.startsWith(CONF_PREFIX) ) { + String tmp = fileName.substring(5); + try { + String confId = tmp.substring(0, tmp.indexOf(":")); + String value = tmp.substring(tmp.indexOf(":") + 1); + confParams.put(confId, value); + } catch(Exception e) { + logger.warning("Could not add configuration: " + tmp); + } + + } else { + if ( fileName.startsWith(FILE_PREFIX) ) { + this.fileNames.add(fileName.substring(5)); + } else { + this.fileNames.add(fileName); + } + } + } + } + if ( enf_useLines ) { + useLines = true; + } else if ( confParams.containsKey(CONF_USELINES)) { + useLines = getBool(confParams.get(CONF_USELINES)); + } + } + + /** + * Constructor that specifies a set of initial policy files to use and + * the schema file used to validate the policies. If schema validation is + * not desired, a null value should be used. + * + * @param fileNames a List of Strings that + * identify policy files + * @param schemaFile the schema file to validate policies against, + * or null if schema validation is not desired. + */ + public FilePolicyModule(List fileNames, String schemaFile) { + this(schemaFile); + + if (fileNames != null) { + this.fileNames.addAll(fileNames); + } + } + + /** + * Adds a file (containing a policy) to the collection of filenames + * associated with this module. Note that this doesn't actually load the + * policy file. Policies aren't loaded from their files until the + * module is initialized through the init method (which + * is called automatically by the PolicyFinder when the + * system comes up). + * + * @param filename the file to add to this module's collection of files + * + * @return true or false depending on the success of this operation. + */ + public boolean addPolicy(String filename) { + return this.fileNames.add(filename); + } + + /** + * Indicates whether this module supports finding policies based on + * a request (target matching). Since this module does support + * finding policies based on requests, it returns true. + * + * @return true, since finding policies based on requests is supported + */ + public boolean isRequestSupported() { + return true; + } + + /** + * Initializes the FilePolicyModule by loading + * the policies contained in the collection of files associated + * with this module. This method also uses the specified + * PolicyFinder to help in instantiating PolicySets. + * + * @param finder a PolicyFinder used to help in instantiating PolicySets + */ + public void init(PolicyFinder finder) { + Object o = finder.getPDPConfiguration().getCustomAttr(ConfigurationStore.BASEDIR); + String baseDir = ""; + if ( o != null) { + baseDir = (String) o; + } + + PolicyReader reader = new PolicyReader(finder, logger, + this.schemaFile, this.useLines); + + for (String fname : this.fileNames ) { + try { + AbstractPolicy policy = + reader.readPolicy(new FileInputStream(baseDir + fname), fname); + this.policies.addPolicy(policy); + } catch (FileNotFoundException fnfe) { + if (logger.isLoggable(Level.WARNING)) { + logger.log(Level.WARNING, "File couldn't be read: " + + fname, fnfe); + } + } catch (ParsingException pe) { + if (logger.isLoggable(Level.WARNING)) { + logger.log(Level.WARNING, "Error reading policy from file " + + fname, pe); + } + } + } + } + + /** + * Finds a policy based on a request's context. If more than one + * applicable policy is found, this will return an error. Note that + * this is basically just a subset of the OnlyOneApplicable Policy + * Combining Alg that skips the evaluation step. See comments in there + * for details on this algorithm. + * + * @param context the representation of the request data + * + * @return the result of trying to find an applicable policy + */ + public PolicyFinderResult findPolicy(EvaluationCtx context) { + try { + context.newEvent(this); + AbstractPolicy policy = this.policies.getPolicy(context); + if (policy == null) { + context.closeCurrentEvent(); + return new PolicyFinderResult(); + } + context.closeCurrentEvent(policy.getId().toString()); + return new PolicyFinderResult(policy); + } catch (TopLevelPolicyException tlpe) { + context.closeCurrentEvent(); + return new PolicyFinderResult(tlpe.getStatus()); + } + } + + + protected static boolean getBool(String value) { + try { + Boolean val = new Boolean(value); + return val.booleanValue(); + } catch (Exception e) { + logger.log(Level.WARNING, "Could not read boolean value " + value + "; Using false as default"); + return false; + } + } + + /** + * this method can be used to enforce the usage of lines parsing + * programatically + * @param useLines + */ + public void enforceUseLines() { + this.enf_useLines = true; + this.useLines = true; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/PolicyCollection.java b/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/PolicyCollection.java new file mode 100644 index 0000000..90dd524 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/PolicyCollection.java @@ -0,0 +1,376 @@ + +/* + * @(#)PolicyCollection.java + * + * Copyright 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.support.finder; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.MatchResult; +import com.sun.xacml.Policy; +import com.sun.xacml.PolicyReference; +import com.sun.xacml.PolicySet; +import com.sun.xacml.PolicyTreeElement; +import com.sun.xacml.Target; +import com.sun.xacml.TargetSection; +import com.sun.xacml.VersionConstraints; + +import com.sun.xacml.combine.PolicyCombiningAlgorithm; + +import com.sun.xacml.ctx.Result; +import com.sun.xacml.ctx.Status; + +import java.io.Serializable; +import java.net.URI; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Iterator; +import java.util.StringTokenizer; +import java.util.TreeSet; + + +/** + * This class handles collections of AbstractPolicy instances, + * and provides some commonly useful operations. Specifically, it lets you + * retrieve matching policies (based on reference or context), it optionally + * handles wrapping multiple matches under a single PolicySet, and it manages + * different versions of policies correctly. This class is intended for use + * as a backing store to PolicyFinderModules, but in practice + * may have many uses. + *

+ * Note that this class will accept multiple versions of the same policy. This + * means that when you retieve a policy by reference, you will get the + * correct version. It also means that when you retrieve a policy based on + * context, there may be multiple revisions of the same policy, any number + * of which may apply. Generally speaking, the correct behavior here is not + * to return all of these policies, since they are (virtually speaking) the + * same policy, but may have conflicting rules. So, as a simplification, and + * to handle the most common cases, only the most recent version of a policy + * is returned in these cases. If you need a more complex solution, you + * will need to implement it yourself. Because the support modules use this + * class as their backing store, this is true also of those modules. + *

+ * Note that this is not a heavily optimized class. It is intended more as + * an example, support code for the finder modules, and a starting utility + * for other programmers than as an enterprise-quality implementation. That + * said, it is fully functional, and should be useful for many applications. + * + * @since 2.0 + * @author Seth Proctor + */ +public class PolicyCollection +{ + + // the actual collection of policies + private HashMap > policies; + + // the single instance of the comparator we'll use for managing versions + private VersionComparator versionComparator = new VersionComparator(); + + // the optional combining algorithm used when wrapping multiple policies + private PolicyCombiningAlgorithm combiningAlg; + + // the optional policy id used when wrapping multiple policies + private URI parentId; + + // default target that matches anything, used in wrapping policies + private static final Target target; + + /** + * This static initializer just sets up the default target, which is + * used by all wrapping policy sets. + */ + static { + target = + new Target(new ArrayList()); + } + + /** + * Creates a new PolicyCollection that will return errors + * when multiple policies match for a given request. + */ + public PolicyCollection() { + this.policies = new HashMap>(); + this.combiningAlg = null; + } + + /** + * Creates a new PolicyCollection that will create a new + * top-level PolicySet when multiple policies match for a given request. + * + * @param combiningAlg the algorithm to use in a new PolicySet when more + * than one policy applies + * @param parentPolicyId the identifier to use for the new PolicySet + */ + public PolicyCollection(PolicyCombiningAlgorithm combiningAlg, + URI parentPolicyId) { + this.policies = new HashMap >(); + + this.combiningAlg = combiningAlg; + this.parentId = parentPolicyId; + } + + /** + * Adds a new policy to the collection, and uses the policy's identifier + * as the reference identifier. If this identifier already exists in the + * collection, and this policy does not represent a new version of the + * policy, then the policy is not added. + * + * @param policy the policy to add + * + * @return true if the policy was added, false otherwise + */ + public boolean addPolicy(AbstractPolicy policy) { + return addPolicy(policy, policy.getId().toString()); + } + + /** + * Adds a new policy to the collection using the given identifier as + * the reference identifier. If this identifier already exists in the + * collection, and this policy does not represent a new version of the + * policy, then the policy is not added. + * + * @param policy the policy to add + * @param identifier the identifier to use when referencing this policy + * + * @return true if the policy was added, false otherwise + */ + public boolean addPolicy(AbstractPolicy policy, String identifier) { + if (this.policies.containsKey(identifier)) { + // this identifier is already is use, so see if this version is + // already in the set + TreeSet set = this.policies.get(identifier); + return set.add(policy); + } + // this identifier isn't already being used, so create a new + // set in the map for it, and add the policy + TreeSet set = new TreeSet (this.versionComparator); + this.policies.put(identifier, set); + return set.add(policy); + } + + /** + * Attempts to retrieve a policy based on the given context. If multiple + * policies match then this will either throw an exception or wrap the + * policies under a new PolicySet (depending on how this instance was + * constructed). If no policies match, then this will return null. See + * the comment in the class header about how this behaves when multiple + * versions of the same policy exist. + * + * @param context representation of a request + * + * @return a matching policy, or null if no policy matches + * + * @throws TopLevelPolicyException if multiple policies match but this + * instance wasn't setup to wrap policies + */ + public AbstractPolicy getPolicy(EvaluationCtx context) + throws TopLevelPolicyException + { + // setup a list of matching policies + ArrayList list = new ArrayList(); + // get an iterator over all the identifiers + Iterator> it = this.policies.values().iterator(); + + while (it.hasNext()) { + // for each identifier, get only the most recent policy + AbstractPolicy policy = it.next().first(); + + // see if we match + context.newEvent(policy); + MatchResult match = policy.match(context); + int result = match.getResult(); + + // if there was an error, we stop right away + if (result == MatchResult.INDETERMINATE) { + context.closeCurrentEvent( + new Result(Result.DECISION_INDETERMINATE, + context)); + throw new TopLevelPolicyException(match.getStatus()); + } + + if (result == MatchResult.NO_MATCH) { + context.closeCurrentEvent( + new Result(Result.DECISION_NOT_APPLICABLE)); + } + + // if we matched, we keep track of the matching policy... + if (result == MatchResult.MATCH) { + context.closeCurrentEvent(); + // ...first checking if this is the first match and if + // we automaticlly nest policies + if ((this.combiningAlg == null) && (list.size() > 0)) { + ArrayList code = new ArrayList(); + code.add(Status.STATUS_PROCESSING_ERROR); + Status status = new Status(code, "too many applicable" + + " top-level policies"); + throw new TopLevelPolicyException(status); + } + + list.add(policy); + } + } + + // no errors happened during the search, so now take the right + // action based on how many policies we found + switch (list.size()) { + case 0: + return null; + case 1: + return ((AbstractPolicy)(list.get(0))); + default: + return new PolicySet(this.parentId, this.combiningAlg, target, list); + } + } + + /** + * Attempts to retrieve a policy based on the given identifier and other + * constraints. If there are multiple versions of the identified policy + * that meet the version constraints, then the most recent version is + * returned. + * + * @param identifier an identifier specifying some policy + * @param type type of reference (policy or policySet) as identified by + * the fields in PolicyReference + * @param constraints any optional constraints on the version of the + * referenced policy (this will never be null, but + * it may impose no constraints, and in fact will + * never impose constraints when used from a pre-2.0 + * XACML policy) + * + * @return the policy/policy set that was retrieved. + */ + public AbstractPolicy getPolicy(String identifier, int type, + VersionConstraints constraints) { + TreeSet set = this.policies.get(identifier); + + // if we don't know about this identifier then there's nothing to do + if (set == null) { + return null; + } + // walk through the set starting with the most recent version, looking + // for a match until we exhaust all known versions + Iterator it = set.iterator(); + while (it.hasNext()) { + AbstractPolicy policy = it.next(); + if (constraints.meetsConstraint(policy.getVersion())) { + // we found a valid version, so see if it's the right kind, + // and if it is then we return it + if (type == PolicyReference.POLICY_REFERENCE) { + if (policy instanceof Policy) { + return policy; + } + } else { + if (policy instanceof PolicySet) { + return policy; + } + } + } + } + + // we didn't find a match + return null; + } + + /** + * A Comparator that is used within this class to maintain + * ordering amongst different versions of the same policy. Note that + * it actually maintains reverse-ordering, since we want to traverse the + * sets in decreasing, not increasing order. + *

+ * Note that this comparator is only used when there are multiple versions + * of the same policy, which in practice will probably happen far less + * (from this class' point of view) than additions or fetches. + */ + static class VersionComparator implements Comparator, Serializable { + + /** + * Serial version UID. + */ + private static final long serialVersionUID = 1L; + + public int compare(AbstractPolicy o1, AbstractPolicy o2) { + // we swap the parameters so that sorting goes largest to smallest + String v1 = o2.getVersion(); + String v2 = o1.getVersion(); + + // do a quick check to see if the strings are equal (note that + // even if the strings aren't equal, the versions can still + // be equal) + if (v1.equals(v2)) { + return 0; + } + + // setup tokenizers, and walk through both strings one set of + // numeric values at a time + StringTokenizer tok1 = new StringTokenizer(v1, "."); + StringTokenizer tok2 = new StringTokenizer(v2, "."); + + while (tok1.hasMoreTokens()) { + // if there's nothing left in tok2, then v1 is bigger + if (! tok2.hasMoreTokens()) { + return 1; + } + + // get the next elements in the version, convert to numbers, + // and compare them (continuing with the loop only if the + // two values were equal) + int num1 = Integer.parseInt(tok1.nextToken()); + int num2 = Integer.parseInt(tok2.nextToken()); + + if (num1 > num2) { + return 1; + } + + if (num1 < num2) { + return -1; + } + } + + // if there's still something left in tok2, then it's bigger + if (tok2.hasMoreTokens()) { + return -1; + } + + // if we got here it means both versions had the same number of + // elements and all the elements were equal, so the versions + // are in fact equal + return 0; + } + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/PolicyReader.java b/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/PolicyReader.java new file mode 100644 index 0000000..c172b9e --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/PolicyReader.java @@ -0,0 +1,429 @@ + +/* + * @(#)PolicyReader.java + * + * Copyright 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.support.finder; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.ParsingException; +import com.sun.xacml.Policy; +import com.sun.xacml.PolicySet; + +import com.sun.xacml.finder.PolicyFinder; +import com.sun.xacml.support.DOMLinesParser; + +import java.io.File; +import java.io.InputStream; +import java.io.IOException; + +import java.net.URL; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + + +/** + * This class is provided as a utility for reading policies from common, + * simple sources: InputStreams, Files, and + * URLs. It can optionally schema validate the policies. + *

+ * Note: some of this functionality was previously provided in + * com.sun.xacml.finder.impl.FilePolicyModule, but as of + * the 2.0 release, that class has been removed. This new + * PolicyReader class provides much better functionality + * for loading policies. + * + * @since 2.0 + * @author Seth Proctor + */ +public class PolicyReader implements ErrorHandler +{ + + /** + * The property which is used to specify the schema file to validate + * against (if any). Note that this isn't used directly by + * PolicyReader, but is referenced by many classes that + * use this class to load policies. + */ + public static final String POLICY_SCHEMA_PROPERTY = + "com.sun.xacml.PolicySchema"; + + // the standard attribute for specifying the XML schema language + private static final String JAXP_SCHEMA_LANGUAGE = + "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; + + // the standard identifier for the XML schema specification + private static final String W3C_XML_SCHEMA = + "http://www.w3.org/2001/XMLSchema"; + + // the standard attribute for specifying schema source + private static final String JAXP_SCHEMA_SOURCE = + "http://java.sun.com/xml/jaxp/properties/schemaSource"; + + // the finder, which is used by PolicySets + private PolicyFinder finder; + + // the builder used to create DOM documents + private DocumentBuilder builder; + + //the parser used to create DOM documents with line information + private DOMLinesParser linesParser; + + //boolean flag if the lineParser should be used (has to be activaed before parsing!) + private boolean useLineParser = false; + + // the optional logger used for error reporting + private Logger logger; + + /** + * Creates a PolicyReader that does not schema-validate + * policies. + * + * @param finder a PolicyFinder that is used by policy sets, + * which may be null only if no references are used + * @param logger a Logger used to report parsing errors + */ + public PolicyReader(PolicyFinder finder, Logger logger) { + this(finder, logger, null); + } + + /** + * Creates a PolicyReader that may schema-validate policies. + * + * @param finder a PolicyFinder that is used by policy sets, + * which may be null only if no references are used + * @param logger a Logger used to report parsing errors + * @param schemaFile the schema file used to validate policies, or + * null if schema validation is not desired + */ + public PolicyReader(PolicyFinder finder, Logger logger, File schemaFile) { + this(finder, logger, schemaFile, false); + } + + + /** + * Creates a PolicyReader that may schema-validate policies. + * + * @param finder a PolicyFinder that is used by policy sets, + * which may be null only if no references are used + * @param logger a Logger used to report parsing errors + * @param schemaFile the schema file used to validate policies, or + * null if schema validation is not desired + */ + public PolicyReader(PolicyFinder finder, Logger logger, File schemaFile, boolean useLineParser) { + this.logger = logger; + this.finder = finder; + this.useLineParser = useLineParser; + + // create the factory + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setIgnoringComments(true); + factory.setNamespaceAware(true); + + // see if we want to schema-validate policies + if (schemaFile == null) { + factory.setValidating(false); + } else { + factory.setValidating(true); + factory.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA); + factory.setAttribute(JAXP_SCHEMA_SOURCE, schemaFile); + } + + if ( useLineParser ) { + try { + Class.forName("com.sun.org.apache.xerces.internal.parsers.DOMParser"); + this.useLineParser = DOMLinesParser.checkFeatureAvailable(); + } catch (Exception e) { + this.useLineParser = false; + logger.warning("For the useLineParser the xerces DOMParser must be available on the classpath"); + } + if ( this.useLineParser ) { + initDOMLinesParser(factory, schemaFile); + } + } + + // now use the factory to create the document builder + try { + this.builder = factory.newDocumentBuilder(); + this.builder.setErrorHandler(this); + + } catch (ParserConfigurationException pce) { + throw new IllegalArgumentException("Filed to setup reader: " + + pce.toString()); + } + } + + private void initDOMLinesParser(DocumentBuilderFactory factory, File schemaFile) { + + if ( schemaFile != null ) { + //TODO + logger.warning("Schema File validation not possible with active line numbers"); + } + + this.linesParser = new DOMLinesParser(); + + + try { + this.linesParser.setFeature("http://apache.org/xml/features/dom/create-entity-ref-nodes", false); + // only check if changes are there. do not execute in normal mode + //setFeatures(Constants.getSAXFeatures(), factory, Constants.SAX_FEATURE_PREFIX); + //setFeatures(Constants.getXercesFeatures(), factory, Constants.XERCES_FEATURE_PREFIX); + } catch( Exception e) { + logger.warning("Could not set Features for DOMLinesParser!"); + } + + } + +// /** +// * function used to compare feature lists of DOMLinesParser and DocumentBuilderFactory for compability +// * reasons +// * @param features +// * @param factory +// * @param prefix +// */ +// private void setFeatures(Enumeration features, DocumentBuilderFactory factory, String prefix) { +// +// Object feature; String sFeature; +// while ( features.hasMoreElements() ) { +// feature = features.nextElement(); +// if ( feature instanceof String ) { +// sFeature = (String) feature; +// try { +// if ( factory.getFeature( prefix + sFeature) != linesParser.getFeature(prefix + sFeature)) { +// this.linesParser.setFeature( prefix + sFeature, factory.getFeature( prefix + sFeature)); +// System.out.println(" SET FEATURE " + prefix+ sFeature + " to " + factory.getFeature( prefix + sFeature)); +// } else { +// System.out.println(" Feature " + prefix + sFeature + " already set"); +// } +// } catch (Exception e) { +// System.out.println(" ERROR: FEATURE " + prefix+ sFeature + " could not be set"); +// } +// } +// } +// } + + /** + * Tries to read an XACML policy or policy set from the given file. + * + * @param file the file containing the policy to read + * + * @return a (potentially schema-validated) policy loaded from the + * given file + * + * @throws ParsingException if an error occurs while reading or + * parsing the policy + */ + public synchronized AbstractPolicy readPolicy(File file) + throws ParsingException + { + try { + Document root = null; + if ( useLineParser ) { + linesParser.parse(file); + root = linesParser.getDocument(); + } else { + root = this.builder.parse(file);; + } + + return handleDocument(root); + } catch (IOException ioe) { + throw new ParsingException("Failed to read the file", ioe); + } catch (SAXException saxe) { + throw new ParsingException("Failed to parse the file", saxe); + } + } + + + /** + * Tries to read an XACML policy or policy set from the given stream. + * + * @param input the stream containing the policy to read + * + * @return a (potentially schema-validated) policy loaded from the + * given file + * + * @throws ParsingException if an error occurs while reading or + * parsing the policy + */ + public synchronized AbstractPolicy readPolicy(InputStream input, String fileName) + throws ParsingException + { + try { + + Document root = null; + if ( useLineParser ) { + linesParser.parse(input, fileName); + root = linesParser.getDocument(); + } else { + root = this.builder.parse(input);; + } + + return handleDocument(root); + //return handleDocument(this.builder.parse(input)); + } catch (IOException ioe) { + throw new ParsingException("Failed to read the stream", ioe); + } catch (SAXException saxe) { + throw new ParsingException("Failed to parse the stream", saxe); + } + } + + /** + * Tries to read an XACML policy or policy set from the given stream. + * + * @param input the stream containing the policy to read + * + * @return a (potentially schema-validated) policy loaded from the + * given file + * + * @throws ParsingException if an error occurs while reading or + * parsing the policy + */ + public synchronized AbstractPolicy readPolicy(InputStream input) + throws ParsingException + { + return readPolicy(input, null); + } + + /** + * Tries to read an XACML policy or policy set based on the given URL. + * This may be any resolvable URL, like a file or http pointer. + * + * @param url a URL pointing to the policy to read + * + * @return a (potentially schema-validated) policy loaded from the + * given file + * + * @throws ParsingException if an error occurs while reading or + * parsing the policy, or if the URL can't + * be resolved + */ + public synchronized AbstractPolicy readPolicy(URL url) + throws ParsingException + { + try { + return readPolicy(url.openStream()); + } catch (IOException ioe) { + throw new ParsingException("Failed to resolve the URL: " + + url.toString(), ioe); + } + } + + /** + * A private method that handles reading the policy and creates the + * correct kind of AbstractPolicy. + */ + private AbstractPolicy handleDocument(Document doc) + throws ParsingException + { + // handle the policy, if it's a known type + Element root = doc.getDocumentElement(); + String name = root.getTagName(); + + try { + // see what type of policy this is + if (name.equals("Policy")) { + return Policy.getInstance(root); + } else if (name.equals("PolicySet")) { + return PolicySet.getInstance(root, this.finder); + } else { + // this isn't a root type that we know how to handle + throw new ParsingException("Unknown root document type: " + name); + } + } catch (IllegalArgumentException e) { + logger.log(Level.WARNING, "Could not parse Document (IllegalArgumentException): " + e.getMessage()); + throw new ParsingException("Could not parse Document (IllegalArgumentException): " + e.getMessage(), e); + } + + } + + /** + * Standard handler routine for the XML parsing. + * + * @param exception information on what caused the problem + */ + public void warning(SAXParseException exception) { + if (this.logger.isLoggable(Level.WARNING)) { //startDocument + this.logger.warning("Warning on line " + exception.getLineNumber() + + ": " + exception.getMessage()); + } + } + + /** + * Standard handler routine for the XML parsing. + * + * @param exception information on what caused the problem + * + * @throws SAXException always to halt parsing on errors + */ + public void error(SAXParseException exception) throws SAXException { + if (this.logger.isLoggable(Level.WARNING)) { + this.logger.warning("Error on line " + exception.getLineNumber() + + ": " + exception.getMessage() + " ... " + + "Policy will not be available"); + } + + throw new SAXException("error parsing policy" + (exception.getLineNumber() == -1 ? "" : "at line number " + exception.getLineNumber())); + } + + /** + * Standard handler routine for the XML parsing. + * + * @param exception information on what caused the problem + * + * @throws SAXException always to halt parsing on errors + */ + public void fatalError(SAXParseException exception) throws SAXException { + if (this.logger.isLoggable(Level.WARNING)) { + this.logger.warning("Fatal error on line " + + exception.getLineNumber() + + ": " + exception.getMessage() + " ... " + + "Policy will not be available"); + } + + throw new SAXException("fatal error parsing policy" + (exception.getLineNumber() == -1 ? "" : "at line number " + exception.getLineNumber())); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/StaticPolicyFinderModule.java b/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/StaticPolicyFinderModule.java new file mode 100644 index 0000000..5c972de --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/StaticPolicyFinderModule.java @@ -0,0 +1,320 @@ + +/* + * @(#)StaticPolicyFinderModule.java + * + * Copyright 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.support.finder; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; + +import com.sun.xacml.combine.CombiningAlgFactory; +import com.sun.xacml.combine.PolicyCombiningAlgorithm; + +import com.sun.xacml.finder.PolicyFinder; +import com.sun.xacml.finder.PolicyFinderModule; +import com.sun.xacml.finder.PolicyFinderResult; + +import java.io.File; + +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; + +import java.util.Iterator; +import java.util.List; + +import java.util.logging.Level; +import java.util.logging.Logger; + + +/** + * This is a simple implementation of PolicyFinderModule that + * supports retrieval based on context, and is designed for use with a + * run-time configuration. Its constructor accepts a List of + * Strings that represent URLs or files, and these are resolved + * to policies when the module is initialized. Beyond this, there is no + * modifying or re-loading the policies represented by this class. This + * class will optionally wrap multiple applicable policies into a dynamic + * PolicySet. + *

+ * Note that this class is designed to complement + * StaticRefPolicyFinderModule. It would be easy to support both + * kinds of policy retrieval in a single class, but the functionality is + * instead split between two classes. The reason is that when you define a + * configuration for your PDP, it's easier to specify the two sets of policies + * by using two different finder modules. Typically, there aren't many + * policies that exist in both sets, so loading the sets separately isn't + * a problem. If this is a concern to you, simply create your own class and + * merge the two existing classes. + *

+ * This module is provided as an example, but is still fully functional, and + * should be useful for many simple applications. This is provided in the + * support package rather than the core codebase because it + * implements non-standard behavior. + * + * @since 2.0 + * @author Seth Proctor + */ +public class StaticPolicyFinderModule extends PolicyFinderModule +{ + + // the list of policy URLs passed to the constructor + private List policyList; + + // the map of policies + private PolicyCollection policies; + + // the optional schema file + private File schemaFile = null; + + // the policy identifier for any policy sets we dynamically create + private static final String POLICY_ID = + "urn:com:sun:xacml:support:finder:dynamic-policy-set"; + private static URI policyId = null; + + // the logger we'll use for all messages + private static final Logger logger = + Logger.getLogger(StaticPolicyFinderModule.class.getName()); + + static { + try { + policyId = new URI(POLICY_ID); + } catch (Exception e) { + // this can't actually happen, but just in case... + if (logger.isLoggable(Level.SEVERE)) { + logger.log(Level.SEVERE, "couldn't assign default policy id"); + } + } + } + + /** + * Creates a StaticPolicyFinderModule that provides + * access to the given collection of policies and returns an error when + * more than one policy matches a given context. Any policy that cannot + * be loaded will be noted in the log, but will not cause an error. The + * schema file used to validate policies is defined by the property + * PolicyReader.POLICY_SCHEMA_PROPERTY. If the retrieved + * property is null, then no schema validation will occur. + * + * @param policyList a List of Strings that + * represent URLs or files pointing to XACML policies + */ + public StaticPolicyFinderModule(List policyList) { + this.policyList = policyList; + this.policies = new PolicyCollection(); + + String schemaName = + System.getProperty(PolicyReader.POLICY_SCHEMA_PROPERTY); + if (schemaName != null) { + this.schemaFile = new File(schemaName); + } + } + + /** + * Creates a StaticPolicyFinderModule that provides + * access to the given collection of policies and returns an error when + * more than one policy matches a given context. Any policy that cannot + * be loaded will be noted in the log, but will not cause an error. + * + * @param policyList a List of Strings that + * represent URLs or files pointing to XACML policies + * @param schemaFile the schema file to validate policies against, + * or null if schema validation is not desired + */ + public StaticPolicyFinderModule(List policyList, String schemaFile) { + this.policyList = policyList; + this.policies = new PolicyCollection(); + + if (schemaFile != null) { + this.schemaFile = new File(schemaFile); + } + } + + /** + * Creates a StaticPolicyFinderModule that provides + * access to the given collection of policies. The given combining + * algorithm is used to create new PolicySets when more than one + * policy applies. Any policy that cannot be loaded will be noted in + * the log, but will not cause an error. The schema file used to + * validate policies is defined by the property + * PolicyReader.POLICY_SCHEMA_PROPERTY. If the retrieved + * property is null, then no schema validation will occur. + * + * @param combiningAlg the algorithm to use in a new PolicySet when more + * than one policy applies + * @param policyList a List of Strings that + * represent URLs or files pointing to XACML policies + * + * @throws URISyntaxException if the combining algorithm is not a + * well-formed URI + * @throws UnknownIdentifierException if the combining algorithm identifier + * isn't known + */ + public StaticPolicyFinderModule(String combiningAlg, List policyList) + throws URISyntaxException, UnknownIdentifierException + { + PolicyCombiningAlgorithm alg = (PolicyCombiningAlgorithm) + (CombiningAlgFactory.getInstance(). + createAlgorithm(new URI(combiningAlg))); + + this.policyList = policyList; + this.policies = new PolicyCollection(alg, policyId); + + String schemaName = + System.getProperty(PolicyReader.POLICY_SCHEMA_PROPERTY); + if (schemaName != null) { + this.schemaFile = new File(schemaName); + } + } + + /** + * Creates a StaticPolicyFinderModule that provides + * access to the given collection of policies. The given combining + * algorithm is used to create new PolicySets when more than one + * policy applies. Any policy that cannot be loaded will be noted in + * the log, but will not cause an error. + * + * @param combiningAlg the algorithm to use in a new PolicySet when more + * than one policy applies + * @param policyList a List of Strings that + * represent URLs or files pointing to XACML policies + * @param schemaFile the schema file to validate policies against, + * or null if schema validation is not desired + * + * @throws URISyntaxException if the combining algorithm is not a + * well-formed URI + * @throws UnknownIdentifierException if the combining algorithm identifier + * isn't known + */ + public StaticPolicyFinderModule(String combiningAlg, List policyList, + String schemaFile) + throws URISyntaxException, UnknownIdentifierException + { + PolicyCombiningAlgorithm alg = (PolicyCombiningAlgorithm) + (CombiningAlgFactory.getInstance(). + createAlgorithm(new URI(combiningAlg))); + + this.policyList = policyList; + this.policies = new PolicyCollection(alg, policyId); + + if (schemaFile != null) { + this.schemaFile = new File(schemaFile); + } + } + + /** + * Always returns true since this module does support + * finding policies based on context. + * + * @return true + */ + public boolean isRequestSupported() { + return true; + } + + /** + * Initialize this module. Typically this is called by + * PolicyFinder when a PDP is created. This method is + * where the policies are actually loaded. + * + * @param finder the PolicyFinder using this module + */ + public void init(PolicyFinder finder) { + // now that we have the PolicyFinder, we can load the policies + PolicyReader reader = new PolicyReader(finder, logger, + this.schemaFile); + + Iterator it = this.policyList.iterator(); + while (it.hasNext()) { + String str = it.next(); + AbstractPolicy policy = null; + + try { + try { + // first try to load it as a URL + URL url = new URL(str); + policy = reader.readPolicy(url); + } catch (MalformedURLException murle) { + // assume that this is a filename, and try again + policy = reader.readPolicy(new File(str)); + } + + // we loaded the policy, so try putting it in the collection + if (! this.policies.addPolicy(policy)) { + if (logger.isLoggable(Level.WARNING)) { + logger.log(Level.WARNING, "tried to load the same " + + "policy multiple times: " + str); + } + } + } catch (ParsingException pe) { + if (logger.isLoggable(Level.WARNING)) { + logger.log(Level.WARNING, "Error reading policy: " + str, + pe); + } + } + } + } + + /** + * Finds a policy based on a request's context. If more than one policy + * matches, then this either returns an error or a new policy wrapping + * the multiple policies (depending on which constructor was used to + * construct this instance). + * + * @param context the representation of the request data + * + * @return the result of trying to find an applicable policy + */ + public PolicyFinderResult findPolicy(EvaluationCtx context) { + try { + context.newEvent(this); + AbstractPolicy policy = this.policies.getPolicy(context); + + if (policy == null) { + context.closeCurrentEvent(); + return new PolicyFinderResult(); + } + context.closeCurrentEvent(policy.getId().toString()); + return new PolicyFinderResult(policy); + } catch (TopLevelPolicyException tlpe) { + context.closeCurrentEvent(); + return new PolicyFinderResult(tlpe.getStatus()); + } + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/StaticRefPolicyFinderModule.java b/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/StaticRefPolicyFinderModule.java new file mode 100644 index 0000000..8499513 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/StaticRefPolicyFinderModule.java @@ -0,0 +1,226 @@ + +/* + * @(#)StaticRefPolicyFinderModule.java + * + * Copyright 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.support.finder; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.ParsingException; +import com.sun.xacml.PolicyMetaData; +import com.sun.xacml.VersionConstraints; + +import com.sun.xacml.finder.PolicyFinder; +import com.sun.xacml.finder.PolicyFinderModule; +import com.sun.xacml.finder.PolicyFinderResult; + +import java.io.File; + +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; + +import java.util.Iterator; +import java.util.List; + +import java.util.logging.Level; +import java.util.logging.Logger; + + +/** + * This is a simple implementation of PolicyFinderModule that + * supports retrieval based on reference, and is designed for use with a + * run-time configuration. Its constructor accepts a List of + * Strings that represent URLs or files, and these are resolved + * to policies when the module is initialized. Beyond this, there is no + * modifying or re-loading the policies represented by this class. The + * policy's identifiers are used for reference resolution. + *

+ * Note that this class is designed to complement + * StaticPolicyFinderModule. It would be easy to support both + * kinds of policy retrieval in a single class, but the functionality is + * instead split between two classes. The reason is that when you define a + * configuration for your PDP, it's easier to specify the two sets of policies + * by using two different finder modules. Typically, there aren't many + * policies that exist in both sets, so loading the sets separately isn't + * a problem. If this is a concern to you, simply create your own class and + * merge the two existing classes. + *

+ * This module is provided as an example, but is still fully functional, and + * should be useful for many simple applications. This is provided in the + * support package rather than the core codebase because it + * implements non-standard behavior. + * + * @since 2.0 + * @author Seth Proctor + */ +public class StaticRefPolicyFinderModule extends PolicyFinderModule +{ + + // the list of policy URLs passed to the constructor + private List policyList; + + // the map of policies + private PolicyCollection policies; + + // the optional schema file + private File schemaFile = null; + + // the logger we'll use for all messages + private static final Logger logger = + Logger.getLogger(StaticRefPolicyFinderModule.class.getName()); + + /** + * Creates a StaticRefPolicyFinderModule that provides + * access to the given collection of policies. Any policy that cannot + * be loaded will be noted in the log, but will not cause an error. The + * schema file used to validate policies is defined by the property + * PolicyReader.POLICY_SCHEMA_PROPERTY. If the retrieved + * property is null, then no schema validation will occur. + * + * @param policyList a List of Strings that + * represent URLs or files pointing to XACML policies + */ + public StaticRefPolicyFinderModule(List policyList) { + this.policyList = policyList; + this.policies = new PolicyCollection(); + + String schemaName = + System.getProperty(PolicyReader.POLICY_SCHEMA_PROPERTY); + if (schemaName != null) { + this.schemaFile = new File(schemaName); + } + } + + /** + * Creates a StaticRefPolicyFinderModule that provides + * access to the given collection of policyList. + * + * @param policyList a List of Strings that + * represent URLs or files pointing to XACML policies + * @param schemaFile the schema file to validate policies against, + * or null if schema validation is not desired + */ + public StaticRefPolicyFinderModule(List policyList, String schemaFile) { + this.policyList = policyList; + this.policies = new PolicyCollection(); + + if (schemaFile != null) { + this.schemaFile = new File(schemaFile); + } + } + + /** + * Always returns true since this module does support + * finding policies based on reference. + * + * @return true + */ + public boolean isIdReferenceSupported() { + return true; + } + + /** + * Initialize this module. Typically this is called by + * PolicyFinder when a PDP is created. This method is + * where the policies are actually loaded. + * + * @param finder the PolicyFinder using this module + */ + public void init(PolicyFinder finder) { + // now that we have the PolicyFinder, we can load the policies + PolicyReader reader = new PolicyReader(finder, logger, + this.schemaFile); + + Iterator it = this.policyList.iterator(); + while (it.hasNext()) { + String str = it.next(); + AbstractPolicy policy = null; + + try { + try { + // first try to load it as a URL + URL url = new URL(str); + policy = reader.readPolicy(url); + } catch (MalformedURLException murle) { + // assume that this is a filename, and try again + policy = reader.readPolicy(new File(str)); + } + + // we loaded the policy, so try putting it in the collection + if (! this.policies.addPolicy(policy)) { + if (logger.isLoggable(Level.WARNING)) { + logger.log(Level.WARNING, "tried to load the same " + + "policy multiple times: " + str); + } + } + } catch (ParsingException pe) { + if (logger.isLoggable(Level.WARNING)) { + logger.log(Level.WARNING, "Error reading policy: " + str, + pe); + } + } + } + } + + /** + * Attempts to find a policy by reference, based on the provided + * parameters. + * + * @param idReference an identifier specifying some policy + * @param type type of reference (policy or policySet) as identified by + * the fields in PolicyReference + * @param constraints any optional constraints on the version of the + * referenced policy (this will never be null, but + * it may impose no constraints, and in fact will + * never impose constraints when used from a pre-2.0 + * XACML policy) + * @param parentMetaData the meta-data from the parent policy, which + * provides XACML version, factories, etc. + * + * @return the result of looking for a matching policy + */ + public PolicyFinderResult findPolicy(URI idReference, int type, + VersionConstraints constraints, + PolicyMetaData parentMetaData) { + AbstractPolicy policy = this.policies.getPolicy(idReference.toString(), + type, constraints); + + if (policy == null) { + return new PolicyFinderResult(); + } + return new PolicyFinderResult(policy); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/TopLevelPolicyException.java b/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/TopLevelPolicyException.java new file mode 100644 index 0000000..0ec1998 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/TopLevelPolicyException.java @@ -0,0 +1,132 @@ + +/* + * @(#)TopLevelPolicyException.java + * + * Copyright 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.support.finder; + +import com.sun.xacml.ctx.Status; + + +/** + * This is an exception thrown by the support code when there's an error + * trying to resolve a top-level policy + * + * @since 2.0 + * @author Seth Proctor + */ +public class TopLevelPolicyException extends Exception +{ + + /** + * + */ + private static final long serialVersionUID = 1L; + + // status explaining the error + private transient Status status; + + /** + * Constructs a new TopLevelPolicyException with no message + * or cause. + * + * @param status the Status associated with this error + */ + public TopLevelPolicyException(Status status) { + this.status = status; + } + + /** + * Constructs a new TopLevelPolicyException with a message, + * but no cause. The message is saved for later retrieval by the + * {@link java.lang.Throwable#getMessage() Throwable.getMessage()} + * method. + * + * @param status the Status associated with this error + * @param message the detail message (null if nonexistent + * or unknown) + */ + public TopLevelPolicyException(Status status, String message) { + super(message); + + this.status = status; + } + + /** + * Constructs a new TopLevelPolicyException with a cause, + * but no message. The cause is saved for later retrieval by the + * {@link java.lang.Throwable#getCause() Throwable.getCause()} + * method. + * + * @param status the Status associated with this error + * @param cause the cause (null if nonexistent + * or unknown) + */ + public TopLevelPolicyException(Status status, Throwable cause) { + super(cause); + + this.status = status; + } + + /** + * Constructs a new TopLevelPolicyException 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 status the Status associated with this error + * @param message the detail message (null if nonexistent + * or unknown) + * @param cause the cause (null if nonexistent + * or unknown) + */ + public TopLevelPolicyException(Status status, String message, + Throwable cause) { + super(message, cause); + + this.status = status; + } + + /** + * Returns the status information associated with this error. + * + * @return associated status + */ + public Status getStatus() { + return this.status; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/URLPolicyFinderModule.java b/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/URLPolicyFinderModule.java new file mode 100644 index 0000000..ad66188 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/main/java/com/sun/xacml/support/finder/URLPolicyFinderModule.java @@ -0,0 +1,209 @@ + +/* + * @(#)URLPolicyFinderModule.java + * + * Copyright 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.support.finder; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.ParsingException; +import com.sun.xacml.Policy; +import com.sun.xacml.PolicyMetaData; +import com.sun.xacml.PolicyReference; +import com.sun.xacml.PolicySet; +import com.sun.xacml.VersionConstraints; + +import com.sun.xacml.finder.PolicyFinder; +import com.sun.xacml.finder.PolicyFinderModule; +import com.sun.xacml.finder.PolicyFinderResult; + +import java.io.File; + +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URL; + +import java.util.logging.Logger; + + +/** + * This module supports references made with resolvable URLs (eg, http or + * file pointers). No policies are cached. Instead, all policy references are + * resolved in real-time. To make this module as generally applicable as + * possible, no errors are ever returned when attempting to resolve a + * policy. This means that if a resolved policy is invalid, a server cannot + * be contacted, etc., this module simply reports that it cannot provide a + * policy. If you need to report errors, or support any caching, you have to + * write your own implementation. + *

+ * This module is provided as an example, but is still fully functional, and + * should be useful for many simple applications. This is provided in the + * support package rather than the core codebase because it + * implements non-standard behavior. + * + * @since 2.0 + * @author Seth Proctor + */ +public class URLPolicyFinderModule extends PolicyFinderModule +{ + + // the optional schema file for validating policies + private File schemaFile; + + // the reader used to load all policies + private PolicyReader reader; + + // the logger we'll use for all messages + private static final Logger logger = + Logger.getLogger(URLPolicyFinderModule.class.getName()); + + /** + * Creates a URLPolicyFinderModule. The schema file used + * to validate policies is specified by the property + * PolicyReader.POLICY_SCHEMA_PROPERTY. If the retrieved + * property is null, then no schema validation will occur. + */ + public URLPolicyFinderModule() { + String schemaName = + System.getProperty(PolicyReader.POLICY_SCHEMA_PROPERTY); + + if (schemaName != null) { + this.schemaFile = new File(schemaName); + } + } + + /** + * Creates a URLPolicyFinderModule that may do schema + * validation of policies. + * + * @param schemaFile the schema file to use for validation, or null if + * validation isn't desired + */ + public URLPolicyFinderModule(String schemaFile) { + this.schemaFile = new File(schemaFile); + } + + /** + * Always returns true since this module does support + * finding policies based on reference. + * + * @return true + */ + public boolean isIdReferenceSupported() { + return true; + } + + /** + * Initialize this module. Typically this is called by + * PolicyFinder when a PDP is created. + * + * @param finder the PolicyFinder using this module + */ + public void init(PolicyFinder finder) { + this.reader = new PolicyReader(finder, logger, this.schemaFile); + } + + /** + * Attempts to find a policy by reference, based on the provided + * parameters. Specifically, this module will try to treat the reference + * as a URL, and resolve that URL directly. If the reference is not + * a valid URL, cannot be resolved, or does not resolve to an XACML + * policy, then no matching policy is returned. This method never + * returns an error. + * + * @param idReference an identifier specifying some policy + * @param type type of reference (policy or policySet) as identified by + * the fields in PolicyReference + * @param constraints any optional constraints on the version of the + * referenced policy (this will never be null, but + * it may impose no constraints, and in fact will + * never impose constraints when used from a pre-2.0 + * XACML policy) + * @param parentMetaData the meta-data from the parent policy, which + * provides XACML version, factories, etc. + * + * @return the result of looking for a matching policy + */ + public PolicyFinderResult findPolicy(URI idReference, int type, + VersionConstraints constraints, + PolicyMetaData parentMetaData) { + // see if the URI is in fact a URL + URL url = null; + try { + url = new URL(idReference.toString()); + } catch (MalformedURLException murle) { + // it's not a URL, so we can't handle this reference + return new PolicyFinderResult(); + } + + // try resolving the URL + AbstractPolicy policy = null; + try { + policy = this.reader.readPolicy(url); + } catch (ParsingException pe) { + // An error loading the policy could be many things (the URL + // doesn't actually resolve a policy, the server is down, the + // policy is invalid, etc.). This could be interpreted as an + // error case, or simply as a case where no applicable policy + // is available (as is done when we pre-load policies). This + // module chooses the latter interpretation. + return new PolicyFinderResult(); + } + + // check that we got the right kind of policy...if we didn't, then + // we can't handle the reference + if (type == PolicyReference.POLICY_REFERENCE) { + if (! (policy instanceof Policy)) { + return new PolicyFinderResult(); + } + } else { + if (! (policy instanceof PolicySet)) { + return new PolicyFinderResult(); + } + } + + // finally, check that the constraints match ... note that in a more + // powerful module, you could actually have used the constraints to + // construct a more specific URL, passed the constraints to the + // server, etc., but this example module is staying simple + if (! constraints.meetsConstraint(policy.getVersion())) { + return new PolicyFinderResult(); + } + + // if we got here, then we successfully resolved a policy that is + // the correct type, so return it + return new PolicyFinderResult(policy); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/test/java/com/sun/xacml/support/AppTest.java b/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/test/java/com/sun/xacml/support/AppTest.java new file mode 100644 index 0000000..b209e7b --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml.support/src/test/java/com/sun/xacml/support/AppTest.java @@ -0,0 +1,73 @@ +/* + * @(#)AppTest.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.support; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/pom.xml b/GenericBreakGlass-XACML/src/com.sun.xacml/pom.xml new file mode 100644 index 0000000..f87ed65 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/pom.xml @@ -0,0 +1,65 @@ + + + 4.0.0 + + eu.aniketos.securebpmn.xacml + eu.aniketos.securebpmn.xacml.parent + 1.0 + ../eu.aniketos.securebpmn.xacml.parent/pom.xml + + com.sun.xacml + jar + 0.1 + com.sun.xacml + http://maven.apache.org + + + + 2.3.2 + org.apache.maven.plugins + maven-compiler-plugin + + 1.5 + 1.5 + + + + maven-assembly-plugin + 2.3 + + + jar-with-dependencies + + + + + + + + junit + junit + [4.8,) + test + + + log4j + log4j + [1.2,) + + + + + xalan + xalan + 2.7.1 + + + diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/AbstractPolicy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/AbstractPolicy.java new file mode 100644 index 0000000..a7936a7 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/AbstractPolicy.java @@ -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 children; + // ...or the CombinerElements that are passed to combining algorithms + private List childElements; + + // any obligations held by this policy + private Set obligations; + + // the list of combiner parameters + private List parameters; + + // the maximum delegation depth authorised by this AbstractPolicy. + private int maxDelegationDepth = Constants.MAX_DELEGATION_DEPTH_UNDEFINED; + + protected RuntimeInfo src; + + /** + * Constructor used by PolicyReference, 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 obligations, List 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(obligations)); + } + + if (parameters == null) { + this.parameters = CombinerParameter.EMPTY_LIST; + } else { + this.parameters = Collections. + unmodifiableList(new ArrayList(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(); + this.parameters = new ArrayList(); + 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(this.obligations); + clone.parameters = new ArrayList(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 issuerAttr = new HashSet(); + + for (int i = 0; i < nodes.getLength(); i++) { + Node node = nodes.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE + && node.getLocalName().equals("Attribute")) { + List 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 "1.0". + * + * @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 List of CombinerParameters + */ + public List 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 PolicyIssuer that represents the + * PolicyIssuer for this policy. + * + * @return a PolicyIssuer 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 List of children under this node in the + * policy tree. Depending on what kind of policy this node represents + * the children will either be AbstractPolicy objects + * or Rules. + * + * @return a List of child nodes + */ + public List getChildren() { + return this.children; + } + + /** + * Returns the List of CombinerElements that + * is provided to the combining algorithm. This returns the same set + * of children that getChildren provides along with any + * associated combiner parameters. + * + * @return a List of CombinerElements + */ + public List getChildElements() { + return this.childElements; + } + + /** + * Returns the Set of obligations for this policy, which may be empty + * + * @return the policy's obligations + */ + public Set 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 List must + * contain CombinerElements, which in turn will contain + * Rules or AbstractPolicys, but may not + * contain both types of elements. + * + * @param children1 a List of CombinerElements + * representing the child elements used by the combining + * algorithm + */ + protected void setChildren(List 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 list = new ArrayList(); + + 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 match 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 collectedObligations = new HashSet(); + + // 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 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 Policy and PolicySet 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 + ""); + indenter.in(); + + Iterator>> it = this.policyIssuer.getAttributes().entrySet() + .iterator(); + while (it.hasNext()) { + Map.Entry> entry = it.next(); + Iterator it2 = entry.getValue().iterator(); + while (it2.hasNext()) { + Attribute attr = it2.next(); + attr.encode(output, charsetName, indenter); + } + } + + out.println(indent + ""); + indenter.out(); + } + } + + + /** + * Routine used by Policy and PolicySet 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 + ""); + indenter.in(); + + Iterator oblIt = this.obligations.iterator(); + while (oblIt.hasNext()) { + oblIt.next().encode(output, charsetName, indenter); + } + + out.println(indent + ""); + 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; + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/BasicEvaluationCtx.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/BasicEvaluationCtx.java new file mode 100644 index 0000000..12632af --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/BasicEvaluationCtx.java @@ -0,0 +1,1154 @@ +/* + * @(#)BasicEvaluationCtx.java + * + * Copyright 2004-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.BagAttribute; +import com.sun.xacml.attr.DateAttribute; +import com.sun.xacml.attr.DateTimeAttribute; +import com.sun.xacml.attr.DecisionAttribute; +import com.sun.xacml.attr.StringAttribute; +import com.sun.xacml.attr.TimeAttribute; + +import com.sun.xacml.cond.EvaluationResult; + +import com.sun.xacml.ctx.Attribute; +import com.sun.xacml.ctx.RequestCtx; +import com.sun.xacml.ctx.RequestElement; +import com.sun.xacml.ctx.Result; + +import com.sun.xacml.finder.AttributeFinder; +import com.sun.xacml.finder.RevocationFinder; +import com.sun.xacml.reduction.ReductionGraph; + +import java.net.URI; + +import java.util.ArrayList; +import java.util.Date; +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 java.util.Stack; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Node; + + +/** + * A basic implementation of EvaluationCtx that is created from + * an XACML Request and falls back on an AttributeFinder if a requested + * value isn't available in the Request. + *

+ * Note that this class can do some optional caching for current date, time, + * and dateTime values (defined by a boolean flag to the constructors). The + * XACML specification requires that these values always be available, but it + * does not specify whether or not they must remain constant over the course + * of an evaluation if the values are being generated by the PDP (if the + * values are provided in the Request, then obviously they will remain + * constant). The default behavior is for these environment values to be + * cached, so that (for example) the current time remains constant over the + * course of an evaluation. + * + * @since 1.2 + * @author Seth Proctor + * @author Ludwig Seitz + */ +public class BasicEvaluationCtx implements EvaluationCtx, Cloneable +{ + /** + * the finder to use if a value isn't in the request + */ + private AttributeFinder aFinder; + + /** + * flag that indicates if the attribute finder is deactivated. + */ + private boolean afinderActive = true; + + /** + * the revocation finder to use + */ + private RevocationFinder rFinder; + + /** + * flag that indicates if the revocation finder is deactivated. + */ + private boolean rfinderActive = true; + /** + * the DOM root the original RequestContext document. + */ + private Node requestRoot; + + /** + * The request data. A map of Sets of + * RequestElements keyed by the attribute category + * Strings. + */ + private HashMap> requestElements = null; + + /** + * the cached delegation decision value + */ + private int delegationDecision; + + /** + * the delegation depth value + */ + private int delegationDepth; + + /** + * the resource id + */ + private AttributeValue resourceId; + + /** + * the Set of RequestElements containing + * only the attributes that should be included in the result. + */ + private Set includedAttributes; + + /** + * the resource scope + */ + private int scope; + + /** + * the cached current date, which we may or may + * not be using depending on how this object was constructed + */ + private DateAttribute currentDate; + + /** + * the cached current time, which we may or may + * not be using depending on how this object was constructed + */ + private TimeAttribute currentTime; + + /** + * the cached current dateTime, which we may or may + * not be using depending on how this object was constructed + */ + private DateTimeAttribute currentDateTime; + + /** + * a flag indicating that we should use the cached date/time values. + */ + private boolean useCachedEnvValues; + + /** + * a stack of parent PolicySets. + */ + private Stack parentPolicySets; + + /** + * a stack of ReductionGraphs. + */ + private Stack reductionGraphs; + + /** + * the set of deactivated policies + */ + private Set inactivePolicyIds; + + /** + * the logger we'll use for all messages + */ + private static final Logger logger = + Logger.getLogger(BasicEvaluationCtx.class.getName()); + + /** + * Constructs a new BasicEvaluationCtx based on the given + * request. The resulting context will cache current date, time, and + * dateTime values so they remain constant for this evaluation. + * + * @param request the request + * + * @throws ParsingException if a required attribute is missing, or if there + * are any problems dealing with the request data + */ + public BasicEvaluationCtx(RequestCtx request) + throws ParsingException { + this(request, null, null, true); + } + + /** + * Constructs a new BasicEvaluationCtx based on the given + * request. + * + * @param request the request + * @param cacheEnvValues whether or not to cache the current time, date, + * and dateTime so they are constant for the scope + * of this evaluation + * + * @throws ParsingException if a required attribute is missing, or if there + * are any problems dealing with the request data + */ + public BasicEvaluationCtx(RequestCtx request, boolean cacheEnvValues) + throws ParsingException { + this(request, null, null, cacheEnvValues); + } + + /** + * Constructs a new BasicEvaluationCtx based on the given + * request, and supports looking outside the original request for attribute + * values using the AttributeFinder. The resulting context + * will cache current date, time, and dateTime values so they remain + * constant for this evaluation. + * + * @param request the request + * @param aFinder an AttributeFinder to use in looking for + * attributes that aren't in the request + * @param rFinder an RevocationFinder to use in looking for + * revocations + * + * @throws ParsingException if a required attribute is missing, or if there + * are any problems dealing with the request data + */ + public BasicEvaluationCtx(RequestCtx request, AttributeFinder aFinder, + RevocationFinder rFinder) + throws ParsingException { + this(request, aFinder, rFinder, true); + } + + /** + * Constructs a new BasicEvaluationCtx based on the given + * request, and supports looking outside the original request for attribute + * values using the AttributeFinder. + * + * @param request the request + * @param aFinder an AttributeFinder to use in looking for + * @param rFinder an RevocationFinder to use in looking for + * revocations + * attributes that aren't in the request + * @param cacheEnvValues whether or not to cache the current time, date, + * and dateTime so they are constant for the scope + * of this evaluation + * + * @throws ParsingException if a required attribute is missing, or if there + * are any problems dealing with the request data + */ + public BasicEvaluationCtx(RequestCtx request, AttributeFinder aFinder, + RevocationFinder rFinder, + boolean cacheEnvValues) + throws ParsingException { + // keep track of the attribute finder + this.aFinder = aFinder; + // keep track of the revocation finder + this.rFinder = rFinder; + + // remember the root of the DOM tree for XPath queries + this.requestRoot = request.getDocumentRoot(); + + // initialize the cached date/time values so it's clear we haven't + // retrieved them yet + this.useCachedEnvValues = cacheEnvValues; + this.currentDate = null; + this.currentTime = null; + this.currentDateTime = null; + + // parse the request elements into a map + // and collect the IncludeInResult attributes + this.requestElements = new HashMap>(); + this.includedAttributes = new HashSet(); + Iterator iter = request.getRequestElements().iterator(); + while (iter.hasNext()){ + RequestElement re = iter.next(); + URI category = re.getCategory(); + if (!re.getIncludeInResultSet().isEmpty()) { + this.includedAttributes.add(new RequestElement( + re.getCategory(), re.getIncludeInResultSet())); + } + if (this.requestElements.containsKey(category)) { + this.scope = Constants.SCOPE_MULTIPE_ELEMENTS; + Set set = this.requestElements.get(category); + set.add(re); + } else { + Set set = new HashSet(); + set.add(re); + this.requestElements.put(category, set); + } + } + + //Compatibility code for XACML 2.0 requestId handling + if (request.getXACMLVersion() < Constants.XACML_VERSION_3_0 + && !this.includedAttributes.isEmpty()) { + throw new ParsingException("Can't have included attributes" + + " in XACML < v 3.0"); + } + + //Compatibility code for old Resource handling. + if (this.requestElements.containsKey(Constants.RESOURCE_CAT)) { + Iterator reIt = this.requestElements.get( + Constants.RESOURCE_CAT).iterator(); + while(reIt.hasNext()) { + RequestElement re = (RequestElement)reIt.next(); + checkResource(re.getAttributes()); + } + } + + //this will only be set in administrative requests. + this.delegationDecision = Result.INVALID_DECISION; + this.delegationDepth = 0; + + this.parentPolicySets = new Stack(); + this.reductionGraphs = new Stack(); + + // this is empty when the evaluation context is first created + // it is used during the reduction of untrusted policies + this.inactivePolicyIds = new HashSet(); + } + + /** + * The clone method + * + * @return a copy of this object. + * + */ + public Object clone() { + try { + BasicEvaluationCtx clone = (BasicEvaluationCtx)super.clone(); + if (this.aFinder != null) { + clone.aFinder = (AttributeFinder)this.aFinder.clone(); + } + clone.afinderActive = this.afinderActive; + if(this.rFinder != null) { + clone.rFinder = (RevocationFinder)this.rFinder.clone(); + } + clone.rfinderActive = this.rfinderActive; + if(this.requestRoot != null) { + clone.requestRoot = this.requestRoot.cloneNode(true); + } else { + clone.requestRoot = null; + } + + // deep copy of the requestElements + clone.requestElements = new HashMap>(); + Iterator iter = this.requestElements.keySet().iterator(); + while(iter.hasNext()) { + URI key = URI.create(iter.next().toString()); + Set res = new HashSet(); + Iterator iter2 = this.requestElements.get(key).iterator(); + while(iter2.hasNext()) { + res.add((RequestElement)iter2.next().clone()); + } + clone.requestElements.put(key, res); + } + + clone.delegationDecision = this.delegationDecision; + clone.delegationDepth = this.delegationDepth; + clone.resourceId = this.resourceId; + + //deep copy of the included attributes + clone.includedAttributes = new HashSet(); + Iterator iter3 = this.includedAttributes.iterator(); + while(iter3.hasNext()) { + RequestElement element = iter3.next(); + clone.includedAttributes.add( (RequestElement) element.clone()); + } + synchronized (clone) { + clone.scope = this.scope; + clone.currentDate = this.currentDate; + clone.currentTime = this.currentTime; + clone.currentDateTime = this.currentDateTime; + clone.useCachedEnvValues = this.useCachedEnvValues; + } + //clone.parentPolicySets = (Stack) this.parentPolicySets.clone(); // + clone.parentPolicySets = new Stack(); + Collections.copy(parentPolicySets, this.parentPolicySets); + //clone.reductionGraphs = (Stack) this.reductionGraphs.clone(); + clone.reductionGraphs = new Stack(); + Collections.copy(reductionGraphs, this.reductionGraphs); + clone.inactivePolicyIds = new HashSet(this.inactivePolicyIds); + return clone; + } catch (CloneNotSupportedException e) {//This should never happen + throw new RuntimeException("Couldn't clone BasicEvaluationCtx"); + } + } + + /** + * Create a context for an administrative request from this context. + * + * @param decision The decision code corresponding to those in the + * Result class. + * @param delegate The delegate in this request (a set containing a + * single RequestElement). + * + * @return An administrative context for this context. + */ + public EvaluationCtx createAdminCtx(int decision, Set delegate) { + if (decision == Result.INVALID_DECISION + || decision == Result.DECISION_INDETERMINATE + || decision == Result.DECISION_NOT_APPLICABLE) { + throw new ProcessingException("Invalid decision value for an" + + " administrative request"); + } + + //First copy the old context. + BasicEvaluationCtx adminCtx = null; + adminCtx = (BasicEvaluationCtx)this.clone(); + + //Now set the new values ... + adminCtx.delegationDecision = decision; + adminCtx.delegationDepth = this.delegationDepth + 1; + + //... and modify the requestElements accordingly + HashMap> newREmap = new HashMap>(); + + //get out the delegation relevant information + // and remove the old + adminCtx.requestElements.remove(Constants.DELEGATION_INFO); + adminCtx.requestElements.remove(Constants.DELEGATE); + + //modify the rest so category * becomes category + // urn:oasis:names:tc:xacml:3.0:attribute-category:delegated:* + Iterator>> iter = adminCtx.requestElements.entrySet().iterator(); + while(iter.hasNext()) { + Map.Entry> entry = iter.next(); + Set requestElementCategory = entry.getValue(); + Iterator iter2 = requestElementCategory.iterator(); + HashSet newREset = new HashSet(); + URI category = null; + while(iter2.hasNext()) { + RequestElement oldRe = iter2.next(); + category = oldRe.getCategory(); + if (category.toString().startsWith(Constants.DELEGATED)) { + newREset.add(oldRe); + } else { // add the delegated part to the category + category = URI.create(Constants.DELEGATED + + category.toString()); + // this URI must be valid, since the old category was + RequestElement newRe = new RequestElement(category, + oldRe.getAttributes()); + newREset.add(newRe); + } + } + newREmap.put(category, newREset); + } + + //put in the new delegate + newREmap.put(Constants.DELEGATE, delegate); + + //put in the new delegation info + + // then create the correct DelegationInfo category + DecisionAttribute delegationDecision = new DecisionAttribute(decision); + Set delegationInfoAttrs = new HashSet(); + delegationInfoAttrs.add(delegationDecision); + RequestElement delegationInfo = new RequestElement( + Constants.DELEGATION_INFO, delegationInfoAttrs); + Set delegationInfoSet = new HashSet(); + delegationInfoSet.add(delegationInfo); + // and put it into the new request elements map + newREmap.put(Constants.DELEGATION_INFO, delegationInfoSet); + + //now we are done, copy the newREmap to the requestElements + adminCtx.requestElements = newREmap; + + return adminCtx; + } + + /** + * Creates a copy of this context with disabled attribute finder. + * + * @return A copy of this context with disabled attribute finder. + */ + public EvaluationCtx copyWithoutAttributeFinder() { + BasicEvaluationCtx ctx = (BasicEvaluationCtx)this.clone(); + ctx.aFinder = null; + ctx.afinderActive = false; + return ctx; + } + + /** + * This basically does the same thing that the other types need + * to do, except that we also look for a resource-id attribute, not + * because we're going to use, but only to make sure that it's not + * double, and for the optional scope attribute, to see what the scope + * of the attribute is. + * + * @param resourceAttr A Map keyed by attribute id + * URIs, containing Sets + * of Attributes. + * @param xacmlVersion The XACML version number. + * + * @throws ParsingException + * + */ + private void checkResource(Map> resourceAttr) + throws ParsingException { + + // make sure there's only one value for resource-id + Set rSet = resourceAttr.get(Constants.RESOURCE_ID); + if (rSet != null) { + if (rSet.size() > 1) { + System.err.println("Resource may contain " + + "only one resource-id Attribute"); + throw new ParsingException("too many resource-id attrs"); + } + // keep track of the resource-id attribute + this.resourceId = ((Attribute)(rSet.iterator().next())) + .getValue(); + } + + + // see if a resource-scope attribute was included + if (resourceAttr.containsKey(Constants.RESOURCE_SCOPE)) { + Set set = resourceAttr.get(Constants.RESOURCE_SCOPE); + + // make sure there's only one value for resource-scope + if (set.size() > 1) { + System.err.println("Resource may contain " + + "only one resource-scope Attribute"); + throw new ParsingException("too many resource-scope attrs"); + } + + Attribute attr = (Attribute)(set.iterator().next()); + AttributeValue attrValue = attr.getValue(); + + // scope must be a string, so throw an exception otherwise + if (! attrValue.getType().toString(). + equals(StringAttribute.identifier)) { + throw new ParsingException("scope attr must be a string"); + } + + String value = ((StringAttribute)attrValue).getValue(); + + if (value.equals("Immediate")) { + this.scope = Constants.SCOPE_IMMEDIATE; + } else if (value.equals("Children")) { + this.scope = Constants.SCOPE_CHILDREN; + } else if (value.equals("Descendants")) { + this.scope = Constants.SCOPE_DESCENDANTS; + } else if (value.equals("XPath-expression")) { + this.scope = Constants.SCOPE_XPATH_EXPRESSION; + } else if (value.equals("EntireHierarchy")) { + this.scope = Constants.SCOPE_ENTIRE_HIERARCHY; + } else { + System.err.println("Unknown scope type: " + value); + throw new ParsingException("invalid scope type: " + value); + } + } else { + // by default, the scope is always Immediate + this.scope = Constants.SCOPE_IMMEDIATE; + } + } + + /** + * Returns the DOM root of the original RequestType XML document. + * + * @return the DOM root node + */ + public Node getRequestRoot() { + return this.requestRoot; + } + + /** + * Returns the resource scope of the request, which will be one of the + * three fields denoting Immediate, Children, or Descendants. + * + * @return the scope of the resource in the request + */ + public int getScope() { + return this.scope; + } + + /** + * Returns the resource named in the request as resource-id. + * + * @return the resource + */ + public AttributeValue getResourceId() { + return this.resourceId; + } + + /** + * @return The Set of RequestElements + * representing the included attributes. + */ + public Set getIncludedAttributes() { + return this.includedAttributes; + } + + /** + * 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) { + this.resourceId = resourceId; + + // there will always be exactly one value for this attribute + Iterator rIt = this.requestElements.get(Constants.RESOURCE_CAT).iterator(); + while (rIt.hasNext()) { + RequestElement re = rIt.next(); + Map> attrMap = re.getAttributes(); + Set resId = attrMap.get(Constants.RESOURCE_ID); + Attribute attr = (Attribute)(resId.iterator().next()); + // remove the old value... + resId.remove(attr); + Attribute newAttr = new Attribute(attr.getId(), attr.getIssuer(), + resourceId, + attr.getVersion(), + attr.includeInResult()); + // if it was marked to be included in the result remove this too + if (attr.includeInResult()) { + Iterator iter = this.includedAttributes.iterator(); + while (iter.hasNext()) { + RequestElement ire = iter.next(); + if (ire.getCategory().equals(Constants.RESOURCE_CAT)) { + this.includedAttributes.remove(ire); + Map> newAttrs = new HashMap>(); + newAttrs.putAll(ire.getAttributes()); + newAttrs.remove(Constants.RESOURCE_ID); + Set newResourceId = new HashSet(); + newResourceId.add(newAttr); + newAttrs.put(Constants.RESOURCE_ID, newResourceId); + this.includedAttributes.add(new RequestElement( + ire.getCategory(), newAttrs)); + } + } + } + // ...and insert the new value + resId.add(newAttr); + } + } + + /** + * Returns the value for the current time. The current time, current + * date, and current dateTime are consistent, so that they all + * represent the same moment. If this is the first time that one + * of these three values has been requested, and caching is enabled, + * then the three values will be resolved and stored. + *

+ * Note that the value supplied here applies only to dynamically + * resolved values, not those supplied in the Request. In other words, + * this always returns a dynamically resolved value local to the PDP, + * even if a different value was supplied in the Request. This is + * handled correctly when the value is requested by its identifier. + * + * @return the current time + */ + public synchronized TimeAttribute getCurrentTime() { + long millis = dateTimeHelper(); + if (this.useCachedEnvValues) { + return this.currentTime; + } + return new TimeAttribute(new Date(millis)); + } + + /** + * Returns the value for the current date. The current time, current + * date, and current dateTime are consistent, so that they all + * represent the same moment. If this is the first time that one + * of these three values has been requested, and caching is enabled, + * then the three values will be resolved and stored. + *

+ * Note that the value supplied here applies only to dynamically + * resolved values, not those supplied in the Request. In other words, + * this always returns a dynamically resolved value local to the PDP, + * even if a different value was supplied in the Request. This is + * handled correctly when the value is requested by its identifier. + * + * @return the current date + */ + public synchronized DateAttribute getCurrentDate() { + long millis = dateTimeHelper(); + + if (this.useCachedEnvValues) { + return this.currentDate; + } + return new DateAttribute(new Date(millis)); + } + + /** + * Returns the value for the current dateTime. The current time, current + * date, and current dateTime are consistent, so that they all + * represent the same moment. If this is the first time that one + * of these three values has been requested, and caching is enabled, + * then the three values will be resolved and stored. + *

+ * Note that the value supplied here applies only to dynamically + * resolved values, not those supplied in the Request. In other words, + * this always returns a dynamically resolved value local to the PDP, + * even if a different value was supplied in the Request. This is + * handled correctly when the value is requested by its identifier. + * + * @return the current dateTime + */ + public synchronized DateTimeAttribute getCurrentDateTime() { + long millis = dateTimeHelper(); + + if (this.useCachedEnvValues) { + return this.currentDateTime; + } + return new DateTimeAttribute(new Date(millis)); + } + + /** + * Private helper that figures out if we need to resolve new values, + * and returns either the current moment (if we're not caching) or + * -1 (if we are caching) + * + * @return returns the current moment or -1. + */ + private long dateTimeHelper() { + // if we already have current values, then we can stop (note this + // always means that we're caching) + if (this.currentTime != null) { + return -1; + } + + // get the current moment + Date time = new Date(); + long millis = time.getTime(); + + // if we're not caching then we just return the current moment + if (! this.useCachedEnvValues) { + return millis; + } + // we're caching, so resolve all three values, making sure + // to use clean copies of the date object since it may be + // modified when creating the attributes + this.currentTime = new TimeAttribute(time); + this.currentDate = new DateAttribute(new Date(millis)); + this.currentDateTime = new DateTimeAttribute(new Date(millis)); + + return -1; + } + + /** + * 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) { + Set elements = this.requestElements.get(category); + if (elements == null) { + elements = RequestElement.EMPTY_SET; + } + return getGenericAttributes(category, type, id, issuer, + elements, false); + } + + /** + * Helper function for the resource, action, environment and delegate + * methods to get an attribute. + * + * @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 + * @param elements a set of RequestElements to search for + * the requested attribute. + * @param local get only local attributes, don't call the + * AttributeFinder. + * + * @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. + * + */ + private EvaluationResult getGenericAttributes(URI category, URI type, + URI id, URI issuer, Set elements, boolean local) { + + Iterator iter = elements.iterator(); + Set attrSet = new HashSet(); + while (iter.hasNext()) { + RequestElement element = iter.next(); + // try to find the id + Map> map = element.getAttributes(); + if (map.containsKey(id)) { + attrSet.addAll(map.get(id)); + } + } + + if (attrSet.isEmpty()) { + if (local) { + return new EvaluationResult(BagAttribute.createEmptyBag(type)); + } + // the request didn't have an attribute with that id, so we should + // try asking the attribute finder + return callHelper(category, type, id, issuer, elements); + } + + // now go through each, considering each Attribute object + List attributes = new ArrayList(); + Iterator it = attrSet.iterator(); + + while (it.hasNext()) { + Attribute attr = it.next(); + + // make sure the type and issuer are correct + if ((attr.getValue().getType().equals(type)) && + ((issuer == null) || + ((attr.getIssuer() != null) && + (attr.getIssuer().equals(issuer.toString()))))) { + + // if we got here, then we found a match, so we want to pull + // out the values and put them in out list + attributes.add(attr.getValue()); + } + } + + // see if we found any acceptable attributes + if (attributes.size() == 0) { + if (local) { + return new EvaluationResult(BagAttribute.createEmptyBag(type)); + } + // we failed to find any that matched the type/issuer, or all the + // Attribute types were empty...so ask the finder +// if (logger.isLoggable(Level.FINE)) { +// logger.fine("Attribute not in request: " + id.toString() + +// " ... querying AttributeFinder"); +// } + if (logger.isDebugEnabled()) { + logger.debug("Attribute not in request: " + id.toString() + " category " + category + + " ... querying AttributeFinder"); + } + + return callHelper(category, type, id, issuer, elements); + } + + // if we got here, then we found at least one useful AttributeValue + return new EvaluationResult(new BagAttribute(type, attributes)); + } + + /** + * Protected helper that calls the finder if it's non-null, or else returns + * an empty bag. (Proctected so it can be overridden by subclasses). + * + * @param category the category the attribute value(s) must be in or null + * @param type the type of the attribute value(s) to find or null + * @param id the id of the attribute value(s) to find or null + * @param issuer the issuer of the attribute value(s) to find or null + * @param elements a set of RequestElements to search for the + * requested attribute. + * + * @return an EvaluationResult containing the requested + * attribute or an empty bag. + */ + protected EvaluationResult callHelper(URI category, URI type, URI id, + URI issuer, Set elements) { + if (this.aFinder != null) { + return this.aFinder.findAttribute(category, type, id, issuer, + this); + } + if (this.afinderActive) { + logger.warn("Context tried to invoke AttributeFinder but was " + + "not configured with one"); + } + return new EvaluationResult(BagAttribute.createEmptyBag(type)); + } + + /** + * 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) { + if (this.aFinder != null) { + return this.aFinder.findAttribute(contextPath, namespaceNode, + type, this, xpathVersion); + } + logger.warn("Context tried to invoke AttributeFinder but was " + + "not configured with one"); + + return new EvaluationResult(BagAttribute.createEmptyBag(type)); + } + + /** + * Get the decision. + * + * @return The int value of the decision according to + * the Result class. + */ + public int getDecision() { + return this.delegationDecision; + } + + /** + * Get the delegation depth. + * + * @return The int value specifying the number of nodes + * in the reduction graph until now (not including this one). + */ + public int getDelegationDepth() { + return this.delegationDepth; + } + + /** + * Get a whole category. + * + * @param category The name of the category. If the category does + * not exist return an empty set + * + * @return The Set of RequestElements with + * the matching category. + */ + public Set getCategory(URI category) { + if (this.requestElements.containsKey(category)) { + return new HashSet(this.requestElements.get(category)); + } + return RequestElement.EMPTY_SET; + } + + /** + * @return the Set of RequestElements + * containing the attributes that should be included + * in the result. + */ + public Set getIncludedAttrs() { + return this.includedAttributes; + } + + /** + * @return the Map of RequestElements + * defining this request. + */ + public Map> getRequestElements() { + return Collections.unmodifiableMap(this.requestElements); + } + + /** + * Save the parent PolicySet 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) { + if (pps instanceof PolicySet) { + this.parentPolicySets.push(pps); + } else if (pps instanceof PolicyReference) { + PolicyReference pr = (PolicyReference)pps; + if (pr.getReferenceType() != PolicyReference.POLICYSET_REFERENCE) { + //this should never happen + throw new RuntimeException("Tried to save a Reference " + + "to a Policy as a PolicySet"); + } + this.parentPolicySets.push(pps); + } else { + throw new RuntimeException("Tried to save " + + this.getClass().getName() + " as a PolicySet"); + } + } + + + /** + * Create a reduction graph for the current parent PolicySet. + * + */ + public void createReductionGraph() { + this.reductionGraphs.push(new ReductionGraph(getParentPolicySet())); + } + + + /** + * @return The current reduction graph or null if there is none. + */ + public ReductionGraph getReductionGraph() { + if (this.reductionGraphs != null && !this.reductionGraphs.empty()) { + return (ReductionGraph)this.reductionGraphs.peek(); + } + return null; + } + + /** + * Remove the current ReductionGraph from the stack. + */ + public void popReductionGraph() { + if (!this.reductionGraphs.isEmpty()) { + this.reductionGraphs.pop(); + } + } + + /** + * Returns the root PolicySet for this evaluation context. + * If there is none, return null. + * + * @return the root policy set or null. + */ + public AbstractPolicy getParentPolicySet() { + if (!this.parentPolicySets.empty()) { + return (AbstractPolicy) this.parentPolicySets.peek(); + } + return null; + } + + /** + * Remove the current parent PolicySet from the stack + * of parent policy sets. + */ + public void popParentPolicySet() { + if (!this.parentPolicySets.isEmpty()) { + this.parentPolicySets.pop(); + } + } + + /** + * Checks whether a Policy or PolicySet + * 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) { + if (this.rFinder != null && this.rfinderActive) { + //deactivate revocation finder to avoid infinite loops + // of policies revoking themselves + this.rfinderActive = false; + boolean result = this.rFinder.supportsRevocation(supporting, + candidate, this); + this.rfinderActive = true; + return result; + } + // since there is no revocation finder, no policy can be + // revoked. + logger.warn("Context tried to invoke RevocationFinder but was " + + "not configured with one"); + return false; + } + + /** + * Add new inactive PolicyId to the Map + * @param policyId the id of the new inactive policy + */ + public void addInactivePolicyId(URI policyId) { + this.inactivePolicyIds.add(policyId); + } + + /** + * Return an unmodifiable Set of URIs of + * inactive policies + * @return the inactive policies + */ + public Set getInactivePolicyIds() { + return Collections.unmodifiableSet( + new HashSet(this.inactivePolicyIds)); + } + + /** + * Signal a new event to this EvaluationCtx. + * BasicEvaluationCtx does nothing with this signal. + * + * @param element The new event. + */ + public void newEvent(Object element) { + //BasicEvaluationCtx does nothing with this signal. + } + + /** + * Signal that an event has finished and pass the result. + * BasicEvaluationCtx does nothing with this signal. + * + * @param result The result of the finished event. + */ + public void closeCurrentEvent(Result result) { + //BasicEvaluationCtx does nothing with this signal. + } + + /** + * Signal that an event has finished and pass the result. + * BasicEvaluationCtx does nothing with this signal. + * + * @param result The result of the finished event. + */ + public void closeCurrentEvent(MatchResult result) { + //BasicEvaluationCtx does nothing with this signal. + } + + /** + * Signal that an event has finished and pass the result + * which is a EvaluationResult + * BasicEvaluationCtx does nothing with this signal. + * + * @param result The result of the finished event. + */ + public void closeCurrentEvent(EvaluationResult result) { + //BasicEvaluationCtx does nothing with this signal. + } + + /** + * Signal that an event has finished with a String message. + * BasicEvaluationCtx does nothing with this signal. + * + * @param message The message. + */ + public void closeCurrentEvent(String message) { + //BasicEvaluationCtx does nothing with this signal. + } + + /** + * Signal that an event has finished with no result. + * BasicEvaluationCtx does nothing with this signal. + */ + public void closeCurrentEvent() { + //BasicEvaluationCtx does nothing with this signal. + } +} \ No newline at end of file diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ConfigurationStore.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ConfigurationStore.java new file mode 100644 index 0000000..f657cde --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ConfigurationStore.java @@ -0,0 +1,1408 @@ + +/* + * @(#)ConfigurationStore.java + * + * Copyright 2004-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.AttributeDesignator; +import com.sun.xacml.attr.AttributeFactory; +import com.sun.xacml.attr.AttributeFactoryProxy; +import com.sun.xacml.attr.AttributeProxy; +import com.sun.xacml.attr.BaseAttributeFactory; +import com.sun.xacml.attr.StandardAttributeFactory; + +import com.sun.xacml.combine.BaseCombiningAlgFactory; +import com.sun.xacml.combine.CombiningAlgFactory; +import com.sun.xacml.combine.CombiningAlgFactoryProxy; +import com.sun.xacml.combine.CombiningAlgorithm; +import com.sun.xacml.combine.StandardCombiningAlgFactory; + +import com.sun.xacml.cond.BaseFunctionFactory; +import com.sun.xacml.cond.BasicFunctionFactoryProxy; +import com.sun.xacml.cond.Function; +import com.sun.xacml.cond.FunctionProxy; +import com.sun.xacml.cond.FunctionFactory; +import com.sun.xacml.cond.FunctionFactoryProxy; +import com.sun.xacml.cond.StandardFunctionFactory; + +import com.sun.xacml.cond.cluster.FunctionCluster; + +import com.sun.xacml.finder.AttributeFinder; +import com.sun.xacml.finder.AttributeFinderModule; +import com.sun.xacml.finder.PolicyFinder; +import com.sun.xacml.finder.PolicyFinderModule; +import com.sun.xacml.finder.RequiredAttributesModule; +import com.sun.xacml.finder.ResourceFinder; +import com.sun.xacml.finder.ResourceFinderModule; +import com.sun.xacml.finder.RevocationFinder; +import com.sun.xacml.finder.RevocationFinderModule; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import java.net.URI; +import java.net.URISyntaxException; + +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.apache.log4j.Logger; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.xml.sax.SAXException; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + + +/** + * This class supports run-time loading of configuration data. It loads the + * configurations from an XML file that conforms to the configuration schema. + * By design this class does not get used automatically, nor does it change + * the state of the system directly. A programmer must choose to support this + * mechanism in their program, and then must explicitly use loaded elements. + * This way, the programmer still has full control over their security model, + * but also has the convenience of re-using a common configuration + * mechanism. See http://sunxacml.sourceforge.net/schema/config-0.4.xsd for + * the valid schema. + *

+ * Note that becuase this doesn't tie directly into the rest of the code, you + * are still free to design your own run-time configuration mechanisms. This + * is simply provided as a convenience, and so that all programmers can start + * from a common point. + * + * @since 1.2 + * @author Seth Proctor + */ +public class ConfigurationStore +{ + + /** + * Property used to specify the configuration file. + */ + public static final String PDP_CONFIG_PROPERTY = + "com.sun.xacml.PDPConfigFile"; + + // pdp elements + private PDPConfig defaultPDPConfig; + private HashMap pdpConfigMap; + + // attribute factory elements + private AttributeFactory defaultAttributeFactory; + private HashMap attributeMap; + + // combining algorithm factory elements + private CombiningAlgFactory defaultCombiningFactory; + private HashMap combiningMap; + + // function factory elements + private FunctionFactoryProxy defaultFunctionFactoryProxy; + private HashMap functionMap; + + private Map customAttr = new HashMap(); + + // the classloader we'll use for loading classes + private ClassLoader loader; + +// // directory as base, where all files are searched +// @Deprecated +// private static String static_baseDir; +// + private String baseDir; + + public static final String BASEDIR = "BASEDIR"; + + // the logger we'll use for all messages + private static final Logger logger = + Logger.getLogger(ConfigurationStore.class.getName()); + + /** + * Default constructor. This constructor uses the + * PDP_CONFIG_PROPERTY property to load the configuration. + * If the property isn't set, if it names a file that can't be accessed, + * or if the file is invalid, then an exception is thrown. + * + * @throws ParsingException if anything goes wrong during the parsing + * of the configuration file, the class loading, + * or the factory and pdp setup + */ + public ConfigurationStore() throws ParsingException { + String configFile = System.getProperty(PDP_CONFIG_PROPERTY); + + // make sure that the right property was set + if (configFile == null) { + logger.warn("A property defining a config file was expected, " + + "but none was provided"); + + throw new ParsingException("Config property " + + PDP_CONFIG_PROPERTY + + " needs to be set"); + } + + try { + //setupConfig(new File(static_baseDir + configFile)); + setupConfig(new File(configFile)); + } catch (ParsingException pe) { + logger.error("Runtime config file (" + configFile + ") couldn't be loaded" + + " so no configurations will be available", pe); + throw pe; + } + } + + /** + * Constructor that explicitly specifies the configuration file to load. + * This is useful if your security model doesn't allow the use of + * properties, if you don't want to use a property to specify a + * configuration file, or if you want to use more then one configuration + * file. If the file can't be accessed, or if the file is invalid, then + * an exception is thrown. + * + * @param configFile The configuration file. + * + * @throws ParsingException if anything goes wrong during the parsing + * of the configuration file, the class loading, + * or the factory and pdp setup + */ + public ConfigurationStore(File configFile) throws ParsingException { + // if there is no baseDir, it is assumed that the rest of the + //configuration files are stored in the same directory as the confFile + // if there is no file.separator, baseDir is set to "" + String absPath = configFile.getAbsolutePath(); + String baseDir = absPath.substring(0, + absPath.lastIndexOf(System.getProperty("file.separator")) + 1 ); + init(configFile, baseDir); + } + + + /** + * Constructor that explicitly specifies the configuration file to load. + * This is useful if your security model doesn't allow the use of + * properties, if you don't want to use a property to specify a + * configuration file, or if you want to use more then one configuration + * file. If the file can't be accessed, or if the file is invalid, then + * an exception is thrown. + * + * @param configFile The configuration file. + * + * @throws ParsingException if anything goes wrong during the parsing + * of the configuration file, the class loading, + * or the factory and pdp setup + */ + public ConfigurationStore(File configFile, String baseDir) throws ParsingException { + init(configFile, baseDir); + } + + public ConfigurationStore(InputStream configFile, String baseDir) throws ParsingException { + init(configFile, baseDir); + } + + public ConfigurationStore(String configuration, Map customAttrs) throws ParsingException { + this.customAttr = customAttrs; + if ( customAttrs.containsKey(BASEDIR)) { + this.baseDir = (String) customAttrs.get(BASEDIR); + } + init(configuration); + } + + private void init(File configFile, String baseDir) throws ParsingException { + setBaseDir(baseDir); + try { + setupConfig(configFile); + } catch (ParsingException pe) { + logger.warn("Runtime config file (" + configFile + ")couldn't be loaded" + + " so no configurations will be available", pe); + throw pe; + } + } + + private void init(InputStream configFile, String baseDir) throws ParsingException { + setBaseDir(baseDir); + try { + setupConfig(configFile); + } catch (ParsingException pe) { + logger.warn("Runtime config file (" + configFile + ")couldn't be loaded" + + " so no configurations will be available", pe); + throw pe; + } + } + + protected void init(String configuration) throws ParsingException { + setBaseDir(""); + try { + setupConfig(configuration); + } catch (ParsingException pe) { + logger.warn("Runtime configuration couldn't be loaded" + + " so no configurations will be available (" + pe.getMessage() + ")", pe); + throw pe; + } + } + + private void setBaseDir(String baseDir) { + if ( baseDir == null ) { + baseDir = ""; + } + this.baseDir = baseDir; + customAttr.put(BASEDIR, baseDir); + } + + private void setupConfig(String configuration) throws ParsingException { + setupConfig(getRootNode(configuration)); + } + + private void setupConfig(InputStream configuration) throws ParsingException { + setupConfig(getRootNode(configuration)); + } + + private void setupConfig(File configFile) throws ParsingException { + setupConfig(getRootNode(configFile)); + } + + /** + * Private helper function used by both constructors to actually load the + * configuration data. This is the root of several private methods used + * to setup all the pdps and factories. + * + * @param configFile The configuration file. + * + * @throws ParsingException + */ + //private void setupConfig(File configFile) throws ParsingException { + private void setupConfig(Node root) throws ParsingException { + logger.info("Loading runtime configuration"); + + // load our classloader + this.loader = getClass().getClassLoader(); + + // get the root node from the configuration file + //Node root = getRootNode(configFile); + + // initialize all the maps + this.pdpConfigMap = new HashMap(); + this.attributeMap = new HashMap(); + this.combiningMap = new HashMap(); + this.functionMap = new HashMap(); + if ( customAttr == null ) { + this.customAttr = new HashMap(); + } + + // get the default names + NamedNodeMap attrs = root.getAttributes(); + String defaultPDP = attrs.getNamedItem("defaultPDP").getNodeValue(); + String defaultAF = getDefaultFactory(attrs, "defaultAttributeFactory"); + String defaultCAF = getDefaultFactory(attrs, + "defaultCombiningAlgFactory"); + String defaultFF = getDefaultFactory(attrs, "defaultFunctionFactory"); + + // loop through all the root-level elements, for each one getting its + // name and then loading the right kind of element + NodeList children = root.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + String childName = child.getNodeName(); + String elementName = null; + + // get the element's name + if (child.getNodeType() == Node.ELEMENT_NODE && + child.getAttributes().getNamedItem("name") != null ) { + elementName = child.getAttributes(). + getNamedItem("name").getNodeValue(); + } + + // see if this is a pdp or a factory, and load accordingly, + // putting the new element into the respective map...make sure + // that we're never loading something with the same name twice + if (childName.equals("pdp")) { + if (logger.isDebugEnabled()) { + logger.debug("Loading PDP: " + elementName); + } + if (this.pdpConfigMap.containsKey(elementName)) { + throw new ParsingException("more that one pdp with " + + "name \"" + elementName +"\""); + } + this.pdpConfigMap.put(elementName, parsePDPConfig(child)); + } else if (childName.equals("attributeFactory")) { + if (logger.isDebugEnabled()) { + logger.debug("Loading AttributeFactory: " + elementName); + } + if (this.attributeMap.containsKey(elementName)) { + throw new ParsingException("more that one " + + "attributeFactory with name " + + elementName +"\""); + } + this.attributeMap.put(elementName, + parseAttributeFactory(child)); + } else if (childName.equals("combiningAlgFactory")) { + if (logger.isDebugEnabled()) { + logger.debug("Loading CombiningAlgFactory: " + + elementName); + } + if (this.combiningMap.containsKey(elementName)) { + throw new ParsingException("more that one " + + "combiningAlgFactory with " + + "name \"" + elementName +"\""); + } + this.combiningMap.put(elementName, + parseCombiningAlgFactory(child)); + } else if (childName.equals("functionFactory")) { + if (logger.isDebugEnabled()) { + logger.debug("Loading FunctionFactory: " + elementName); + } + if (this.functionMap.containsKey(elementName)) { + throw new ParsingException("more that one functionFactory" + + " with name \"" + + elementName +"\""); + } + this.functionMap.put(elementName, parseFunctionFactory(child)); + } else { + //custom attribtue + if ( child.getNodeType() == Node.ELEMENT_NODE ) { + String key = null, value = null; + if ( child.getFirstChild() != null ) { + key = childName; + if ( child.getFirstChild().getNodeType() == Node.TEXT_NODE ) { + value = child.getFirstChild().getNodeValue().trim(); + } + } else { + NamedNodeMap foo = child.getAttributes(); + if (foo != null ) { + key = foo.getNamedItem("key").getNodeValue(); + value = foo.getNamedItem("value").getNodeValue(); + } + } + if ( key != null && value != null ) { + if (logger.isDebugEnabled()) { + logger.debug("Read custom attribute " + key + " with value " + value); + } + customAttr.put(key, value); + } + } + } + } + + // copy custom attributes to PDP configs + if ( customAttr.size() > 0 ) { + for (String pdpKey : this.pdpConfigMap.keySet()) { + pdpConfigMap.get(pdpKey).addCutomAttrs(customAttr); + } + } + + // finally, extract the default elements + this.defaultPDPConfig = (PDPConfig)(this.pdpConfigMap.get(defaultPDP)); + + this.defaultAttributeFactory = (AttributeFactory) + (this.attributeMap.get(defaultAF)); + if (this.defaultAttributeFactory == null) { + try { + this.defaultAttributeFactory = + AttributeFactory.getInstance(defaultAF); + } catch (Exception e) { + throw new ParsingException("Unknown AttributeFactory", e); + } + } + /* start hack: required to include datatypes configured in pdp configuration */ + AttributeFactoryProxy attrProxy = new AttributeFactoryProxy() { + public AttributeFactory getFactory() { + return defaultAttributeFactory; + } + }; + BaseAttributeFactory.setDefaultFactory(attrProxy); + /* end hack */ + + this.defaultCombiningFactory = (CombiningAlgFactory) + (this.combiningMap.get(defaultCAF)); + if (this.defaultCombiningFactory == null) { + try { + this.defaultCombiningFactory = + CombiningAlgFactory.getInstance(defaultCAF); + } catch (Exception e) { + throw new ParsingException("Unknown CombininAlgFactory", e); + } + } + + this.defaultFunctionFactoryProxy = (FunctionFactoryProxy) + (this.functionMap.get(defaultFF)); + if (this.defaultFunctionFactoryProxy == null) { + try { + this.defaultFunctionFactoryProxy = + FunctionFactory.getInstance(defaultFF); + } catch (Exception e) { + throw new ParsingException("Unknown FunctionFactory", e); + } + } + /* start hack: required to include functions configured in pdp configuration */ + BaseFunctionFactory.setDefaultFactory(defaultFunctionFactoryProxy); + /* end hack */ + } + + /** + * Private helper that gets a default factory identifier, or fills in + * the default value if no identifier is provided. + * + * @param attrs The XML-attributes of the configuration. + * @param factoryName The name of the default factory XML-attribute. + * + * @return The identifier of the default factory. + */ + private String getDefaultFactory(NamedNodeMap attrs, String factoryName) { + Node node = attrs.getNamedItem(factoryName); + if (node != null) { + return node.getNodeValue(); + } + return Constants.XACML_1_0_IDENTIFIER; + } + + private Node getRootNode(File configFile) throws ParsingException { + try { + return getRootNode(new FileInputStream(configFile)); + } catch(IOException ioe) { + throw new ParsingException("failed to load the file ", ioe); + } + } + + private Node getRootNode(InputStream configFile) throws ParsingException { + DocumentBuilder db = createDocumentBuilder(); + + Document doc = null; + try { + doc = db.parse(configFile); + } catch (IOException ioe) { + throw new ParsingException("failed to load the file ", ioe); + } catch (SAXException saxe) { + throw new ParsingException("error parsing the XML tree", saxe); + } catch (IllegalArgumentException iae) { + throw new ParsingException("no data to parse", iae); + } + + return getRootNode(doc); + } + + private Node getRootNode(String configuration) throws ParsingException { + DocumentBuilder db = createDocumentBuilder(); + + Document doc = null; + try { + doc = db.parse(new ByteArrayInputStream(configuration.getBytes())); + } catch (IOException ioe) { + throw new ParsingException("failed to load the configuration from string ", ioe); + } catch (SAXException saxe) { + throw new ParsingException("error parsing the XML tree", saxe); + } catch (IllegalArgumentException iae) { + throw new ParsingException("no data to parse", iae); + } + + return getRootNode(doc); + } + + private DocumentBuilder createDocumentBuilder() throws ParsingException { + DocumentBuilderFactory dbFactory = + DocumentBuilderFactory.newInstance(); + + dbFactory.setIgnoringComments(true); + dbFactory.setNamespaceAware(false); + dbFactory.setValidating(false); + + try { + return dbFactory.newDocumentBuilder(); + } catch (ParserConfigurationException pce) { + throw new ParsingException("couldn't get a document builder", pce); + } + } + + /** + * Private helper that parses the file and sets up the DOM tree. + * + * @param configFile The filename of the configuration file. + * + * @return The DOM-tree containing the configuration. + * + * @throws ParsingException + */ + //private Node getRootNode(File configFile) throws ParsingException { + private Node getRootNode(Document doc) throws ParsingException { + // DocumentBuilderFactory dbFactory = + // DocumentBuilderFactory.newInstance(); + // + // dbFactory.setIgnoringComments(true); + // dbFactory.setNamespaceAware(false); + // dbFactory.setValidating(false); + // + // DocumentBuilder db = null; + // try { + // db = dbFactory.newDocumentBuilder(); + // } catch (ParserConfigurationException pce) { + // throw new ParsingException("couldn't get a document builder", pce); + // } + // + // Document doc = null; + // try { + // doc = db.parse(new FileInputStream(configFile)); + // } catch (IOException ioe) { + // throw new ParsingException("failed to load the file ", ioe); + // } catch (SAXException saxe) { + // throw new ParsingException("error parsing the XML tree", saxe); + // } catch (IllegalArgumentException iae) { + // throw new ParsingException("no data to parse", iae); + // } + + Element root = doc.getDocumentElement(); + + if (! root.getTagName().equals("config")) { + throw new ParsingException("unknown document type: " + + root.getTagName()); + } + + return root; + } + + /** + * Private helper that handles the pdp elements. + * + * @param root The node containing the finder module class names. + * + * @return The PDP configuration object. + * + * @throws ParsingException + */ + private PDPConfig parsePDPConfig(Node root) throws ParsingException { + + // ArrayList attrModules = new ArrayList(); + // HashSet policyModules = new HashSet(); + // ArrayList rsrcModules = new ArrayList(); + // ArrayList revocationModules = new ArrayList(); + // + // PDPConfig pdpConfig = new PDPConfig(); + // + // // go through all elements of the pdp, loading the specified modules + // NodeList children = root.getChildNodes(); + // for (int i = 0; i < children.getLength(); i++) { + // Node child = children.item(i); + // String name = child.getNodeName(); + // + // if (name.equals("policyFinderModule")) { + // policyModules.add(loadClass("module", child)); + // } else if (name.equals("attributeFinderModule")) { + // attrModules.add(loadClass("module", child)); + // } else if (name.equals("resourceFinderModule")) { + // rsrcModules.add(loadClass("module", child)); + // } else if (name.equals("revocationFinderModule")) { + // revocationModules.add(loadClass("module", child)); + // } + // } + // + // // after loading the modules, use the collections to setup a + // // PDPConfig based on this pdp element + // + // AttributeFinder attrFinder = new AttributeFinder(); + // attrFinder.setModules(attrModules); + // + // PolicyFinder policyFinder = new PolicyFinder(); + // policyFinder.setModules(policyModules); + // + // ResourceFinder rsrcFinder = new ResourceFinder(); + // rsrcFinder.setModules(rsrcModules); + // + // RevocationFinder revocationFinder = new RevocationFinder(); + // revocationFinder.setModules(revocationModules); + // + // pdpConfig.setFinder(attrFinder, policyFinder, rsrcFinder, + // revocationFinder); + // + // return pdpConfig; + + + ArrayList attrModules = new ArrayList(); + HashSet policyModules = new HashSet(); + ArrayList rsrcModules = new ArrayList(); + ArrayList revocationModules = new ArrayList(); + ArrayList requiredAttrModules = new ArrayList(); + + // go through all elements of the pdp, loading the specified modules + NodeList children = root.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + String name = child.getNodeName(); + + if (name.equals("policyFinderModule")) { + policyModules.add((PolicyFinderModule)loadClass("module", child)); + } else if (name.equals("attributeFinderModule")) { + attrModules.add((AttributeFinderModule)loadClass("module", child)); + } else if (name.equals("resourceFinderModule")) { + rsrcModules.add((ResourceFinderModule)loadClass("module", child)); + } else if (name.equals("revocationFinderModule")) { + revocationModules.add((RevocationFinderModule)loadClass("module", child)); + } else if (name.equals("requiredAttributesModule")) { + requiredAttrModules.add((RequiredAttributesModule) loadClass("module", child)); + } + } + + // after loading the modules, use the collections to setup a + // PDPConfig based on this pdp element + + AttributeFinder attrFinder = new AttributeFinder(); + attrFinder.setModules(attrModules); + + PolicyFinder policyFinder = new PolicyFinder(); + policyFinder.setModules(policyModules); + + ResourceFinder rsrcFinder = new ResourceFinder(); + rsrcFinder.setModules(rsrcModules); + + RevocationFinder revocationFinder = new RevocationFinder(); + revocationFinder.setModules(revocationModules); + + AttributeDesignator.setRequiredAttrModules(requiredAttrModules); + + return new PDPConfig(attrFinder, policyFinder, rsrcFinder, + revocationFinder); + } + + /** + * Private helper that handles the attributeFactory elements. + * + * @param root The node containing the attribute factory definition. + * + * @return The attribute factory object. + * + * @throws ParsingException + */ + private AttributeFactory parseAttributeFactory(Node root) + throws ParsingException + { + AttributeFactory factory = null; + + // check if we're starting with the standard factory setup + if (useStandard(root, "useStandardDatatypes")) { + logger.debug("Starting with standard Datatypes"); + + factory = StandardAttributeFactory.getNewFactory(); + } else { + factory = new BaseAttributeFactory(); + } + + // now look for all datatypes specified for this factory, adding + // them as we go + NodeList children = root.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + + if (child.getNodeName().equals("datatype")) { + // a datatype is a class with an identifier + String identifier = child.getAttributes(). + getNamedItem("identifier").getNodeValue(); + AttributeProxy proxy = + (AttributeProxy)(loadClass("datatype", child)); + + try { + factory.addDatatype(identifier, proxy); + } catch (IllegalArgumentException iae) { + throw new ParsingException("duplicate datatype: " + + identifier, iae); + } + } + } + + return factory; + } + + /** + * Private helper that handles the combiningAlgFactory elements. + */ + private CombiningAlgFactory parseCombiningAlgFactory(Node root) + throws ParsingException + { + CombiningAlgFactory factory = null; + + // check if we're starting with the standard factory setup + if (useStandard(root, "useStandardAlgorithms")) { + logger.debug("Starting with standard Combining Algorithms"); + + factory = StandardCombiningAlgFactory.getNewFactory(); + } else { + factory = new BaseCombiningAlgFactory(); + } + CombiningAlgFactory.setAllFactories(factory); + + + // now look for all algorithms specified for this factory, adding + // them as we go + NodeList children = root.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + + if (child.getNodeName().equals("algorithm")) { + // an algorithm is a simple class element + CombiningAlgorithm alg = + (CombiningAlgorithm)(loadClass("algorithm", child)); + try { + factory.addAlgorithm(alg); + } catch (IllegalArgumentException iae) { + throw new ParsingException("duplicate combining " + + "algorithm: " + + alg.getIdentifier().toString(), + iae); + } + } + } + + return factory; + } + + /** + * Private helper that handles the functionFactory elements. This one + * is a little more complex than the other two factory helper methods, + * since it consists of three factories (target, condition, and general). + */ + private FunctionFactoryProxy parseFunctionFactory(Node root) + throws ParsingException + { + FunctionFactoryProxy proxy = null; + FunctionFactory generalFactory = null; + FunctionFactory conditionFactory = null; + FunctionFactory targetFactory = null; + + // check if we're starting with the standard factory setup, and + // make sure that the proxy is pre-configured + if (useStandard(root, "useStandardFunctions")) { + logger.debug("Starting with standard Functions"); + + proxy = StandardFunctionFactory.getNewFactoryProxy(); + + targetFactory = proxy.getTargetFactory(); + conditionFactory = proxy.getConditionFactory(); + generalFactory = proxy.getGeneralFactory(); + } else { + generalFactory = new BaseFunctionFactory(); + conditionFactory = new BaseFunctionFactory(generalFactory); + targetFactory = new BaseFunctionFactory(conditionFactory); + + proxy = new BasicFunctionFactoryProxy(targetFactory, + conditionFactory, + generalFactory); + } + + // go through and load the three sections, putting the loaded + // functions into the appropriate factory + NodeList children = root.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + String name = child.getNodeName(); + + if (name.equals("target")) { + logger.debug("Loading [TARGET] functions"); + functionParserHelper(child, targetFactory); + } else if (name.equals("condition")) { + logger.debug("Loading [CONDITION] functions"); + functionParserHelper(child, conditionFactory); + } else if (name.equals("general")) { + logger.debug("Loading [GENERAL] functions"); + functionParserHelper(child, generalFactory); + } + } + + return proxy; + } + + /** + * Private helper used by the function factory code to load a specific + * target, condition, or general section. + */ + private void functionParserHelper(Node root, FunctionFactory factory) + throws ParsingException + { + // go through all elements in the section + NodeList children = root.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + String name = child.getNodeName(); + + if (name.equals("function")) { + // a function section is a simple class element + Function function = + (Function)(loadClass("function", child)); + try { + factory.addFunction(function); + } catch (IllegalArgumentException iae) { + throw new ParsingException("duplicate function", iae); + } + } else if (name.equals("abstractFunction")) { + // an abstract function is a class with an identifier + URI identifier = null; + try { + identifier = new URI(child.getAttributes(). + getNamedItem("identifier"). + getNodeValue()); + } catch (URISyntaxException urise) { + throw new ParsingException("invalid function identifier", + urise); + } + + FunctionProxy proxy = + (FunctionProxy)(loadClass("abstract function", child)); + try { + factory.addAbstractFunction(proxy, identifier); + } catch (IllegalArgumentException iae) { + throw new ParsingException("duplicate abstract function", + iae); + } + } else if (name.equals("functionCluster")) { + // a cluster is a class that will give us a collection of + // functions that need to be added one by one into the factory + FunctionCluster cluster = + (FunctionCluster)(loadClass("function cluster", child)); + + Iterator it = cluster.getSupportedFunctions().iterator(); + while (it.hasNext()) { + try { + factory.addFunction(it.next()); + } catch (IllegalArgumentException iae) { + throw new ParsingException("duplicate function", iae); + } + } + } + } + } + + + + /** + * Private helper that is used by all the code to load an instance of + * the given class...this assumes that the class is in the classpath, + * both for simplicity and for stronger security + */ + protected Object loadClass(String prefix, Node root) + throws ParsingException + { + // get the name of the class + String className = + root.getAttributes().getNamedItem("class").getNodeValue(); + + if (logger.isDebugEnabled()) { + logger.debug("Loading [ " + prefix + ": " + className + " ]"); + } + + // load the given class using the local classloader + Class c = null; + try { + c = this.loader.loadClass(className); + } catch (ClassNotFoundException cnfe) { + throw new ParsingException("couldn't load class " + className, + cnfe); + } + Object instance = null; + + // figure out if there are any parameters to the constructor + if (root.hasChildNodes()) { + // parse the arguments to the constructor + List args = null; + try { + args = getArgs(root); + } catch (IllegalArgumentException iae) { + throw new ParsingException("illegal class arguments", iae); + } + int argLength = args.size(); + + // next we need to see if there's a constructor that matches the + // arguments provided...this has to be done by hand since + // Class.getConstructor(Class []) doesn't handle sub-classes and + // generic types (for instance, a constructor taking List won't + // match a parameter list containing ArrayList) + + // get the list of all available constructors + Constructor [] cons = c.getConstructors(); + Constructor constructor = null; + + for (int i = 0; i < cons.length; i++) { + // get the parameters for this constructor + Class [] params = cons[i].getParameterTypes(); + if (params.length == argLength) { + Iterator it = args.iterator(); + int j = 0; + + // loop through the parameters and see if each one is + // assignable from the coresponding input argument + while (it.hasNext()) { + if (! params[j].isAssignableFrom(it.next().getClass())) { + break; + } + j++; + } + + // if we looked at all the parameters, then this + // constructor matches the input + if (j == argLength) { + constructor = cons[i]; + } + } + + // if we've found a matching constructor then stop looping + if (constructor != null) { + break; + } + } + + // make sure we found a matching constructor + if (constructor == null) { + throw new ParsingException("couldn't find a matching " + + "constructor for " + c); + } + + // finally, instantiate the class + try { + instance = constructor.newInstance(args.toArray()); + } catch (InstantiationException ie) { + throw new ParsingException("couldn't instantiate " + className, + ie); + } catch (IllegalAccessException iae) { + throw new ParsingException("couldn't get access to instance " + + "of " + className, iae); + } catch (InvocationTargetException ite) { + throw new ParsingException("couldn't create " + className, + ite); + } + } else { + // we're using a null constructor, so this is easy + try { + instance = c.newInstance(); + } catch (InstantiationException ie) { + throw new ParsingException("couldn't instantiate " + className + + " with empty constructor", ie); + } catch (IllegalAccessException iae) { + throw new ParsingException("couldn't get access to instance " + + "of " + className, iae); + } + } + Method setConfigurationStore = null; + try { + setConfigurationStore = c.getMethod("setConfigurationStore", this.getClass()); + setConfigurationStore.invoke(instance, this); + //logger.debug("set ConfigurationStore to " + c); + } catch ( NoSuchMethodException e) { + logger.debug(c + " does not have a \"setConfigurationStore\" method to retreive the current configuration"); + } catch (Exception e) { + logger.debug("Error at setting the ConfigurationStore to " + c + ": " + e.getClass() + ": " + e.getMessage() + ")"); + e.printStackTrace(); + } + + return instance; + } + + /** + * Private helper that gets the constructor arguments for a given class. + * Right now this just supports String and List, but it's trivial to + * add support for other types should that be needed. Right now, it's not + * clear that there's any need for other types. + */ + private List getArgs(Node root) { + List args = new ArrayList(); + NodeList children = root.getChildNodes(); + + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + String name = child.getNodeName(); + + if (child.getNodeType() == Node.ELEMENT_NODE) { + if (name.equals("string")) { + args.add(child.getFirstChild().getNodeValue()); + } else if (name.equals("list")) { + args.add(getArgs(child)); + } else { + throw new IllegalArgumentException("unkown arg type: " + + name); + } + } + } + return args; + } + + /** + * Private helper used by the three factory routines to see if the + * given factory should be based on the standard setup + */ + private boolean useStandard(Node node, String attributeName) { + NamedNodeMap map = node.getAttributes(); + if (map == null) { + return true; + } + + Node attrNode = map.getNamedItem(attributeName); + if (attrNode == null) { + return true; + } + + return attrNode.getNodeValue().equals("true"); + } + + /** + * Returns the default PDP configuration. If no default was specified + * then this throws an exception. + * + * @return the default PDP configuration + * + * @throws UnknownIdentifierException if there is no default config + */ + public PDPConfig getDefaultPDPConfig() throws UnknownIdentifierException { + if (this.defaultPDPConfig == null) { + throw new UnknownIdentifierException("no default available"); + } + + return this.defaultPDPConfig; + } + + /** + * Returns the PDP configuration with the given name. If no such + * configuration exists then an exception is thrown. + * + * @param name The name of the configuration. + * + * @return the matching PDP configuation + * + * @throws UnknownIdentifierException if the name is unknown + */ + public PDPConfig getPDPConfig(String name) + throws UnknownIdentifierException + { + Object object = this.pdpConfigMap.get(name); + + if (object == null) { + throw new UnknownIdentifierException("unknown pdp: " + name); + } + + return (PDPConfig)object; + } + + /** + * Returns a set of identifiers representing each PDP configuration + * available. + * + * @return a Set of Strings + */ + public Set getSupportedPDPConfigurations() { + return Collections.unmodifiableSet(this.pdpConfigMap.keySet()); + } + + /** + * Returns the default attribute factory. + * + * @return The default attribute factory. + */ + public AttributeFactory getDefaultAttributeFactory() { + return this.defaultAttributeFactory; + } + + /** + * Returns the attribute factory with the given name. If no such + * factory exists then an exception is thrown. + * + * @param name The name of the attribute factory. + * + * @return the matching attribute factory + * + * @throws UnknownIdentifierException if the name is unknown + */ + public AttributeFactory getAttributeFactory(String name) + throws UnknownIdentifierException + { + Object object = this.attributeMap.get(name); + + if (object == null) { + throw new UnknownIdentifierException("unknown factory: " + name); + } + + return (AttributeFactory)object; + } + + /** + * Returns a set of identifiers representing each attribute factory + * available. + * + * @return a Set of Strings + */ + public Set getSupportedAttributeFactories() { + return Collections.unmodifiableSet(this.attributeMap.keySet()); + } + + /** + * Registers all the supported factories with the given identifiers. If + * a given identifier is already in use, then that factory is not + * registered. This method is provided only as a convenience, and + * any registration that may involve identifier clashes should be done + * by registering each factory individually. + */ + public void registerAttributeFactories() { + Iterator it = this.attributeMap.keySet().iterator(); + + while (it.hasNext()) { + String id = it.next(); + AttributeFactory af = this.attributeMap.get(id); + + try { + AttributeFactory.registerFactory(id, new AFProxy(af)); + } catch (IllegalArgumentException iae) { + logger.warn("Couldn't register AttributeFactory:" + + id + " (already in use)", iae); + } + } + } + + /** + * Returns the default combiningAlg factory. + * + * @return the default combiningAlg factory + */ + public CombiningAlgFactory getDefaultCombiningAlgFactory() { + return this.defaultCombiningFactory; + } + + /** + * Returns the combiningAlg factory with the given name. If no such + * factory exists then an exception is thrown. + * + * @param name The name of the combining algorithm factory. + * + * @return the matching combiningAlg factory + * + * @throws UnknownIdentifierException if the name is unknown + */ + public CombiningAlgFactory getCombiningAlgFactory(String name) + throws UnknownIdentifierException + { + Object object = this.combiningMap.get(name); + + if (object == null) { + throw new UnknownIdentifierException("unknown factory: " + name); + } + + return (CombiningAlgFactory)object; + } + + /** + * Returns a set of identifiers representing each combiningAlg factory + * available. + * + * @return a Set of Strings + */ + public SetgetSupportedCombiningAlgFactories() { + return Collections.unmodifiableSet(this.combiningMap.keySet()); + } + + /** + * Registers all the supported factories with the given identifiers. If + * a given identifier is already in use, then that factory is not + * registered. This method is provided only as a convenience, and + * any registration that may involve identifier clashes should be done + * by registering each factory individually. + */ + public void registerCombiningAlgFactories() { + Iterator it = this.combiningMap.keySet().iterator(); + + while (it.hasNext()) { + String id = it.next(); + CombiningAlgFactory cf = this.combiningMap.get(id); + + try { + CombiningAlgFactory.registerFactory(id, new CAFProxy(cf)); + } catch (IllegalArgumentException iae) { + logger.warn("Couldn't register " + + "CombiningAlgFactory: " + id + " (already in use)", + iae); + } + } + } + + /** + * Returns the default function factory proxy. + * + * @return the default function factory proxy + */ + public FunctionFactoryProxy getDefaultFunctionFactoryProxy() { + return this.defaultFunctionFactoryProxy; + } + + /** + * Returns the function factory proxy with the given name. If no such + * proxy exists then an exception is thrown. + * + * @param name The name of the function factory proxy. + * + * @return the matching function factory proxy + * + * @throws UnknownIdentifierException if the name is unknown + */ + public FunctionFactoryProxy getFunctionFactoryProxy(String name) + throws UnknownIdentifierException + { + Object object = this.functionMap.get(name); + + if (object == null) { + throw new UnknownIdentifierException("unknown factory: " + name); + } + + return (FunctionFactoryProxy)object; + } + + /** + * Returns a set of identifiers representing each function factory proxy + * available. + * + * @return a Set of Strings + */ + public Set getSupportedFunctionFactories() { + return Collections.unmodifiableSet(this.functionMap.keySet()); + } + + /** + * Registers all the supported factories with the given identifiers. If + * a given identifier is already in use, then that factory is not + * registered. This method is provided only as a convenience, and + * any registration that may involve identifier clashes should be done + * by registering each factory individually. + */ + public void registerFunctionFactories() { + Iterator it = this.functionMap.keySet().iterator(); + + while (it.hasNext()) { + String id = it.next(); + FunctionFactoryProxy ffp = this.functionMap.get(id); + + try { + FunctionFactory.registerFactory(id, ffp); + } catch (IllegalArgumentException iae) { + logger.warn("Couldn't register FunctionFactory: " + + id + " (already in use)", iae); + } + } + } + + /** + * Uses the default configuration to re-set the default factories used + * by the system (attribute, combining algorithm, and function). If + * a default is not provided for a given factory, then that factory + * will not be set as the system's default. + */ + public void useDefaultFactories() { + logger.debug("Switching to default factories from configuration"); + + // set the default attribute factory, if it exists here + if (this.defaultAttributeFactory != null) { + AttributeFactory.setDefaultFactory( + new AFProxy(this.defaultAttributeFactory)); + } + + // set the default combining algorithm factory, if it exists here + if (this.defaultCombiningFactory != null) { + CombiningAlgFactory.setDefaultFactory( + new CAFProxy(this.defaultCombiningFactory)); + + } + + // set the default function factories, if they exists here + if (this.defaultFunctionFactoryProxy != null) { + FunctionFactory.setDefaultFactory( + this.defaultFunctionFactoryProxy); + } + } + + public String getBaseDir() { + return baseDir; + } + +// public Map getCustumAttrs() { +// return this.customAttr; +// } + + public Object getCustomAttr(String key) { + return this.customAttr.get(key); + } + + /** + * + */ + static class AFProxy implements AttributeFactoryProxy { + private AttributeFactory factory; + + /** + * @param factory + */ + public AFProxy(AttributeFactory factory) { + this.factory = factory; + } + + /** + * @see com.sun.xacml.attr.AttributeFactoryProxy#getFactory() + */ + public AttributeFactory getFactory() { + return this.factory; + } + } + + /** + * + */ + static class CAFProxy implements CombiningAlgFactoryProxy { + private CombiningAlgFactory factory; + + /** + * @param factory + */ + public CAFProxy(CombiningAlgFactory factory) { + this.factory = factory; + } + /** + * @see com.sun.xacml.combine.CombiningAlgFactoryProxy#getFactory() + */ + public CombiningAlgFactory getFactory() { + return this.factory; + } + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Constants.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Constants.java new file mode 100644 index 0000000..ec64dc0 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Constants.java @@ -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"; + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/EvaluationCtx.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/EvaluationCtx.java new file mode 100644 index 0000000..05bf2c8 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/EvaluationCtx.java @@ -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 BasicEvaluationCtx 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 + * Result class. + * @param delegate The delegate in this request (a set containing a + * single RequestElement). + * + * @return An administrative context for this context. + */ + public EvaluationCtx createAdminCtx(int decision, Set 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 int value of the decision according to + * the Result class. + */ + public int getDecision(); + + /** + * Get the delegation depth. + * + * @return The int 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 Set of s with + * the matching category. + */ + public Set getCategory(URI category); + + /** + * @return The Set of RequestElements + * describing the attributes to be included in the result. + */ + public Set getIncludedAttributes(); + + /** + * @return the Map of RequestElements + * defining this request. + */ + public Map> getRequestElements(); + + /** + * Save the parent PolicySet 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 ReductionGraph from the stack. + */ + public void popReductionGraph(); + + /** + * Get the parent PolicySet for this evaluation context. + * + * @return the parent policy set + */ + public AbstractPolicy getParentPolicySet(); + + /** + * Remove the current parent PolicySet 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 Set of URIs of + * inactive policies + * @return the inactive policies + */ + public Set getInactivePolicyIds(); + + /** + * Checks whether a Policy or PolicySet + * 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 Result + * + * @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 MatchResult + * + * @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 EvaluationResult + * + * @param result The result of the finished event. + */ + public void closeCurrentEvent(EvaluationResult result); + + /** + * Signal that an event has finished with a String message. + * + * @param message The message. + */ + public void closeCurrentEvent(String message); + + /** + * Signal that an event has finished with no result. + */ + public void closeCurrentEvent(); + +} + diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Indenter.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Indenter.java new file mode 100644 index 0000000..1457411 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Indenter.java @@ -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 Indenter with the default indent + * width. + */ + public Indenter() { + this(DEFAULT_WIDTH); + } + + /** + * Constructs an Indenter 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 String 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; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/MatchElement.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/MatchElement.java new file mode 100644 index 0000000..3adb2b1 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/MatchElement.java @@ -0,0 +1,11 @@ +package com.sun.xacml; + +import com.sun.xacml.debug.Locatable; + +/** + * + * + */ +public interface MatchElement extends Locatable { + public MatchResult match(EvaluationCtx context); +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/MatchResult.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/MatchResult.java new file mode 100644 index 0000000..cb4e076 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/MatchResult.java @@ -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 MatchResult with no Status + * + * @param result the applicable result + */ + public MatchResult(int result) { + this(result, null); + } + + /** + * Constructor that creates a MatchResult, 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; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Obligation.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Obligation.java new file mode 100644 index 0000000..76c1979 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Obligation.java @@ -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 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 EMPTY_SET = Collections.emptySet(); + + /** + * Constructor that takes all the data associated with an obligation. + * The attribute assignment list contains Attribute 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 List of Attributes + */ + public Obligation(URI id, int fulfillOn, List assignments) { + init(id, fulfillOn, assignments, false); + } + + public Obligation(URI id, int fulfillOn, List assignments, boolean dynamic) { + init(id, fulfillOn, assignments, dynamic); + + } + + private void init(URI id, int fulfillOn, List assignments, boolean dynamic) { + this.id = id; + this.fulfillOn = fulfillOn; + this.dynamic_attributes = dynamic; + this.assignments = Collections. + unmodifiableList(new ArrayList(assignments)); + } + + private Obligation(URI id, int fulfillOn, boolean dynamic) { + this.id = id; + this.fulfillOn = fulfillOn; + this.dynamic_attributes = dynamic; + } + + /** + * Creates an instance of Obligation 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 assignments = new ArrayList(); + + 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 + * List contains objects of type Attribute + * with only the correct attribute fields being used. + * + * @return the assignments + */ + public List getAssignments() { + return this.assignments; + } + + /** + * Encodes this Obligation into its XML form and writes this + * out to the provided OutputStream 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 Obligation into its XML form and writes this + * out to the provided OutputStream 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 + ""); + + indenter.in(); + + Iterator it = this.assignments.iterator(); + + while (it.hasNext()) { + Attribute attr = it.next(); + out.println(indenter.makeString() + + "" + + attr.getValue().encode() + + ""); + } + + indenter.out(); + + out.println(indent + ""); + } + + /** + * @param indenter + * @return the string representation of this obligation encoded in XML + */ + public String toString(Indenter indenter) { + String indent = indenter.makeString(); + + String result =indent + "" + Constants.nl; + + indenter.in(); + + Iterator it = this.assignments.iterator(); + + while (it.hasNext()) { + Attribute attr = it.next(); + result += indenter.makeString() + + "" + + attr.getValue().encode() + + "" + Constants.nl; + } + + indenter.out(); + + result += indent + "" + 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 tmpAttr = new ArrayList(); + 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(); + return obl; + } + } + + public boolean isDynamic() { + return dynamic_attributes; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PDP.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PDP.java new file mode 100644 index 0000000..e93ce07 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PDP.java @@ -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 PDP 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 + * EvaluationCtx. + *

+ * 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 code = new ArrayList(); + 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 EvaluationCtx 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 RequestCtx. 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 EvaluationCtx implementation other + * than BasicEvaluationCtx). + * + * @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 code = new ArrayList(); + 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 results = new HashSet(); + + // at this point, we need to go through all the resources we + // successfully found and start collecting results + Iterator 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 failureMap = resourceResult.getFailures(); + Iterator> it2 = failureMap.entrySet().iterator(); + while (it2.hasNext()) { + Map.Entry 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> elements = context.getRequestElements(); + Iterator iter = elements.keySet().iterator(); + Set> setOfsets = new HashSet>(); + while (iter.hasNext()) { + Set reSet = context.getCategory(iter.next()); + //Do the division + if (setOfsets.isEmpty()) { + //Create initial set of sets + Iterator iter2 = reSet.iterator(); + while (iter2.hasNext()) { + RequestElement re = iter2.next(); + Set newSet = new HashSet(); + newSet.add(re); + setOfsets.add(newSet); + } + } else { + Iterator> iter2 = setOfsets.iterator(); + Set> newSetOfSets = new HashSet>(); + while (iter2.hasNext()) { + Set subset = iter2.next(); + Iterator iter3 = reSet.iterator(); + while(iter3.hasNext()) { + RequestElement re = iter3.next(); + Set newSet = new HashSet(); + newSet.addAll(subset); + newSet.add(re); + newSetOfSets.add(newSet); + } + } + setOfsets = newSetOfSets; + } + } + if (setOfsets.size() < 2) { + ArrayList code = new ArrayList(); + 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 results = new HashSet(); + + // at this point, we need to go through all the sets we + // successfully found and start collecting creating requests + // and collect results + Iterator> it = setOfsets.iterator(); + while (it.hasNext()) { + // get the next set of request elements, and create a + // new request for it. + Set 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 code = new ArrayList(); + 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 evaluate 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 code = new ArrayList(); + 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 AttributeFinder + * (used by subclasses of the PDP). + */ + protected AttributeFinder getAttributeFinder() { + return this.attributeFinder; + } + + /** + * @return The RevocationFinder + * (used by subclasses of the PDP). + */ + protected RevocationFinder getRevocationFinder() { + return this.revocationFinder; + } + + /** + * @return The PolicyFinder + * (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; +// } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PDPConfig.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PDPConfig.java new file mode 100644 index 0000000..ae53fb4 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PDPConfig.java @@ -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 AttributeFinder, + * PolicyFinder, ResourceFinder, and the + * RevocationFinder 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 customAttr = new HashMap(); + + /** + * Constructor that creates a PDPConfig from components. + * + * @param attributeFinder the AttributeFinder that the PDP + * should use, or null if it shouldn't use any + * @param policyFinder the PolicyFinder that the PDP + * should use, or null if it shouldn't use any + * @param resourceFinder the ResourceFinder that the PDP + * should use, or null if it shouldn't use any + * @param revocationFinder The RevocationFinder 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 AttributeFinder that was configured, or + * null if none was configured + * + * @return the AttributeFinder or null + */ + public AttributeFinder getAttributeFinder() { + return this.attributeFinder; + } + + /** + * Returns the PolicyFinder that was configured, or + * null if none was configured + * + * @return the PolicyFinder or null + */ + public PolicyFinder getPolicyFinder() { + return this.policyFinder; + } + + /** + * Returns the ResourceFinder that was configured, or + * null if none was configured + * + * @return the ResourceFinder or null + */ + public ResourceFinder getResourceFinder() { + return this.resourceFinder; + } + + + /** + * Returns the RevocationFinder that was configured, or + * null if none was configured + * + * @return the RevocationFinder or null + */ + public RevocationFinder getRevocationFinder() { + return this.revocationFinder; + } + + public void setCutomAttrs(Map 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 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 getCustomAttrs() { + return customAttr; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ParsingException.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ParsingException.java new file mode 100644 index 0000000..4f6688a --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ParsingException.java @@ -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 ParsingException with no message + * or cause. + */ + public ParsingException() { + //parsing exception with no message or cause. + } + + /** + * Constructs a new ParsingException 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 (null if nonexistent + * or unknown) + */ + public ParsingException(String message) { + super(message); + } + + /** + * Constructs a new ParsingException 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 (null if nonexistent + * or unknown) + */ + public ParsingException(Throwable cause) { + super(cause); + } + + /** + * Constructs a new ParsingException 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 (null if nonexistent + * or unknown) + * @param cause the cause (null if nonexistent + * or unknown) + */ + public ParsingException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Policy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Policy.java new file mode 100644 index 0000000..3de1c27 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Policy.java @@ -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 Set of VariableDefinitions in this policy + */ + private Set definitions; + + /** + * Creates a new Policy with only the required elements. + * + * @param id the policy identifier + * @param combiningAlg the CombiningAlgorithm used on the + * rules in this set + * + * @param target the Target 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 Policy with only the required elements. + * + * @param id the policy identifier + * @param combiningAlg the CombiningAlgorithm used on the + * rules in this set + * @param issuer the PolicyIssuer for this policy or null + * if it is the trusted issuer + * @param target the Target 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 Policy with only the required elements + * plus rules. + * + * @param id the policy identifier + * @param combiningAlg the CombiningAlgorithm used on the + * rules in this set + * @param target the Target for this policy + * @param rules a list of Rule objects + * + * @throws IllegalArgumentException if the List of rules + * contains an object that is not a + * Rule + */ + public Policy(URI id, RuleCombiningAlgorithm combiningAlg, Target target, + List rules) { + this(id, null, null, combiningAlg, null, null, target, null, + rules, null); + } + + /** + * Creates a new Policy with only the required elements + * plus rules. + * + * @param id the policy identifier + * @param combiningAlg the CombiningAlgorithm used on the + * rules in this set + * @param issuer the PolicyIssuer for this policy or null + * if it is the trusted issuer + * @param target the Target for this policy + * @param rules a list of Rule objects + * + * @throws IllegalArgumentException if the List of rules + * contains an object that is not a + * Rule + */ + public Policy(URI id, RuleCombiningAlgorithm combiningAlg, + PolicyIssuer issuer, Target target, List rules) { + this(id, null, null, combiningAlg, null, issuer, target, null, + rules, null); + } + + /** + * Creates a new Policy 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 CombiningAlgorithm used on the + * rules in this set + * @param description a String describing the policy + * @param target the Target for this policy + * @param rules a list of Rule objects + * + * @throws IllegalArgumentException if the List of rules + * contains an object that is not a + * Rule + */ + public Policy(URI id, String version, String xacmlVersion, + RuleCombiningAlgorithm combiningAlg, + String description, Target target, List rules) { + this(id, version, xacmlVersion, combiningAlg, description, null, + target, null, rules, null); + } + + /** + * Creates a new Policy 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 CombiningAlgorithm used on the + * rules in this set + * @param description a String describing the policy + * @param issuer the PolicyIssuer for this policy or null + * if it is the trusted issuer + * @param target the Target for this policy + * @param rules a list of Rule objects + * + * @throws IllegalArgumentException if the List of rules + * contains an object that is not a + * Rule + */ + public Policy(URI id, String version, String xacmlVersion, + RuleCombiningAlgorithm combiningAlg, + String description, PolicyIssuer issuer, Target target, + List rules) { + this(id, version, xacmlVersion, combiningAlg, description, issuer, + target, null, rules, null); + } + + /** + * Creates a new Policy 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 CombiningAlgorithm used on the + * rules in this set + * @param description a String describing the policy + * @param target the Target for this policy + * @param defaultVersion the XPath version to use + * @param rules a list of Rule objects + * + * @throws IllegalArgumentException if the List of rules + * contains an object that is not a + * Rule + */ + public Policy(URI id, String version, String xacmlVersion, + RuleCombiningAlgorithm combiningAlg, + String description, Target target, String defaultVersion, + List rules) { + this(id, version, xacmlVersion, combiningAlg, description, null, + target, defaultVersion, rules, null); + } + + /** + * Creates a new Policy 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 CombiningAlgorithm used on the + * rules in this set + * @param description a String describing the policy + * @param issuer the PolicyIssuer for this policy or null + * if it is the trusted issuer + * @param target the Target for this policy + * @param defaultVersion the XPath version to use + * @param rules a list of Rule objects + * + * @throws IllegalArgumentException if the List of rules + * contains an object that is not a + * Rule + */ + public Policy(URI id, String version, String xacmlVersion, + RuleCombiningAlgorithm combiningAlg, + String description, PolicyIssuer issuer, Target target, + String defaultVersion, List rules) { + this(id, version, xacmlVersion, combiningAlg, description, issuer, + target, defaultVersion, rules, null); + } + + /** + * Creates a new Policy 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 CombiningAlgorithm used on the + * rules in this set + * @param description a String describing the policy + * @param target the Target for this policy + * @param defaultVersion the XPath version to use + * @param rules a list of Rule objects + * @param obligations a set of Obligations objects + * + * @throws IllegalArgumentException if the List of rules + * contains an object that is not a + * Rule + */ + public Policy(URI id, String version, String xacmlVersion, + RuleCombiningAlgorithm combiningAlg, + String description, Target target, String defaultVersion, + List rules, Set obligations) { + this(id, version, xacmlVersion, combiningAlg, description, null, + target, defaultVersion, rules, obligations, null); + } + + /** + * Creates a new Policy 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 CombiningAlgorithm used on the + * rules in this set + * @param description a String describing the policy + * @param issuer the PolicyIssuer for this policy or null + * if it is the trusted issuer + * @param target the Target for this policy + * @param defaultVersion the XPath version to use + * @param rules a list of Rule objects + * @param obligations a set of Obligations objects + * + * @throws IllegalArgumentException if the List of rules + * contains an object that is not a + * Rule + */ + public Policy(URI id, String version, String xacmlVersion, + RuleCombiningAlgorithm combiningAlg, + String description, PolicyIssuer issuer, Target target, + String defaultVersion, List rules, Set obligations) { + this(id, version, xacmlVersion, combiningAlg, description, issuer, + target, defaultVersion, rules, obligations, null); + } + + /** + * Creates a new Policy 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 CombiningAlgorithm used on the + * rules in this set + * @param description a String describing the policy + * @param target the Target for this policy + * @param defaultVersion the XPath version to use + * @param rules a list of Rule objects + * @param obligations a set of Obligations objects + * @param definitions a set of VariableDefinition objects + * that must provide all definitions referenced by + * all VariableReferences in the policy + * + * @throws IllegalArgumentException if the List of rules + * contains an object that is not a + * Rule + */ + public Policy(URI id, String version, String xacmlVersion, + RuleCombiningAlgorithm combiningAlg, + String description, Target target, String defaultVersion, + List rules, Set obligations, Set definitions) { + this(id, version, xacmlVersion, combiningAlg, description, null, target, + defaultVersion, rules, obligations, definitions); + } + + /** + * Creates a new Policy 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 CombiningAlgorithm used on the + * rules in this set + * @param description a String describing the policy + * @param issuer the PolicyIssuer for this policy or null + * if it is the trusted issuer + * @param target the Target for this policy + * @param defaultVersion the XPath version to use + * @param rules a list of Rule objects + * @param obligations a set of Obligations objects + * @param definitions a set of VariableDefinition objects + * that must provide all definitions referenced by + * all VariableReferences in the policy + * + * @throws IllegalArgumentException if the List of rules + * contains an object that is not a + * Rule + */ + public Policy(URI id, String version, String xacmlVersion, + RuleCombiningAlgorithm combiningAlg, + String description, PolicyIssuer issuer, Target target, + String defaultVersion, List rules, Set obligations, + Set definitions) { + super(id, version, xacmlVersion, combiningAlg, description, issuer, + target, defaultVersion, obligations, null, + Constants.MAX_DELEGATION_DEPTH_UNDEFINED); + + List list = null; + + // check that the list contains only rules + if (rules != null) { + list = new ArrayList(); + Iterator 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(definitions)); + } + } + + /** + * Creates a new Policy 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 + * CombinerElements 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 CombiningAlgorithm used on the + * rules in this set + * @param description a String describing the policy or + * null if there is no description + * @param target the Target for this policy + * @param defaultVersion the XPath version to use or null if there is + * no default version + * @param ruleElements a list of RuleCombinerElement objects + * or null if there are no rules + * @param obligations a set of Obligations objects or null + * if there are no obligations + * @param definitions a set of VariableDefinition objects + * that must provide all definitions referenced by + * all VariableReferences in the policy + * @param parameters the List of + * CombinerParameters provided for general + * use by the combining algorithm + * + * @throws IllegalArgumentException if the List of rules + * contains an object that is not a + * RuleCombinerElement + */ + public Policy(URI id, String version, String xacmlVersion, + RuleCombiningAlgorithm combiningAlg, + String description, Target target, String defaultVersion, + List ruleElements, Set obligations, Set definitions, + List parameters) { + this(id, version, xacmlVersion, combiningAlg, description, null, + target, defaultVersion, ruleElements, obligations, + definitions, parameters, + Constants.MAX_DELEGATION_DEPTH_UNDEFINED); + } + + /** + * Creates a new Policy 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 + * CombinerElements 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 CombiningAlgorithm used on the + * rules in this set + * @param description a String 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 Target for this policy + * @param defaultVersion the XPath version to use or null if there is + * no default version + * @param ruleElements a list of RuleCombinerElement objects + * or null if there are no rules + * @param obligations a set of Obligations objects or null + * if there are no obligations + * @param definitions a set of VariableDefinition objects + * that must provide all definitions referenced by + * all VariableReferences in the policy + * @param parameters the List of + * CombinerParameters provided for general + * use by the combining algorithm + * @param maxDelegationDepth the maximum delegation depth authorised + * by this policy set. + * + * @throws IllegalArgumentException if the List of rules + * contains an object that is not a + * RuleCombinerElement + */ + public Policy(URI id, String version, String xacmlVersion, + RuleCombiningAlgorithm combiningAlg, + String description, PolicyIssuer issuer, Target target, + String defaultVersion, List ruleElements, Set obligations, + Set definitions, List 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 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(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 rules = new ArrayList(); + Map> parameters = new HashMap>(); + + Map variableIds = new HashMap(); + 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(); + + // 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 list = parameters.get(ref); + parseParameters(list, child); + } else { + List list = new ArrayList(); + 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 elements = new ArrayList(); + Iterator it = rules.iterator(); + + while (it.hasNext()) { + Rule rule = it.next(); + String id = rule.getId().toString(); + List 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(this.definitions); + clone.setChildren(this.getChildElements()); + return clone; + } + + /** + * Helper method that parses out a collection of combiner parameters. + */ + private void parseParameters(List 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 Policy 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 Set of VariableDefinitions + */ + public Set getVariableDefinitions() { + return this.definitions; + } + + /** + * Encodes this Policy into its XML representation and writes + * this encoding to the given OutputStream 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 Policy into its XML representation and writes + * this encoding to the given OutputStream 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 + ""); + + } else { + out.println(">"); + } + + indenter.in(); + String nextIndent = indenter.makeString(); + + String description = getDescription(); + if (description != null) { + out.println(nextIndent + "" + description + + ""); + } + encodePolicyIssuer(output, charsetName, indenter); + + + String version = getDefaultVersion(); + if (version != null) { + out.println("" + version + + ""); + } + getTarget().encode(output, charsetName, indenter); + + Iterator it = this.definitions.iterator(); + while (it.hasNext()) { + ((VariableDefinition)(it.next())).encode(output, charsetName, + indenter); + } + encodeCommonElements(output, charsetName, indenter); + + indenter.out(); + out.println(indent + ""); + } + + public RuntimeInfo getRuntimeInfo() { + return this.src; + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PolicyMetaData.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PolicyMetaData.java new file mode 100644 index 0000000..33bccec --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PolicyMetaData.java @@ -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 PolicyMetaData instance with all the parameters + * set to their default values. + */ + public PolicyMetaData() { + this(Constants.XACML_DEFAULT_VERSION, + Constants.XPATH_VERSION_UNSPECIFIED); + } + + /** + * Creates a PolicyMetaData 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 PolicyMetaData 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 PolicyMetaData 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 PolicyMetaData 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 AttributeFactory used by the associated + * policy. + * + * @return a AttributeFactory + */ + public AttributeFactory getAttributeFactory() { + return this.afProxy.getFactory(); + } + + /** + * Returns the CombiningAlgFactory used by the associated + * policy. + * + * @return a CombiningAlgFactory + */ + public CombiningAlgFactory getCombiningAlgFactory() { + return this.cafProxy.getFactory(); + } + + /** + * Returns the Target FunctionFactory used by the associated + * policy. + * + * @return a FunctionFactory + */ + public FunctionFactory getTargetFunctionFactory() { + return this.ffProxy.getTargetFactory(); + } + + /** + * Returns the Condition FunctionFactory used by the + * associated policy. + * + * @return a FunctionFactory + */ + public FunctionFactory getConditionFunctionFactory() { + return this.ffProxy.getConditionFactory(); + } + + /** + * Returns the General FunctionFactory used by the associated + * policy. + * + * @return a FunctionFactory + */ + public FunctionFactory getGeneralFunctionFactory() { + return this.ffProxy.getGeneralFactory(); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PolicyReference.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PolicyReference.java new file mode 100644 index 0000000..1dfe97e --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PolicyReference.java @@ -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. + *

+ * NOTE: all of the accessor methods, the match method, and the evaluate method + * require this class to ask its PolicyFinder 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 Policy + */ + public static final int POLICY_REFERENCE = 0; + + /** + * Identifies this as a reference to a PolicySet + */ + 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 PolicyReference 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 PolicyFinder 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 PolicyReference 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 PolicyFinder 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 PolicyReference 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 + * PolicyMetaData 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 PolicyFinder 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 PolicyReference object based on + * a DOM node. + * + * @param root the DOM root of a PolicyIdReference or a + * PolicySetIdReference XML type + * @param finder the PolicyFinder 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 URI + */ + 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 POLICY_REFERENCE + * or POLICYSET_REFERENCE + */ + 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 List of child policy nodes + * + * @throws ProcessingException if the referenced policy can't be retrieved + */ + public List 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 List of CombinerElements + * + * @throws ProcessingException if the referenced policy can't be retrieved + */ + public List 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 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 code = new ArrayList(); + 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 match 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 codes = new Vector(); + 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 PolicyReference into its XML representation + * and writes this encoding to the given OutputStream 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 PolicyReference into its XML representation + * and writes this encoding to the given OutputStream 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 + "" + this.reference.toString() + + ""); + } else { + out.println(encoded + "" + + this.reference.toString() + + ""); + } + } + + /** + * 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; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PolicySet.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PolicySet.java new file mode 100644 index 0000000..6dc41c7 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PolicySet.java @@ -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 PolicySet with only the required elements. + * + * @param id the policy set identifier + * @param combiningAlg the CombiningAlgorithm used on the + * policies in this set + * @param target the Target 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 PolicySet with only the required elements. + * + * @param id the policy set identifier + * @param combiningAlg the CombiningAlgorithm used on the + * policies in this set + * @param issuer the PolicyIssuer for this set or null if + * it is the trusted issuer + * @param target the Target 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 PolicySet with only the required elements, + * plus some policies. + * + * @param id the policy set identifier + * @param combiningAlg the CombiningAlgorithm used on the + * policies in this set + * @param target the Target for this set + * @param policies a list of AbstractPolicy objects + * + * @throws IllegalArgumentException if the List of policies + * contains an object that is not an + * AbstractPolicy + */ + public PolicySet(URI id, PolicyCombiningAlgorithm combiningAlg, + Target target, List policies) { + this(id, null, null, combiningAlg, null, null, target, policies, + null, null); + } + + /** + * Creates a new PolicySet with only the required elements, + * plus some policies. + * + * @param id the policy set identifier + * @param combiningAlg the CombiningAlgorithm used on the + * policies in this set + * @param issuer the PolicyIssuer for this set or null if + * it is the trusted issuer + * @param target the Target for this set + * @param policies a list of AbstractPolicy objects + * + * @throws IllegalArgumentException if the List of policies + * contains an object that is not an + * AbstractPolicy + */ + public PolicySet(URI id, PolicyCombiningAlgorithm combiningAlg, + PolicyIssuer issuer, Target target, List policies) { + this(id, null, null, combiningAlg, null, issuer, target, policies, + null, null); + } + + /** + * Creates a new PolicySet 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 CombiningAlgorithm used on the + * policies in this set + * @param description a String describing the policy + * @param target the Target for this set + * @param policies a list of AbstractPolicy objects + * + * @throws IllegalArgumentException if the List of policies + * contains an object that is not an + * AbstractPolicy + */ + public PolicySet(URI id, String version, String xacmlVersion, + PolicyCombiningAlgorithm combiningAlg, + String description, Target target, List policies) { + this(id, version, xacmlVersion, combiningAlg, description, null, + target, policies, null, null); + } + + /** + * Creates a new PolicySet 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 CombiningAlgorithm used on the + * policies in this set + * @param description a String describing the policy + * @param issuer the PolicyIssuer for this set or null if + * it is the trusted issuer + * @param target the Target for this set + * @param policies a list of AbstractPolicy objects + * + * @throws IllegalArgumentException if the List of policies + * contains an object that is not an + * AbstractPolicy + */ + public PolicySet(URI id, String version, String xacmlVersion, + PolicyCombiningAlgorithm combiningAlg, + String description, PolicyIssuer issuer, Target target, + List policies) { + this(id, version, xacmlVersion, combiningAlg, description, issuer, + target, policies, null, null); + } + + /** + * Creates a new PolicySet 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 CombiningAlgorithm used on the + * policies in this set + * @param description a String describing the policy + * @param target the Target for this set + * @param policies a list of AbstractPolicy objects + * @param defaultVersion the XPath version to use + * + * @throws IllegalArgumentException if the List of policies + * contains an object that is not an + * AbstractPolicy + */ + public PolicySet(URI id, String version, String xacmlVersion, + PolicyCombiningAlgorithm combiningAlg, + String description, Target target, List policies, + String defaultVersion) { + this(id, version, xacmlVersion, combiningAlg, description, null, + target, policies, defaultVersion, null); + } + + /** + * Creates a new PolicySet 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 CombiningAlgorithm used on the + * policies in this set + * @param description a String describing the policy + * @param issuer the PolicyIssuer for this set or null if + * it is the trusted issuer + * @param target the Target for this set + * @param policies a list of AbstractPolicy objects + * @param defaultVersion the XPath version to use + * + * @throws IllegalArgumentException if the List of policies + * contains an object that is not an + * AbstractPolicy + */ + public PolicySet(URI id, String version, String xacmlVersion, + PolicyCombiningAlgorithm combiningAlg, + String description, PolicyIssuer issuer, + Target target, List policies, String defaultVersion) { + this(id, version, xacmlVersion, combiningAlg, description, issuer, + target, policies, defaultVersion, null); + } + + /** + * Creates a new PolicySet 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 CombiningAlgorithm used on the + * policies in this set + * @param description a String describing the policy + * @param target the Target for this set + * @param policies a list of AbstractPolicy objects + * @param defaultVersion the XPath version to use + * @param obligations a set of Obligation objects + * + * @throws IllegalArgumentException if the List of policies + * contains an object that is not an + * AbstractPolicy + */ + public PolicySet(URI id, String version, String xacmlVersion, + PolicyCombiningAlgorithm combiningAlg, + String description, Target target, List policies, + String defaultVersion, Set obligations) { + this(id, version, xacmlVersion, combiningAlg, description, null, + target, policies, defaultVersion, obligations, null, -1); + } + + /** + * Creates a new PolicySet 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 CombiningAlgorithm used on the + * policies in this set + * @param description a String describing the policy + * @param issuer the PolicyIssuer for this set or null if + * it is the trusted issuer + * @param target the Target for this set + * @param policies a list of AbstractPolicy objects + * @param defaultVersion the XPath version to use + * @param obligations a set of Obligation objects + * + * @throws IllegalArgumentException if the List of policies + * contains an object that is not an + * AbstractPolicy + */ + public PolicySet(URI id, String version, String xacmlVersion, + PolicyCombiningAlgorithm combiningAlg, + String description, PolicyIssuer issuer, + Target target, List policies, String defaultVersion, + Set obligations) { + super(id, version, xacmlVersion, combiningAlg, description, issuer, + target, defaultVersion, obligations, null, + Constants.MAX_DELEGATION_DEPTH_UNDEFINED); + + List list = null; + + // check that the list contains only AbstractPolicy objects + if (policies != null) { + list = new ArrayList(); + Iterator 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 PolicySet 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 + * CombinerElements 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 CombiningAlgorithm used on the + * rules in this set + * @param description a String describing the policy or + * null if there is no description + * @param target the Target for this policy + * @param policyElements a list of CombinerElement 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 Obligations objects or null + * if there are no obligations + * @param parameters the List of + * CombinerParameters provided for general + * use by the combining algorithm + * + * @throws IllegalArgumentException if the List of rules + * contains an object that is not a + * Rule + */ + public PolicySet(URI id, String version, String xacmlVersion, + PolicyCombiningAlgorithm combiningAlg, + String description, Target target, + List policyElements, String defaultVersion, + Set obligations, List parameters) { + this(id, version, xacmlVersion, combiningAlg, description, null, target, + policyElements, defaultVersion, obligations, parameters, + Constants.MAX_DELEGATION_DEPTH_UNDEFINED); + } + + /** + * Creates a new PolicySet 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 + * CombinerElements 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 CombiningAlgorithm used on the + * rules in this set + * @param description a String describing the policy or + * null if there is no description + * @param issuer the PolicyIssuer for this set or null if + * it is the trusted issuer + * @param target the Target for this policy + * @param policyElements a list of CombinerElement 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 Obligations objects or null + * if there are no obligations + * @param parameters the List of + * CombinerParameters provided for general + * use by the combining algorithm + * @param maxDelegationDepth the maximum delegation depth authorised + * by this policy set. + * + * @throws IllegalArgumentException if the List of rules + * contains an object that is not a + * Rule + */ + public PolicySet(URI id, String version, String xacmlVersion, + PolicyCombiningAlgorithm combiningAlg, + String description, PolicyIssuer issuer, + Target target, List policyElements, + String defaultVersion, Set obligations, + List 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 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 policies = new ArrayList(); + Map> policyParameters = new HashMap>(); + Map> policySetParameters = new HashMap>(); + 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 elements = new ArrayList(); + + // 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 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> 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 list = parameters.get(ref); + parseParameters(list, root); + } else { + List list = new ArrayList(); + parseParameters(list, root); + parameters.put(ref, list); + } + } + + /** + * Private helper method that handles parsing a single parameter. + */ + private void parseParameters(List 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 PolicySet object based on a + * DOM node. The node must be the root of PolicySetType XML object, + * otherwise an exception is thrown. This PolicySet will + * not support references because it has no PolicyFinder. + * + * @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 PolicySet 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 PolicyFinder 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 PolicySet into its XML representation and + * writes this encoding to the given OutputStream 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 PolicySet into its XML representation and + * writes this encoding to the given OutputStream 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 + ""); + + } else { + out.println(">"); + } + + indenter.in(); + String nextIndent = indenter.makeString(); + + String description = getDescription(); + if (description != null) { + out.println(nextIndent + "" + description + + ""); + } + encodePolicyIssuer(output, charsetName, indenter); + + String version = getDefaultVersion(); + if (version != null) { + out.println("" + version + + ""); + } + getTarget().encode(output, charsetName, indenter); + encodeCommonElements(output, charsetName, indenter); + + indenter.out(); + out.println(indent + ""); + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PolicyTreeElement.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PolicyTreeElement.java new file mode 100644 index 0000000..166e7b1 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/PolicyTreeElement.java @@ -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 EMPTY_LIST = Collections.emptyList(); + + /** + * Returns the List of PolicyTreeElement 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 List + * instead of some unordered collection because in cases like combining + * or evaluation the order is often important. + * + * @return the non-null List of children of this node + */ + public List 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 OutputStream 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 OutputStream 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; + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ProcessingException.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ProcessingException.java new file mode 100644 index 0000000..46462e5 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ProcessingException.java @@ -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 ProcessingException with no message + * or cause. + */ + public ProcessingException() { + //Processing exception with no message or cause + } + + /** + * Constructs a new ProcessingException 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 (null if nonexistent + * or unknown) + */ + public ProcessingException(String message) { + super(message); + } + + /** + * Constructs a new ProcessingException 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 (null if nonexistent + * or unknown) + */ + public ProcessingException(Throwable cause) { + super(cause); + } + + /** + * Constructs a new ProcessingException 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 (null if nonexistent + * or unknown) + * @param cause the cause (null if nonexistent + * or unknown) + */ + public ProcessingException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Rule.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Rule.java new file mode 100644 index 0000000..8336b64 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Rule.java @@ -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 Rule 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 Result + * @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 Rule 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 Result + * @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 Rule object for XACML 1.x only. + * + * @deprecated As of 2.0 you should use the Constructor that accepts + * the new Condition class. + * + * @param id the rule's identifier + * @param effect the effect to return if the rule applies (either + * Pemit or Deny) as specified in Result + * @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 Rule 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 + * PolicyMetaData 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 Rule 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 VariableManager used to connect + * VariableReferences to their cooresponding + * VariableDefinitions + * + * @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 Rule will return from + * the evaluate method (Permit or Deny) if the request applies. + * + * @return a decision effect, as defined in Result + */ + public int getEffect() { + return this.effectAttr; + } + + /** + * Returns the id of this Rule + * + * @return the rule id + */ + public URI getId() { + return this.idAttr; + } + + /** + * Returns the given description of this Rule or null if + * there is no description + * + * @return the description or null + */ + public String getDescription() { + return this.description; + } + + /** + * Returns the target for this Rule 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 List. + * + * @return a List with no elements + */ + public List getChildren() { + return PolicyTreeElement.EMPTY_LIST; + } + + /** + * Returns the condition for this Rule 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 + * Rule's Target. Note that unlike the matching + * done by the evaluate method, if the Target + * 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 code = new ArrayList(); + 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. + *

+ * 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 Rule has no Target 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 Rule into its XML representation and writes + * this encoding to the given OutputStream 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 Rule into its XML representation and writes + * this encoding to the given OutputStream 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 + ""); + + indenter.in(); + String nextIndent = indenter.makeString(); + + if (this.description != null) { + out.println(nextIndent + "" + this.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 + ""); + } else { + // the Rule is empty, so close the tag and we're done + out.println("/>"); + } + } + + public RuntimeInfo getRuntimeInfo() { + return this.src; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Target.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Target.java new file mode 100644 index 0000000..d5ab427 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/Target.java @@ -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. + * + * 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.io.OutputStream; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +//import org.apache.log4j.Logger; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.sun.xacml.PolicyMetaData; +import com.sun.xacml.debug.RuntimeInfo; +import com.sun.xacml.debug.RuntimeInfo.ELEMENT_TYPE; + +/** + * Represents the TargetType XML type in XACML. This also stores several + * other XML types: The matching categories (e.g. Subjects, Resources, + * Actions, Environments, Delegates). The target is used to quickly + * identify whether the parent element (a policy set, policy, or rule) is + * applicable to a given request. + * + * @since 1.0 + * @author Seth Proctor + * @author Ludwig Seitz + */ +public class Target implements Cloneable, MatchElement +{ + + /** + * A List containing TargetSections. + * These represent the disjunctive sections of this target. + */ + private List targetElements; + + /** + * The version of XACML of the policy containing this target + */ + private int xacmlVersion = Constants.XACML_DEFAULT_VERSION; + + + private RuntimeInfo src; + +// /** +// * The logger we'll use for all messages +// */ +// private static final Logger logger = +// Logger.getLogger(Target.class.getName()); + + /** + * Constructor that creates a Target from components. + * + * @param targetSections A List of + * TargetSections can be null. + */ + public Target(List targetSections) { + this(targetSections, Constants.XACML_DEFAULT_VERSION); + } + + /** + * Constructor that creates a Target from components. + * + * @param targetSections A List of + * TargetSections can be null. + * @param xacmlVersion The XACML version (for encoding). + */ + public Target(List targetSections, int xacmlVersion) { + if (targetSections != null) { + this.targetElements = new ArrayList(targetSections); + } else { + this.targetElements = TargetSection.EMPTY_LIST; + } + + this.xacmlVersion = xacmlVersion; + } + + /** + * The clone method constructor + * + * FIXME: this does no deep copy on the Lists and Sets. + * + * @return a copy of this object. + */ + public Object clone() { + try { + Target clone = (Target)super.clone(); + clone.targetElements = new ArrayList(this.targetElements); + clone.xacmlVersion = this.xacmlVersion; + return clone; + } catch (CloneNotSupportedException e) {//this should never happen + throw new RuntimeException("Couldn't clone Target"); + } + } + + + /** + * Creates a Target by parsing a node. + * + * @param root The node to parse for the Target + * @param metaData The policy meta data. + * @return a new Target constructed by parsing + * + * @throws ParsingException if the DOM node is invalid + */ + public static Target getInstance(Node root, PolicyMetaData metaData) + throws ParsingException { + RuntimeInfo src = RuntimeInfo.getRuntimeInfo(root, ELEMENT_TYPE.TARGET); + // first check we really got a Target + if (root.getNodeType() != Node.ELEMENT_NODE) { + throw new ParsingException("Can't create a Target from" + + " a node that is not an element-node" + + (src != null ? src.getLocationMsgForError() : "")); + } + if (!root.getLocalName().equals("Target")) { + throw new ParsingException("Can't create a Target from a " + + root.getLocalName() + " element" + + (src != null ? src.getLocationMsgForError() : "")); + } + List targetElements = new ArrayList(); + + NodeList children = root.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + if (child.getNodeType() == Node.ELEMENT_NODE) { + targetElements.add(TargetSection.getInstance(child, metaData)); + } + } + Target target = new Target(targetElements, metaData.getXACMLVersion()); + if (src != null ) { + target.src = src; + src.setXACMLObject(target); + } + return target; + } + + /** + * Returns the Map of TargetSections for + * this target, keyed by category. + * + * @return the Map of TargetSections. + */ + public List getTargetSections() { + return Collections.unmodifiableList(this.targetElements); + } + + /** + * Returns whether or not this Target matches any request. + * + * @return true if this Target matches any request, false otherwise + */ + //TODO changed function + /*public boolean matchesAny() { + return this.targetElements.isEmpty(); + } */ + + public boolean matchesAny() { + if ( this.targetElements.isEmpty() ) { + return true; + } else { + for ( TargetSection element : targetElements ) { + if ( ! element.matchesAny() ) { + return false; + } + } + return true; + } + } + //TODO changed function + + /** + * Determines whether this Target matches + * the input request (whether it is applicable). + * + * @param context the representation of the request + * + * @return the result of trying to match the target and the request + */ + public MatchResult match(EvaluationCtx context) { + context.newEvent(this); + MatchResult result = null; + + // before matching, see if this target matches any request + if (this.matchesAny()) { + result = new MatchResult(MatchResult.MATCH); + context.closeCurrentEvent(result); + return result; + } + Iterator it = this.targetElements.iterator(); + while (it.hasNext()) { + TargetSection section + = (TargetSection)it.next(); + context.newEvent(section); + result = section.match(context); + context.closeCurrentEvent(result); + if (result.getResult() != MatchResult.MATCH) { +// logger.debug("failed to match a disjunctive section " +// + "of the target"); + context.closeCurrentEvent(result); + return result; + } + + } + + // if we got here, then everything matched + result = new MatchResult(MatchResult.MATCH); + context.closeCurrentEvent(result); + return result; + } + + /** + * Encodes this Target into its XML representation and writes + * this encoding to the given OutputStream 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 Target into its XML representation and writes + * this encoding to the given OutputStream 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(); + indenter.out(); + String indent1 = indenter.makeString(); + indenter.out(); + String indent2 = indenter.makeString(); + indenter.in(); + indenter.in(); + + + if (this.matchesAny()) { + if (this.xacmlVersion > Constants.XACML_VERSION_1_1) { + //since 2.0, if all the sections match any request, then the Target + //element is empty and should be encoded simply as en empty tag + out.println(indent + ""); + } else { + out.println(indent + ""); + out.println(indent1 + ""); + out.println(indent2 + ""); + out.println(indent1 + ""); + out.println(indent1 + ""); + out.println(indent2 + ""); + out.println(indent1 + ""); + out.println(indent1 + ""); + out.println(indent2 + ""); + out.println(indent1 + ""); + out.println(indent + ""); + } + } else { + out.println(indent + ""); + indenter.in(); + + if (this.xacmlVersion < Constants.XACML_VERSION_3_0) { + TargetSection subject = null; + TargetSection resource = null; + TargetSection action = null; + TargetSection environment = null; + //fetch subject, resource and action + for (int i=0; i"); + out.println(indent2 + ""); + out.println(indent1 + ""); + } + if (resource != null) { + resource.encode(output, charsetName, indenter); + } else if (this.xacmlVersion < Constants.XACML_VERSION_2_0) { + out.println(indent1 + ""); + out.println(indent2 + ""); + out.println(indent1 + ""); + } + if (action != null) { + action.encode(output, charsetName, indenter); + } else if (this.xacmlVersion < Constants.XACML_VERSION_2_0) { + out.println(indent1 + ""); + out.println(indent2 + ""); + out.println(indent1 + ""); + } + if (environment != null + && this.xacmlVersion == Constants.XACML_VERSION_2_0) { + environment.encode(output, charsetName, indenter); + } + } else { + Iterator it = this.targetElements.iterator(); + while (it.hasNext()) { + TargetSection section + = (TargetSection)it.next(); + section.encode(output, charsetName, indenter); + } + } + indenter.out(); + out.println(indent + ""); + } + } + + public RuntimeInfo getRuntimeInfo() { + return this.src; + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/TargetMatch.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/TargetMatch.java new file mode 100644 index 0000000..8d4921e --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/TargetMatch.java @@ -0,0 +1,537 @@ + +/* + * @(#)TargetMatch.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.EvaluationCtx; + +import com.sun.xacml.attr.AttributeDesignator; +import com.sun.xacml.attr.AttributeFactory; +import com.sun.xacml.attr.AttributeSelector; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BagAttribute; +import com.sun.xacml.attr.BooleanAttribute; + +import com.sun.xacml.cond.Evaluatable; +import com.sun.xacml.cond.EvaluationResult; +import com.sun.xacml.cond.Expression; +import com.sun.xacml.cond.Function; +import com.sun.xacml.cond.FunctionFactory; +import com.sun.xacml.cond.FunctionTypeException; + +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.net.URISyntaxException; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + + +/** + * Represents the Match XML type in XACML. This is the part of the Target that + * actually evaluates whether the specified attribute values in the Target match + * the corresponding attribute values in the request context. + * + * @since 1.0 + * @author Seth Proctor + * @author Ludwig Seitz + */ +public class TargetMatch implements MatchElement +{ + + /** + * The function used for matching. + */ + private Function function; + + /** + * The AttributeDesignator or + * AttributeSelector to be used to select + * attributes from the request context + */ + private Evaluatable eval; + + /** + * The value to compare against. + */ + private AttributeValue attrValue; + + /** + * The xacml version for encoding. + */ + private int xacmlVersion; + + /** + * The match category. Used only for backwards compatibility. + */ + private URI category; + + private RuntimeInfo src; + + /** + * Constructor that creates a default versionTargetMatch + * from components. + * + * @param function the Function that represents the MatchId + * @param eval the AttributeDesignator or + * AttributeSelector to be used to select + * attributes from the request context + * @param attrValue the AttributeValue to compare against + * + * @throws IllegalArgumentException if the input type isn't a valid value + */ + public TargetMatch(Function function, Evaluatable eval, + AttributeValue attrValue) + throws IllegalArgumentException { + this(function, eval, attrValue, Constants.XACML_DEFAULT_VERSION, + null); + } + + + + /** + * Constructor that creates a TargetMatch from components. + * + * @param function the Function that represents the MatchId + * @param eval the AttributeDesignator or + * AttributeSelector to be used to select + * attributes from the request context + * @param attrValue the AttributeValue to compare against + * @param xacmlVersion The XACML version number. + * @param category The category of this match (e.g. "Subject") for + * XACML versions 2.0 and earlier. Is null for + * later versions. + * + * @throws IllegalArgumentException if the input type isn't a valid value + */ + public TargetMatch(Function function, Evaluatable eval, + AttributeValue attrValue, int xacmlVersion, + URI category) + throws IllegalArgumentException { + + this.function = function; + this.eval = eval; + this.attrValue = attrValue; + this.xacmlVersion = xacmlVersion; + this.category = category; + } + + /** + * Creates a TargetMatch by parsing a node, using the + * input prefix to determine which category of match this is. + * + * @param root The node to parse for the TargetMatch + * @param metaData The policy's meta-data + * @param masterCategory The category of the TargetMatchGroup, for + * checking consistency. + * + * @return a new TargetMatch constructed by parsing + * + * @throws ParsingException if there was an error during parsing + */ + public static TargetMatch getInstance(Node root, + PolicyMetaData metaData, URI masterCategory) + throws ParsingException { + RuntimeInfo src = RuntimeInfo.getRuntimeInfo(root, ELEMENT_TYPE.TARGET_MATCH); + // first make sure the node passed is indeed a TargetMatch + if (root.getNodeType() != Node.ELEMENT_NODE) { + throw new ParsingException("Can't create a TargetMatch from" + + " a node that is not an element-node" + + (src != null ? src.getLocationMsgForError() : "")); + } + if (!root.getLocalName().endsWith("Match")) { + throw new ParsingException("Can't create a TargetMatch from a " + + root.getLocalName() + " element" + + (src != null ? src.getLocationMsgForError() : "")); + } + Function function; + Evaluatable eval = null; + AttributeValue attrValue = null; + + AttributeFactory attrFactory = AttributeFactory.getInstance(); + + // get the function type, making sure that it's really a correct + // Target function + String funcName = null; + if (root.getAttributes().getNamedItem("MatchId") != null) { + funcName = root.getAttributes().getNamedItem("MatchId") + .getNodeValue(); + } else { + throw new ParsingException("Required XML attribute " + + "MatchId not found while parsing a TargetMatch" + + (src != null ? src.getLocationMsgForError() : "")); + } + + FunctionFactory factory = FunctionFactory.getTargetInstance(); + try { + URI funcId = new URI(funcName); + function = factory.createFunction(funcId); + } catch (URISyntaxException use) { + throw new ParsingException("Error parsing TargetMatch" + + (src != null ? src.getLocationMsgForError() : ""), use); + } catch (UnknownIdentifierException uie) { + throw new ParsingException("Unknown MatchId" + + (src != null ? src.getLocationMsgForError() : ""), uie); + } catch (FunctionTypeException fte) { + // try to create an abstract function + try { + URI funcId = new URI(funcName); + function = factory.createAbstractFunction(funcId, root); + } catch (Exception e) { + // any exception here is an error + throw new ParsingException("invalid abstract function" + + (src != null ? src.getLocationMsgForError() : ""), e); + } + } + + // next, get the designator or selector being used, and the attribute + // value paired with it + NodeList nodes = root.getChildNodes(); + for (int i = 0; i < nodes.getLength(); i++) { + Node node = nodes.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE) { + String name = node.getLocalName(); + // endsWith() is compatibility code for XACML 2.0 + if (name.endsWith("AttributeDesignator")) { + if (name.equals("AttributeDesignator")) { + if (metaData.getXACMLVersion() + < Constants.XACML_VERSION_3_0) { + throw new ParsingException( + "Can't create a < XACML 3.0 " + + "AttributeDesignator out of a " + + name + " element" + + (src != null ? src.getLocationMsgForError() : "")); + } + } else { // XACML 2.0 compatibility + if (metaData.getXACMLVersion() + > Constants.XACML_VERSION_2_0) { + throw new ParsingException( + "Can't create a > XACML 2.0 " + + "AttributeDesignator out of a " + + name + " element" + + (src != null ? src.getLocationMsgForError() : "")); + } + String categoryStr + = name.replaceAll("AttributeDesignator", ""); + URI category = null; + if (categoryStr.equals("Subject")) { + category = Constants.SUBJECT_CAT; + } else if (categoryStr.equals("Resource")) { + category = Constants.RESOURCE_CAT; + } else if (categoryStr.equals("Action")) { + category = Constants.ACTION_CAT; + } else if (categoryStr.equals("Environment")){ + category = Constants.ENVIRONMENT_CAT; + } else { + throw new ParsingException("Can't create a " + + "< XACML 3.0 AttributeDesignator out of" + + " a " + categoryStr + " element" + + (src != null ? src.getLocationMsgForError() : "")); + } + + if (!category.equals(masterCategory)) { + throw new ParsingException(categoryStr + "Match" + + " can't be located in enclosing " + + masterCategory.toString() + " element" + + (src != null ? src.getLocationMsgForError() : "")); + } + } + eval = AttributeDesignator.getInstance(node, metaData); + } else if (name.equals("AttributeSelector")) { + eval = AttributeSelector.getInstance(node, metaData); + } else if (name.equals("AttributeValue")) { + try { + attrValue = attrFactory.createValue(node); + } catch (UnknownIdentifierException uie) { + throw new ParsingException( + "Unknown Attribute Type" + + (src != null ? src.getLocationMsgForError() : ""), uie); + } + } else { + throw new ParsingException("Encountered: '" + + name + "' node while parsing a TargetMatch" + + (src != null ? src.getLocationMsgForError() : "")); + } + } + } + + // finally, check that the inputs are valid for this function + List inputs = new ArrayList(); + inputs.add(attrValue); + inputs.add(eval); + function.checkInputsNoBag(inputs, src); + + TargetMatch targetMatch = new TargetMatch(function, eval, attrValue, + metaData.getXACMLVersion(), masterCategory); + if ( src != null ) { + targetMatch.src = src; + src.setXACMLObject(targetMatch); + } + return targetMatch; + } + + /** + * Returns the Function used to do the matching. + * + * @return the match function + */ + public Function getMatchFunction() { + return this.function; + } + + /** + * Returns the AttributeValue used by the matching function. + * + * @return the AttributeValue for the match + */ + public AttributeValue getMatchValue() { + return this.attrValue; + } + + /** + * Returns the AttributeDesignator or + * AttributeSelector used by the matching function. + * + * @return the designator or selector for the match + */ + public Evaluatable getMatchEvaluatable() { + return this.eval; + } + + /** + * Returns the category of this match. + * + * @return the category of this match. + */ + public URI getCategory() { + return this.category; + } + + + public RuntimeInfo getRuntimeInfo() { + return this.src; + } + + /** + * Determines whether this TargetMatch matches + * the input request (whether it is applicable) + * + * @param context the representation of the request + * + * @return the result of trying to match the TargetMatch and the request + */ + public MatchResult match(EvaluationCtx context) { + // start by evaluating the AD/AS + EvaluationResult result = this.eval.evaluate(context); + + if (result.indeterminate()) { + // in this case, we don't ask the function for anything, and we + // simply return INDETERMINATE + return new MatchResult(MatchResult.INDETERMINATE, + result.getStatus()); + } + + // an AD/AS will always return a bag + BagAttribute bag = (BagAttribute)(result.getAttributeValue()); + + if (! bag.isEmpty()) { + // we got back a set of attributes, so we need to iterate through + // them, seeing if at least one matches + Iterator it = bag.iterator(); + boolean atLeastOneError = false; + Status firstIndeterminateStatus = null; + + while (it.hasNext()) { + ArrayList inputs = new ArrayList(); + + inputs.add(this.attrValue); + inputs.add(it.next()); + + // do the evaluation + MatchResult match = evaluateMatch(inputs, context); + + // we only need one match for this whole thing to match + if (match.getResult() == MatchResult.MATCH) { + return match; + } + + // if it was INDETERMINATE, we want to remember for later + if (match.getResult() == MatchResult.INDETERMINATE) { + atLeastOneError = true; + + // there are no rules about exactly what status data + // should be returned here, so like in the combining + // algs, we'll just track the first error + if (firstIndeterminateStatus == null) { + firstIndeterminateStatus = match.getStatus(); + } + } + } + + // if we got here, then nothing matched, so we'll either return + // INDETERMINATE or NO_MATCH + if (atLeastOneError) { + return new MatchResult(MatchResult.INDETERMINATE, + firstIndeterminateStatus); + } + return new MatchResult(MatchResult.NO_MATCH); + + } + // this is just an optimization, since the loop above will + // actually handle this case, but this is just a little + // quicker way to handle an empty bag + return new MatchResult(MatchResult.NO_MATCH); + } + + /** + * Private helper that evaluates an individual match. + */ + private MatchResult evaluateMatch(List inputs, EvaluationCtx context) { + + RuntimeInfo funcSrc = null; + //set (context dependent) source locator for function + if ( src != null ) { + //funcSrc = RuntimeInfo.getIndirectSourceLocator(src, ELEMENT_TYPE.FUNCTION); + funcSrc = src.getIndirectRuntimeInfo(function, ELEMENT_TYPE.FUNCTION); + this.function.setRuntimeInfo(funcSrc); + } + + // first off, evaluate the function + EvaluationResult result = this.function.evaluate(inputs, context); + + //unset source locator + if ( funcSrc != null ) { + this.function.unsetRuntimeInfo(funcSrc) ; + } + + // if it was indeterminate, then that's what we return immediately + if (result.indeterminate()) { + return new MatchResult(MatchResult.INDETERMINATE, + result.getStatus()); + } + + // otherwise, we figure out if it was a match + BooleanAttribute bool = (BooleanAttribute)(result.getAttributeValue()); + + if (bool.getValue()) { + return new MatchResult(MatchResult.MATCH); + } + return new MatchResult(MatchResult.NO_MATCH); + } + + /** + * Encodes this TargetMatch into its XML representation and + * writes this encoding to the given OutputStream 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 TargetMatch into its XML representation and + * writes this encoding to the given OutputStream 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(); + String closingTag = null; + + if (this.xacmlVersion < Constants.XACML_VERSION_3_0) { + if (this.category.equals(Constants.SUBJECT_CAT)) { + out.print(indent + ""); + indenter.in(); + + this.attrValue.encode(output, charsetName, indenter); + this.eval.encode(output, charsetName, indenter); + + indenter.out(); + out.println(indent + closingTag); + } +} \ No newline at end of file diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/TargetMatchGroup.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/TargetMatchGroup.java new file mode 100644 index 0000000..5857e88 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/TargetMatchGroup.java @@ -0,0 +1,330 @@ + +/* + * @(#)TargetMatchGroup.java + * + * Copyright 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 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.Iterator; +import java.util.List; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.sun.xacml.debug.RuntimeInfo; +import com.sun.xacml.debug.RuntimeInfo.ELEMENT_TYPE; + + +/** + * This class contains a group of TargetMatch instances and + * represents the different elements in an XACML Target (e.g. Subject) + * + * @since 2.0 + * @author Seth Proctor + * @author Ludwig Seitz + */ +public class TargetMatchGroup implements MatchElement +{ + + /** + * The list of TargetMatches. + */ + private List matches; + + /** + * The XACML version number. Only used for encoding. + */ + private int xacmlVersion; + + /** + * The category. Only used for encoding XACML versions < 3.0 + */ + private URI category; + + public static final List EMPTY_LIST = Collections.emptyList(); + + private RuntimeInfo src; + + /** + * Constructor that creates a new TargetMatchGroup based + * on the given elements with the default XACML version. + * + * @param matchElements A List of TargetMatch. + * They should all have the same category. + */ + public TargetMatchGroup(List matchElements) { + this(matchElements, Constants.XACML_DEFAULT_VERSION, null); + } + /** + * Constructor that creates a new TargetMatchGroup based + * on the given elements. + * + * @param matchElements A List of TargetMatch. + * They should all have the same category. + * @param xacmlVersion The XACML version number. + * @param category The category if this match group. + * This is null for XACML version > 2.0. + */ + public TargetMatchGroup(List matchElements, int xacmlVersion, + URI category) { + if (matchElements == null) { + this.matches = Collections.unmodifiableList(new ArrayList()); + } else { + this.matches = + Collections.unmodifiableList(new ArrayList(matchElements)); + } + + this.xacmlVersion = xacmlVersion; + this.category = category; + if (this.category == null + && this.xacmlVersion < Constants.XACML_VERSION_3_0) { + throw new IllegalArgumentException("Can't create TargetSections" + + " in XACML version < 3.0 without category"); + } + } + + /** + * Creates a Target based on its DOM node. + * + * @param root The node to parse for the target group. + * @param metaData Meta-data associated with the policy. + * @param masterCategory The category of the TargetSection, for + * checking consistency. + * + * @return a new TargetMatchGroup constructed by parsing + * + * @throws ParsingException if the DOM node is invalid + */ + public static TargetMatchGroup getInstance(Node root, + PolicyMetaData metaData, + URI masterCategory) + throws ParsingException { + RuntimeInfo src = RuntimeInfo.getRuntimeInfo(root, ELEMENT_TYPE.TARGET_MATCH_GROUP ); + if (root.getNodeType() != Node.ELEMENT_NODE) { + throw new ParsingException("Can't create a TargetMatchGroup from" + + " a node that is not an element-node" + + (src != null ? src.getLocationMsgForError() : "")); + } + List matches = new ArrayList(); + NodeList children = root.getChildNodes(); + String categoryStr = root.getLocalName(); + + if (!categoryStr.equals("AllOf")) { //XACML v2.0 or lower + if (metaData.getXACMLVersion() + > Constants.XACML_VERSION_2_0) { + throw new ParsingException("Can't create a > XACML 2.0" + + " TargetMatchGroup form a " + categoryStr + + " element" + + (src != null ? src.getLocationMsgForError() : "")); + } + + URI category = null; + if (categoryStr.equals("Subject")) { + category = Constants.SUBJECT_CAT; + } else if (categoryStr.equals("Resource")) { + category = Constants.RESOURCE_CAT; + } else if (categoryStr.equals("Action")) { + category = Constants.ACTION_CAT; + } else if (categoryStr.equals("Environment")){ + category= Constants.ENVIRONMENT_CAT; + } else { + throw new ParsingException("Can't create a < XACML 3.0" + + " TargetMatchGroup from a " + categoryStr + + " element" + + (src != null ? src.getLocationMsgForError() : "")); + } + + if (!category.equals(masterCategory)) { + throw new ParsingException(categoryStr + " element must" + + " can't be in enclosing " + + masterCategory.toString() + " element" + + (src != null ? src.getLocationMsgForError() : "")); + } + } else if (categoryStr.equals("AllOf") + && (metaData.getXACMLVersion() + < Constants.XACML_VERSION_3_0)) { + throw new ParsingException("Can't create a < XACML 3.0" + + " TargetMatchGroup from a " + categoryStr + + " element" + + (src != null ? src.getLocationMsgForError() : "")); + } + + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + if (child.getNodeType() == Node.ELEMENT_NODE) { + matches.add(TargetMatch.getInstance(child, metaData, + masterCategory)); + } + } + + TargetMatchGroup targetMatchGroup = new TargetMatchGroup(matches, + metaData.getXACMLVersion(), masterCategory); + if ( src != null ) { + targetMatchGroup.src = src; + src.setXACMLObject(targetMatchGroup); + } + return targetMatchGroup; + } + + /** + * Determines whether this TargetMatchGroup matches + * the input request (whether it is applicable). + * + * @param context the representation of the request + * + * @return the result of trying to match the group with the context + */ + public MatchResult match(EvaluationCtx context) { + //TODO changed function + if ( this.matches.size() == 0 ) { + return new MatchResult(MatchResult.MATCH); + } + //TODO changed function + Iterator it = this.matches.iterator(); + MatchResult result = null; + + while (it.hasNext()) { + TargetMatch tm = (TargetMatch)(it.next()); + context.newEvent(tm); + result = tm.match(context); + context.closeCurrentEvent(result); + if (result.getResult() != MatchResult.MATCH) { + break; + } + } + + return result; + } + + /** + * Returns the category of this group. + * + * @return the category of this group. + */ + public URI getCategory() { + return this.category; + } + + /** + * Encodes this TargetMatchGroup into its XML representation + * and writes this encoding to the given OutputStream 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 TargetMatchGroup into its XML representation + * and writes this encoding to the given OutputStream 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(); + Iterator it = this.matches.iterator(); + String closingTag = null; + + if (this.xacmlVersion > Constants.XACML_VERSION_2_0) { + out.println(indent + ""); + closingTag = ""; + } else { // XACML 2.0 and below compatibility code + if (this.category.equals(Constants.SUBJECT_CAT)) { + out.println(indent + ""); + closingTag = ""; + } else if (this.category.equals(Constants.RESOURCE_CAT)) { + out.println(indent + ""); + closingTag = ""; + } else if (this.category.equals(Constants.ACTION_CAT)) { + out.println(indent + ""); + closingTag = ""; + } else if (this.category.equals(Constants.ENVIRONMENT_CAT)) { + out.println(indent + ""); + closingTag = ""; + } + } + + indenter.in(); + + while (it.hasNext()) { + TargetMatch tm = (TargetMatch)(it.next()); + tm.encode(output, charsetName, indenter); + } + out.println(indent + closingTag); + indenter.out(); + } + + /** + * Returns the matches of this match group. + * @return The list of TargetMatches. + */ + public List getMatches() { + return Collections.unmodifiableList(this.matches); + } + public RuntimeInfo getRuntimeInfo() { + return this.src; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/TargetSection.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/TargetSection.java new file mode 100644 index 0000000..f683f5f --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/TargetSection.java @@ -0,0 +1,382 @@ + +/* + * @(#)TargetSection.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.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.Collections; +import java.util.Iterator; +import java.util.List; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + + +/** + * This is a container class for instances of TargetMatchGroup + * and represents the matching categories sections of an XACML Target + * (e.g. Subjects, Resources, Actions, Environments, Delegates). + * This section may apply to any request. + * + * @since 2.0 + * @author Seth Proctor + * @author Ludwig Seitz + */ +public class TargetSection implements MatchElement +{ + + /** + * The list of match groups + */ + private List matchGroups; + + /** + * The XACML version of this target section + * for encoding older XACML versions + */ + private int xacmlVersion; + + /** + * The category of this target section + */ + private URI category; + + public static final List EMPTY_LIST = Collections.emptyList(); + + private RuntimeInfo src; + + /** + * Constructor that takes a group and a version. If the group is + * null or empty, then this represents a section that matches any request. + * + * @param matchGroups A possibly null List of + * TargetMatchGroups. + */ + public TargetSection(List matchGroups) { + this(matchGroups, null, Constants.XACML_DEFAULT_VERSION); + } + + /** + * Constructor that takes a group and a version. If the group is + * null or empty, then this represents a section that matches any request. + * + * @param matchGroups A possibly null List of + * TargetMatchGroups. + * @param category The category of this target section. + * @param xacmlVersion The XACML version of this TargetSection + * (for encoding). + */ + public TargetSection(List matchGroups, URI category, int xacmlVersion) { + if (matchGroups == null) { + this.matchGroups = TargetMatchGroup.EMPTY_LIST; + } else { + this.matchGroups = Collections. + unmodifiableList(new ArrayList(matchGroups)); + } + this.category = category; + this.xacmlVersion = xacmlVersion; + if (this.xacmlVersion < Constants.XACML_VERSION_3_0) { + if (this.category == null) { + throw new IllegalArgumentException("Can't create TargetSections" + + " in XACML version < 3.0 without category"); + } + if (!this.category.toString().startsWith( + "urn:oasis:names:tc:xacml:1.0:subject-category:") + && !this.category.equals(Constants.RESOURCE_CAT) + && !this.category.equals(Constants.ACTION_CAT)) { + if (this.xacmlVersion == Constants.XACML_VERSION_2_0) { + if (!this.category.equals(Constants.ENVIRONMENT_CAT)) { + throw new IllegalArgumentException("Illegal" + + " Category: " + + this.category.toString() + + " for pre XACML 3.0 policy"); + } + } else { + throw new IllegalArgumentException("Illegal" + + " Category: " + + this.category.toString() + + " for pre XACML 3.0 policy"); + } + } + } + } + + /** + * Creates a Target by parsing a node. + * + * @param root The node to parse for the Target. + * @param metaData The meta-data from the enclosing policy. + * + * @return a new Target constructed by parsing + * + * @throws ParsingException if the DOM node is invalid + */ + public static TargetSection getInstance(Node root, PolicyMetaData metaData) + throws ParsingException { + RuntimeInfo src = RuntimeInfo.getRuntimeInfo(root, ELEMENT_TYPE.TARGET_SECTION); + if (root.getNodeType() != Node.ELEMENT_NODE) { + throw new ParsingException("Can't create a TargetSection from" + + " a node that is not an element-node" + + (src != null ? src.getLocationMsgForError() : "")); + } + List groups = new ArrayList(); + NodeList children = root.getChildNodes(); + String categoryStr = null; + URI category = null; + if (metaData.getXACMLVersion() > Constants.XACML_VERSION_2_0) { + if (!root.getLocalName().equals("AnyOf")) { + throw new ParsingException("Found: " + root.getLocalName() + + " tag where expecting AnyOf tag" + + (src != null ? src.getLocationMsgForError() : "")); + } + } else { + //Get node name minus the tailing 's' + categoryStr = root.getLocalName(); + categoryStr = categoryStr.substring(0, categoryStr.length()-1); + + if (categoryStr.equals("Subject")) { + category = Constants.SUBJECT_CAT; + } else if (categoryStr.equals("Resource")) { + category = Constants.RESOURCE_CAT; + } else if (categoryStr.equals("Action")) { + category = Constants.ACTION_CAT; + } else if (metaData.getXACMLVersion() + == Constants.XACML_VERSION_2_0 + && categoryStr.equals("Environment")) { + category = Constants.ENVIRONMENT_CAT; + } else { + throw new ParsingException("Invalid element: " + + root.getLocalName() + + "for XACML version:" + metaData.getXACMLVersion() + + (src != null ? src.getLocationMsgForError() : "")); + } + } + + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + if (child.getNodeType() == Node.ELEMENT_NODE) { + //check for Any* elements as children + if (metaData.getXACMLVersion() < Constants.XACML_VERSION_2_0) { + if (child.getLocalName().startsWith("Any")) { + TargetSection targetSection = new TargetSection(groups, + category, metaData.getXACMLVersion()); + targetSection.src = src; + return targetSection; + } + } + groups.add(TargetMatchGroup.getInstance(child, metaData, + category)); + } + } + + // at this point the list is non-empty (it has specific groups to + // match) or is empty + TargetSection targetSection = new TargetSection(groups, + category, metaData.getXACMLVersion()); + if ( src != null ) { + targetSection.src = src; + src.setXACMLObject(targetSection); + } + return targetSection; + } + + /** + * Returns the TargetMatchGroups contained in this group. + * + * @return a List of TargetMatchGroups + */ + public List getMatchGroups() { + return this.matchGroups; + } + + /** + * Returns whether this section matches any request. + * + * @return true if this section matches any request, false otherwise + */ + public boolean matchesAny() { + return this.matchGroups.isEmpty(); + } + + /** + * Returns the category of this section. + * + * @return the category of this section. + */ + public URI getCategory() { + return this.category; + } + + /** + * Determines whether this TargetSection matches + * the input request (whether it is applicable). + * + * @param context the representation of the request + * + * @return the result of trying to match the target and the request + */ + public MatchResult match(EvaluationCtx context) { + // if we apply to anything, then we always match + if (this.matchGroups.isEmpty()) { + return new MatchResult(MatchResult.MATCH); + } + + // there are specific matching elements, so prepare to iterate + // through the list + Iterator it = this.matchGroups.iterator(); + Status firstIndeterminateStatus = null; + + // in order for this section to match, one of the groups must match + while (it.hasNext()) { + // get the next group and try matching it + TargetMatchGroup group = (TargetMatchGroup)(it.next()); + context.newEvent(group); + MatchResult result = group.match(context); + context.closeCurrentEvent(result); + + // we only need one match, so if this matched, then we're done + if (result.getResult() == MatchResult.MATCH) { + return result; + } + + // if we didn't match then it was either a NO_MATCH or + // INDETERMINATE...in the second case, we need to remember + // it happened, 'cause if we don't get a MATCH, then we'll + // be returning INDETERMINATE + if (result.getResult() == MatchResult.INDETERMINATE) { + if (firstIndeterminateStatus == null) { + firstIndeterminateStatus = result.getStatus(); + } + } + } + + // if we got here, then none of the sub-matches passed, so + // we have to see if we got any INDETERMINATE cases + if (firstIndeterminateStatus == null) { + return new MatchResult(MatchResult.NO_MATCH); + } + return new MatchResult(MatchResult.INDETERMINATE, + firstIndeterminateStatus); + } + + /** + * Encodes this TargetSection into its XML representation + * and writes this encoding to the given OutputStream 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 TargetSection into its XML representation and + * writes this encoding to the given OutputStream 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(); + String closingTag = null; + // figure out if this section applies to any request + if (!this.matchGroups.isEmpty()) { + if (this.xacmlVersion > Constants.XACML_VERSION_2_0) { + // this has specific rules, so we can now encode them + out.println(indent + ""); + closingTag = ""; + + } else { // XACML 2.0 and below compatibility code + if (this.category.equals(Constants.SUBJECT_CAT)) { + out.println(indent + ""); + closingTag = ""; + } else if (this.category.equals(Constants.RESOURCE_CAT)) { + out.println(indent + ""); + closingTag = ""; + } else if (this.category.equals(Constants.ACTION_CAT)) { + out.println(indent + ""); + closingTag = ""; + } else if (this.category.equals(Constants.ENVIRONMENT_CAT)) { + out.println(indent + ""); + closingTag = ""; + } + } + Iterator it = this.matchGroups.iterator(); + indenter.in(); + while (it.hasNext()) { + TargetMatchGroup group = (TargetMatchGroup)(it.next()); + group.encode(output, charsetName, indenter); + } + indenter.out(); + out.println(indent + closingTag); + } + } + + public RuntimeInfo getRuntimeInfo() { + return this.src; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/UnknownIdentifierException.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/UnknownIdentifierException.java new file mode 100644 index 0000000..a8466d0 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/UnknownIdentifierException.java @@ -0,0 +1,71 @@ + +/* + * @(#)UnknownIdentifierException.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 an unknown identifier was used, such as the + * identifier used in any of the standard factories. + * + * @since 1.0 + * @author Seth Proctor + */ +public class UnknownIdentifierException extends Exception +{ + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Creates an UnknownIdentifierException with no data + */ + public UnknownIdentifierException() { + //contains no data + } + + /** + * Creates an UnknownIdentifierException with a message + * + * @param message the message + */ + public UnknownIdentifierException(String message) { + super(message); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/VersionConstraints.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/VersionConstraints.java new file mode 100644 index 0000000..371ae56 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/VersionConstraints.java @@ -0,0 +1,241 @@ + +/* + * @(#)VersionConstraints.java + * + * Copyright 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 java.util.StringTokenizer; + + +/** + * Supports the three version constraints that can be included with a + * policy reference. This class also provides a simple set of comparison + * methods for matching against the constraints. Note that this feature + * was introduced in XACML 2.0, which means that constraints are never + * used in pre-2.0 policy references. + * + * @since 2.0 + * @author Seth Proctor + */ +public class VersionConstraints +{ + + // internal identifiers used to specify the kind of match + private static final int COMPARE_EQUAL = 0; + private static final int COMPARE_LESS = 1; + private static final int COMPARE_GREATER = 2; + + // the three constraint strings + private String version; + private String earliest; + private String latest; + + /** + * Creates a VersionConstraints with the three optional + * constraint strings. Each of the three strings must conform to the + * VersionMatchType type defined in the XACML schema. Any of the + * strings may be null to specify that the given constraint is not + * used. + * + * @param version a matching constraint on the version or null + * @param earliest a lower-bound constraint on the version or null + * @param latest an upper-bound constraint on the version or null + */ + public VersionConstraints(String version, String earliest, String latest) { + this.version = version; + this.earliest = earliest; + this.latest = latest; + } + + /** + * Returns the matching constraint string, which will be null if there + * is no constraint on matching the version. + * + * @return the version constraint + */ + public String getVersionConstraint() { + return this.version; + } + + /** + * Returns the lower-bound constraint string, which will be null if there + * is no lower-bound constraint on the version. + * + * @return the lower-bound constraint + */ + public String getEarliestConstraint() { + return this.earliest; + } + + /** + * Returns the upper-bound constraint string, which will be null if there + * is no upper-bound constraint on the version. + * + * @return the upper-bound constraint + */ + public String getLatestConstraint() { + return this.latest; + } + + /** + * Checks if the given version string meets all three constraints. + * + * @param version the version to compare, which is formatted as a + * VersionType XACML type + * + * @return true if the given version meets all the constraints + */ + public boolean meetsConstraint(String version) { + return (matches(version, this.version) + && isEarlier(version, this.latest) + && isLater(version, this.earliest)); + } + + /** + * Checks if the given version string matches the constraint string. + * + * @param version the version string to check + * @param constraint a constraint string to use in matching + * + * @return true if the version string matches the constraint + */ + public static boolean matches(String version, String constraint) { + return compareHelper(version, constraint, COMPARE_EQUAL); + } + + /** + * Checks if the given version string is less-than or equal-to the + * constraint string. + * + * @param version the version string to check + * @param constraint a constraint string to use in matching + * + * @return true if the version string is earlier than the constraint + */ + public static boolean isEarlier(String version, String constraint) { + return compareHelper(version, constraint, COMPARE_LESS); + } + + /** + * Checks if the given version string is greater-than or equal-to the + * constraint string. + * + * @param version the version string to check + * @param constraint a constraint string to use in matching + * + * @return true if the version string is later than the constraint + */ + public static boolean isLater(String version, String constraint) { + return compareHelper(version, constraint, COMPARE_GREATER); + } + + /** + * Private helper that handles all three comparisons. + */ + private static boolean compareHelper(String version, String constraint, + int type) { + // check that a constraint was provided... + if (constraint == null) { + return true; + } + + // ...and a version too + // FIXME: this originally returned false, but I think it should + // return true, since we always match if the contstraint is + // unbound (null) ... is that right? + if (version == null) { + return true; + } + + // setup tokenizers + StringTokenizer vtok = new StringTokenizer(version, "."); + StringTokenizer ctok = new StringTokenizer(constraint, "."); + + while (vtok.hasMoreTokens()) { + // if there's nothing left in the constraint, then this means + // we didn't match, unless this is the greater-than function + if (! ctok.hasMoreTokens()) { + if (type == COMPARE_GREATER) { + return true; + } + return false; + } + + // get the next constraint token... + String c = ctok.nextToken(); + + // ...and if it's a + then it's done and we match + if (c.equals("+")) { + return true; + } + String v = vtok.nextToken(); + + // if it's a * then we always match, otherwise... + if (! c.equals("*")) { + // if it's a match then we just keep going, otherwise... + if (! v.equals(c)) { + // if we're matching on equality, then we failed + if (type == COMPARE_EQUAL) { + return false; + } + + // convert both tokens to integers... + int cint = Integer.valueOf(c).intValue(); + int vint = Integer.valueOf(v).intValue(); + + // ...and do the right kind of comparison + if (type == COMPARE_LESS) { + return vint <= cint; + } + return vint >= cint; + } + } + } + + // if we got here, then we've finished the processing the version, + // so see if there's anything more in the constrant, which would + // mean we didn't match unless we're doing less-than + if (ctok.hasMoreTokens()) { + if (type == COMPARE_LESS) { + return true; + } + return false; + } + + // we got through everything, so the constraint is met + return true; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/AnyURIAttribute.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/AnyURIAttribute.java new file mode 100644 index 0000000..bfb329d --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/AnyURIAttribute.java @@ -0,0 +1,201 @@ + +/* + * @(#)AnyURIAttribute.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.attr; + +import java.net.URI; +import java.net.URISyntaxException; + +import org.w3c.dom.Node; + +import com.sun.xacml.ParsingException; + + +/** + * Representation of an xs:anyURI value. This class supports parsing + * xs:anyURI values. + * + * @since 1.0 + * @author Seth Proctor + */ +public class AnyURIAttribute extends AttributeValue +{ + + /** + * Official name of this type + */ + public static final String identifier = + TypeIdentifierConstants.ANYURI; + + + //URI version of name for this type + private static URI identifierURI; + + // RuntimeException that wraps an Exception thrown during the + // creation of identifierURI, null if none + private static RuntimeException earlyException; + + /** + * Static initializer that initializes the identifierURI + * class field so that we can catch any exceptions thrown + * by URI(String) and transform them into a RuntimeException. + * Such exceptions should never happen but should be reported + * properly if they ever do. + */ + static { + try { + identifierURI = URI.create(identifier); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + // the URI value that this class represents + private URI value; + + /** + * Creates a new AnyURIAttribute that represents + * the URI value supplied. + * + * @param value the URI value to be represented + */ + public AnyURIAttribute(URI value) { + super(identifierURI); + + // Shouldn't happen, but just in case... + if (earlyException != null) { + throw earlyException; + } + this.value = value; + } + + /** + * Returns a new AnyURIAttribute that represents + * the xs:anyURI at a particular DOM node. + * + * @param root the Node that contains the desired value + * + * @return a new AnyURIAttribute representing the + * appropriate value (null if there is a parsing error) + * + * @throws URISyntaxException + * @throws ParsingException + */ + public static AnyURIAttribute getInstance(Node root) + throws URISyntaxException, ParsingException { + if (root.getFirstChild() != null) { + return getInstance(root.getFirstChild().getNodeValue()); + } + throw new ParsingException("Error while parsing" + + "a AnyURIAttribute"); + } + + /** + * Returns a new AnyURIAttribute that represents + * the xs:anyURI value indicated by the String provided. + * + * @param value a string representing the desired value + * + * @return a new AnyURIAttribute representing the + * appropriate value + * + * @throws URISyntaxException + * @throws ParsingException + */ + public static AnyURIAttribute getInstance(String value) + throws URISyntaxException, ParsingException { + if (value == null) { + throw new ParsingException("Can't create a " + + "AnyURIAttribute from null input"); + } + return new AnyURIAttribute(new URI(value)); + } + + /** + * Returns the URI value represented by this object. + * + * @return the URI value + */ + public URI getValue() { + return this.value; + } + + /** + * Returns true if the input is an instance of this class and if its + * value equals the value contained in this class. + * + * @param o the object to compare + * + * @return true if this object and the input represent the same value + */ + public boolean equals(Object o) { + if (! (o instanceof AnyURIAttribute)) { + return false; + } + AnyURIAttribute other = (AnyURIAttribute)o; + + return this.value.equals(other.value); + } + + /** + * Returns the hashcode value used to index and compare this object with + * others of the same type. Typically this is the hashcode of the backing + * data object. + * + * @return the object's hashcode value + */ + public int hashCode() { + return this.value.hashCode(); + } + + /** + * Converts to a String representation. + * + * @return the String representation + */ + public String toString() { + return "AnyURIAttribute: \"" + this.value.toString() + "\""; + } + + /** + * @return The AttributeValue encoded as a String. + * + */ + public String encode() { + return this.value.toString(); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/AttributeDesignator.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/AttributeDesignator.java new file mode 100644 index 0000000..1c6e5e2 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/AttributeDesignator.java @@ -0,0 +1,552 @@ + +/* + * @(#)AttributeDesignator.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.attr; + +import com.sun.xacml.Constants; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.Indenter; +import com.sun.xacml.ParsingException; +import com.sun.xacml.PolicyMetaData; + +import com.sun.xacml.cond.Evaluatable; +import com.sun.xacml.cond.EvaluationResult; +import com.sun.xacml.cond.Expression; + +import com.sun.xacml.ctx.Attribute; +import com.sun.xacml.ctx.Status; +import com.sun.xacml.ctx.StatusDetail; +import com.sun.xacml.debug.RuntimeInfo; +import com.sun.xacml.debug.RuntimeInfo.ELEMENT_TYPE; +import com.sun.xacml.finder.RequiredAttributesModule; + +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.List; +import java.util.Set; + +import org.apache.log4j.Logger; + +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; + + +/** + * Represents Attribute Designators in XACML. + * + * @since 1.0 + * @author Seth Proctor + * @author Ludwig Seitz + */ +public class AttributeDesignator implements Evaluatable +{ + + /** + * The category of the Designator. + */ + private URI category; + + /** + * The datatype resolved by this designator + */ + private URI type; + + /** + * The attribute id resolved by this designator + */ + private URI id; + + /** + * The optional issuer attribute + */ + private URI issuer; + + /** + * Throw an error if the resolution doesn't find something + */ + private boolean mustBePresent; + + /** + * The XACML version + */ + private int xacmlVersion; + + /** + * Backwards compatibility switch that indicates if the + * SubjectCategory was explicit or default. + */ + private boolean withSubjectCategory = false; + + /** + * Information where the Attribute Designator has been defined in src (files) + */ + private RuntimeInfo src = null; + + /** + * the logger we'll use for all messages + */ + private static final Logger logger = + Logger.getLogger(AttributeDesignator.class.getName()); + + private static ArrayList requiredAttrModules; + + public static void setRequiredAttrModules(ArrayList requiredAttrModules) { + AttributeDesignator.requiredAttrModules = requiredAttrModules; + } + + /** + * Creates a new AttributeDesignator. + * + * @param category the category of this designator + * @param type the data type resolved by this designator + * @param id the attribute id looked for by this designator + * @param mustBePresent whether resolution must find a value + * @param issuer the issuer of the values to search for or null if no + * issuer is specified + * + */ + public AttributeDesignator(URI category, URI type, URI id, + boolean mustBePresent, URI issuer) { + this(category, type, id, mustBePresent, issuer, + Constants.XACML_DEFAULT_VERSION, false); + } + + /** + * Creates a new AttributeDesignator. + * + * @param category the category of this designator + * @param type the data type resolved by this designator + * @param id the attribute id looked for by this designator + * @param mustBePresent whether resolution must find a value + * @param issuer the issuer of the values to search for or null if no + * issuer is specified + * @param xacmlVersion the XACML version that is used. + * @param withSubjectCategory Backwards compatibility switch that + * indicates if the SubjectCategory is + * explicit or default. + * + */ + public AttributeDesignator(URI category, URI type, URI id, + boolean mustBePresent, URI issuer, int xacmlVersion, + boolean withSubjectCategory) { + + this.category = category; + this.type = type; + this.id = id; + this.mustBePresent = mustBePresent; + this.issuer = issuer; + this.xacmlVersion = xacmlVersion; + this.withSubjectCategory = withSubjectCategory; + } + + + + /** + * Creates a new AttributeDesignator based on the DOM + * root of the XML data. + * + * @param root the DOM root of the AttributeDesignatorType XML type + * @param metaData the meta-data associated with the containing policy + * + * @return the designator + * + * @throws ParsingException if the AttributeDesignatorType was invalid + */ + public static AttributeDesignator getInstance(Node root, + PolicyMetaData metaData) throws ParsingException { + URI category = null; + URI type = null; + URI id = null; + URI issuer = null; + boolean mustBePresent = false; + int xacmlVersion = metaData.getXACMLVersion(); + boolean withSubjectCategory = false; + + RuntimeInfo src = RuntimeInfo.getRuntimeInfo(root, ELEMENT_TYPE.ATTRIBUTE_DESIGNATOR); + + NamedNodeMap attrs = root.getAttributes(); + if (root.getNodeType() != Node.ELEMENT_NODE) { + throw new ParsingException("Cannot build a AttributeDesignator" + + " with this node type: " + root.getClass().getName() + + (src != null ? src.getLocationMsgForError() : "")); + } + + if (root.getLocalName().equals("SubjectAttributeDesignator")) { + if (xacmlVersion > Constants.XACML_VERSION_2_0) { + throw new ParsingException("Can't create a > XACML 2.0" + + "AttributeDesignator from " + root.getLocalName() + + (src != null ? src.getLocationMsgForError() : "")); + } + //compatibility code for XACML 2.0 + category = Constants.SUBJECT_CAT; + if (attrs != null) { + Node catNode = attrs.getNamedItem("SubjectCategory"); + if (catNode != null) { + try { + category = new URI(catNode.getNodeValue()); + } catch (URISyntaxException e) { + throw new ParsingException("Error while parsing" + + "category: " + catNode.getNodeValue() + + (src != null ? src.getLocationMsgForError() : "")); + } + withSubjectCategory = true; + } + } + } else if (root.getLocalName().equals("ResourceAttributeDesignator")) { + if (xacmlVersion > Constants.XACML_VERSION_2_0) { + throw new ParsingException("Can't create an > XACML 2.0 " + + "AttributeDesignator from " + root.getLocalName() + + src.getLocationMsgForError()); + } + category = Constants.RESOURCE_CAT; + } else if (root.getLocalName().equals("ActionAttributeDesignator")) { + if (xacmlVersion > Constants.XACML_VERSION_2_0) { + throw new ParsingException("Can't create an > XACML 2.0 " + + "AttributeDesignator from " + root.getLocalName() + + (src != null ? src.getLocationMsgForError() : "")); + } + category = Constants.ACTION_CAT; + } else if (root.getLocalName().equals( + "EnvironmentAttributeDesignator")) { + if (xacmlVersion != Constants.XACML_VERSION_2_0) { + throw new ParsingException("Can't create an XACML 2.0 " + + "AttributeDesignator from " + root.getLocalName() + + src.getLocationMsgForError()); + } + category = Constants.ENVIRONMENT_CAT; + } else { + if (xacmlVersion < Constants.XACML_VERSION_3_0) { + throw new ParsingException("Can't create an XACML " + + xacmlVersion + " AttributeDesignator from " + + root.getLocalName() + + (src != null ? src.getLocationMsgForError() : "")); + } + // there's always a category + try { + category = new URI( + attrs.getNamedItem("Category").getNodeValue()); + } catch (Exception e) { + throw new ParsingException("Required Category missing or" + + " invalid in AttributeDesignator" + + (src != null ? src.getLocationMsgForError() : ""), e); + } + } + try { + // there's always an Id + id = new URI(attrs.getNamedItem("AttributeId").getNodeValue()); + } catch (Exception e) { + throw new ParsingException("Required AttributeId missing or" + + " invalid in AttributeDesignator" + + src.getLocationMsgForError(), e); + } + + try { + // there's always a data type + type = new URI(attrs.getNamedItem("DataType").getNodeValue()); + } catch (Exception e) { + throw new ParsingException("Required DataType missing or" + + " invalid in AttributeDesignator" + + (src != null ? src.getLocationMsgForError() : ""), e); + } + + try { + // there might be an issuer + Node node = attrs.getNamedItem("Issuer"); + if (node != null) { + issuer = new URI(node.getNodeValue()); + } + // there might be a mustBePresent flag + node = attrs.getNamedItem("MustBePresent"); + if (node != null) { + if (node.getNodeValue().equals("true")) { + mustBePresent = true; + } + } + } catch (Exception e) { + // this shouldn't ever happen, but in theory something could go + // wrong in the code in this try block + throw new ParsingException("Error parsing AttributeDesignator " + + "optional attributes" + + (src != null ? src.getLocationMsgForError() : ""), e); + } + + AttributeDesignator attrDesgn = new AttributeDesignator(category, type, + id, mustBePresent, issuer, xacmlVersion, withSubjectCategory); + if ( src != null ) { + attrDesgn.src = src; + src.setXACMLObject(attrDesgn); + } + return attrDesgn; + } + + /** + * Returns the type of attribute that is resolved by this designator. + * While an AD will always return a bag, this method will always return + * the type that is stored in the bag. + * + * @return the attribute type + */ + public URI getType() { + return this.type; + } + + /** + * Returns the AttributeId of the values resolved by this designator. + * + * @return identifier for the values to resolve + */ + public URI getId() { + return this.id; + } + + /** + * Returns the category for this designator. + * + * @return the category + */ + public URI getCategory() { + return this.category; + } + + /** + * Returns the issuer of the values resolved by this designator if + * specified. + * + * @return the attribute issuer or null if unspecified + */ + public URI getIssuer() { + return this.issuer; + } + + /** + * Returns whether or not a value is required to be resolved by this + * designator. + * + * @return true if a value is required, false otherwise + */ + public boolean mustBePresent() { + return this.mustBePresent; + } + + /** + * Always returns true, since a designator always returns a bag of + * attribute values. + * + * @return true + */ + public boolean returnsBag() { + return true; + } + + /** + * Always returns an empty list since designators never have children. + * + * @return an empty List + */ + public List getChildren() { + return Expression.EMPTY_LIST; //Collections.emptyList(); + } + + public RuntimeInfo getRuntimeInfo() { + return this.src; + } + + /** + * Evaluates the pre-assigned meta-data against the given context, + * trying to find some matching values. + * + * @param context the representation of the request + * + * @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 evaluate(EvaluationCtx context) { + context.newEvent(this); + EvaluationResult result = null; + + // look in the right section for some attribute values + result = context.getAttribute(this.category, this.type, this.id, + this.issuer); + + // if the lookup was indeterminate, then we return immediately + if (result.indeterminate()) { + context.closeCurrentEvent(result); + return result; + } + + BagAttribute bag = (BagAttribute)(result.getAttributeValue()); + + if (bag.isEmpty()) { + // if it's empty, this may be an error + if (this.mustBePresent) { + if (logger.isInfoEnabled()) { + logger.info("AttributeDesignator failed to resolve a " + + "value for a required attribute: " + + this.id.toString() + " (MustBePresent: " + + mustBePresent + ")"); + } + + ArrayList code = new ArrayList(); + code.add(Status.STATUS_MISSING_ATTRIBUTE); + + String message = "Couldn't find " + + "AttributeDesignator attribute"; + + // Note that there is a bug in the XACML spec. You can't + // specify an identifier without specifying acceptable + // values. Until this is fixed, this code will only + // return the status code, and not any hints about what + // was missing + Set attr = null; + for ( RequiredAttributesModule requAttrMod : requiredAttrModules ) { + attr = requAttrMod.resolveRequiredAttributes(context, this); + + if ( attr != null && attr.size() > 0 ) { + break; + } + } + + Status status; + if ( attr == null ) { + status = new Status(code, message); + } else { + status = new Status(code, message, new StatusDetail(attr)); + } + + EvaluationResult evalResult = new EvaluationResult(status); + context.closeCurrentEvent(evalResult); + return evalResult; + } + } + + // if we got here the bag wasn't empty, or mustBePresent was false, + // so we just return the result + context.closeCurrentEvent(result); + return result; + } + + /** + * Encodes this designator into its XML representation and + * writes this encoding to the given OutputStream 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 designator into its XML representation and + * writes this encoding to the given OutputStream 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(); + + String tag = ""; + + if (this.xacmlVersion > Constants.XACML_VERSION_2_0) { + tag = " registeredFactories; + + /** + * static intialiazer that sets up the default factory proxy and + * registers the standard namespaces + */ + static { + AttributeFactoryProxy proxy = new AttributeFactoryProxy() { + public AttributeFactory getFactory() { + return StandardAttributeFactory.getFactory(); + } + }; + + registeredFactories = new HashMap(); + registeredFactories.put(Constants.XACML_1_0_IDENTIFIER, proxy); + registeredFactories.put(Constants.XACML_2_0_IDENTIFIER, proxy); + + defaultFactoryProxy = proxy; + } + + /** + * Default constructor. Used only by subclasses. + */ + protected AttributeFactory() { + // used only by subclasses + } + + /** + * Returns the default factory. Depending on the default factory's + * implementation, this may return a singleton instance or new instances + * with each invokation. + * + * @return the default AttributeFactory + */ + public static final AttributeFactory getInstance() { + return defaultFactoryProxy.getFactory(); + } + + /** + * Returns a factory based on the given identifier. You may register + * as many factories as you like, and then retrieve them through this + * interface, but a factory may only be registered once using a given + * identifier. By default, the standard XACML 1.0 and 2.0 identifiers + * are regsietered to provide the standard factory. + * + * @param identifier the identifier for a factory + * + * @return an AttributeFactory + * + * @throws UnknownIdentifierException if the given identifier isn't + * registered + */ + public static final AttributeFactory getInstance(String identifier) + throws UnknownIdentifierException + { + AttributeFactoryProxy proxy = registeredFactories.get(identifier); + + if (proxy == null) { + throw new UnknownIdentifierException("Uknown AttributeFactory " + + "identifier: " + identifier); + } + return proxy.getFactory(); + } + + /** + * Sets the default factory. This does not register the factory proxy as + * an identifiable factory. + * + * @param proxy the AttributeFactoryProxy to set as the new + * default factory proxy + */ + public static final void setDefaultFactory(AttributeFactoryProxy proxy) { + defaultFactoryProxy = proxy; + } + + /** + * Registers the given factory proxy with the given identifier. If the + * identifier is already used, then this throws an exception. If the + * identifier is not already used, then it will always be bound to the + * given proxy. + * + * @param identifier the identifier for the proxy + * @param proxy the AttributeFactoryProxy to register with + * the given identifier + * + * @throws IllegalArgumentException if the identifier is already used + */ + public static final void registerFactory(String identifier, + AttributeFactoryProxy proxy) + throws IllegalArgumentException + { + synchronized (registeredFactories) { + if (registeredFactories.containsKey(identifier)) { + throw new IllegalArgumentException("Identifier is already " + + "registered as " + + "AttributeFactory: " + + identifier); + } + registeredFactories.put(identifier, proxy); + } + } + + /** + * Adds a proxy to the factory, which in turn will allow new attribute + * types to be created using the factory. Typically the proxy is + * provided as an anonymous class that simply calls the getInstance + * methods (or something similar) of some AttributeValue + * class. + * + * @param id the name of the attribute type + * @param proxy the proxy used to create new attributes of the given type + * + * @throws IllegalArgumentException if the given id is already in use + */ + public abstract void addDatatype(String id, AttributeProxy proxy); + + /** + * Adds a proxy to the default factory, which in turn will allow new + * attribute types to be created using the factory. Typically the proxy + * is provided as an anonymous class that simply calls the getInstance + * methods (or something similar) of some AttributeValue + * class. + * + * @deprecated As of version 1.2, replaced by + * {@link #addDatatype(String,AttributeProxy)}. + * The new factory system requires you to get a factory + * instance and then call the non-static methods on that + * factory. The static versions of these methods have been + * left in for now, but are slower and will be removed in + * a future version. Note that this operates only on the + * default factory. + * + * @param id the name of the attribute type + * @param proxy the proxy used to create new attributes of the given type + * + * @throws IllegalArgumentException if the given id is already in use + */ + public static void addAttributeProxy(String id, AttributeProxy proxy) { + getInstance().addDatatype(id, proxy); + } + + /** + * Returns the datatype identifiers supported by this factory. + * + * @return a Set of Strings + */ + public abstract Set getSupportedDatatypes(); + + /** + * Creates a value based on the given DOM root node. The type of the + * attribute is assumed to be present in the node as an XAML attribute + * named DataType, as is the case with the + * AttributeValueType in the policy schema. The value is assumed to be + * the first child of this node. + * + * @param root the DOM root of an attribute value + * + * @return a new AttributeValue + * + * @throws UnknownIdentifierException if the type in the node isn't + * known to the factory + * @throws ParsingException if the node is invalid or can't be parsed + * by the appropriate proxy + */ + public abstract AttributeValue createValue(Node root) + throws UnknownIdentifierException, ParsingException; + + /** + * Creates a value based on the given DOM root node. The type of the + * attribute is assumed to be present in the node as an XAML attribute + * named DataType, as is the case with the + * AttributeValueType in the policy schema. The value is assumed to be + * the first child of this node. This uses the default factory. + * + * @deprecated As of version 1.2, replaced by + * {@link #createValue(Node)}. + * The new factory system requires you to get a factory + * instance and then call the non-static methods on that + * factory. The static versions of these methods have been + * left in for now, but are slower and will be removed in + * a future version. + * + * @param root the DOM root of an attribute value + * + * @return a new AttributeValue + * + * @throws UnknownIdentifierException if the type in the node isn't + * known to the factory + * @throws ParsingException if the node is invalid or can't be parsed + * by the appropriate proxy + */ + public static AttributeValue createAttribute(Node root) + throws UnknownIdentifierException, ParsingException + { + return getInstance().createValue(root); + } + + /** + * Creates a value based on the given DOM root node and data type. + * + * @param root the DOM root of an attribute value + * @param dataType the type of the attribute + * + * @return a new AttributeValue + * + * @throws UnknownIdentifierException if the data type isn't known to + * the factory + * @throws ParsingException if the node is invalid or can't be parsed + * by the appropriate proxy + */ + public abstract AttributeValue createValue(Node root, URI dataType) + throws UnknownIdentifierException, ParsingException; + + /** + * Creates a value based on the given DOM root node and data type. This + * uses the default factory. + * + * @deprecated As of version 1.2, replaced by + * {@link #createValue(Node,URI)}. + * The new factory system requires you to get a factory + * instance and then call the non-static methods on that + * factory. The static versions of these methods have been + * left in for now, but are slower and will be removed in + * a future version. + * + * @param root the DOM root of an attribute value + * @param dataType the type of the attribute + * + * @return a new AttributeValue + * + * @throws UnknownIdentifierException if the data type isn't known to + * the factory + * @throws ParsingException if the node is invalid or can't be parsed + * by the appropriate proxy + */ + public static AttributeValue createAttribute(Node root, URI dataType) + throws UnknownIdentifierException, ParsingException + { + return getInstance().createValue(root, dataType); + } + + /** + * Creates a value based on the given DOM root node and data type. + * + * @param root the DOM root of an attribute value + * @param type the type of the attribute + * + * @return a new AttributeValue + * + * @throws UnknownIdentifierException if the type isn't known to + * the factory + * @throws ParsingException if the node is invalid or can't be parsed + * by the appropriate proxy + */ + public abstract AttributeValue createValue(Node root, String type) + throws UnknownIdentifierException, ParsingException; + + /** + * Creates a value based on the given DOM root node and data type. This + * uses the default factory. + * + * @deprecated As of version 1.2, replaced by + * {@link #createValue(Node,String)}. + * The new factory system requires you to get a factory + * instance and then call the non-static methods on that + * factory. The static versions of these methods have been + * left in for now, but are slower and will be removed in + * a future version. + * + * @param root the DOM root of an attribute value + * @param type the type of the attribute + * + * @return a new AttributeValue + * + * @throws UnknownIdentifierException if the type isn't known to + * the factory + * @throws ParsingException if the node is invalid or can't be parsed + * by the appropriate proxy + */ + public static AttributeValue createAttribute(Node root, String type) + throws UnknownIdentifierException, ParsingException + { + return getInstance().createValue(root, type); + } + + /** + * Creates a value based on the given data type and text-encoded value. + * Used primarily by code that does an XPath query to get an + * attribute value, and then needs to turn the resulting value into + * an Attribute class. + * + * @param dataType the type of the attribute + * @param value the text-encoded representation of an attribute's value + * + * @return a new AttributeValue + * + * @throws UnknownIdentifierException if the data type isn't known to + * the factory + * @throws ParsingException if the text is invalid or can't be parsed + * by the appropriate proxy + */ + public abstract AttributeValue createValue(URI dataType, String value) + throws UnknownIdentifierException, ParsingException; + + /** + * Creates a value based on the given data type and text-encoded value. + * Used primarily by code that does an XPath query to get an + * attribute value, and then needs to turn the resulting value into + * an Attribute class. This uses the default factory. + * + * @deprecated As of version 1.2, replaced by + * {@link #createValue(URI,String)}. + * The new factory system requires you to get a factory + * instance and then call the non-static methods on that + * factory. The static versions of these methods have been + * left in for now, but are slower and will be removed in + * a future version. + * + * @param dataType the type of the attribute + * @param value the text-encoded representation of an attribute's value + * + * @return a new AttributeValue + * + * @throws UnknownIdentifierException if the data type isn't known to + * the factory + * @throws ParsingException if the text is invalid or can't be parsed + * by the appropriate proxy + */ + public static AttributeValue createAttribute(URI dataType, String value) + throws UnknownIdentifierException, ParsingException + { + return getInstance().createValue(dataType, value); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/AttributeFactoryProxy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/AttributeFactoryProxy.java new file mode 100644 index 0000000..9c355ef --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/AttributeFactoryProxy.java @@ -0,0 +1,58 @@ + +/* + * @(#)AttributeFactoryProxy.java + * + * Copyright 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.attr; + + +/** + * A simple proxy interface used to install new + * AttributeFactorys. + * + * @since 1.2 + * @author Seth Proctor + */ +public interface AttributeFactoryProxy +{ + + /** + * Returns an instance of the AttributeFactory for which + * this is a proxy. + * + * @return an AttributeFactory instance + */ + public AttributeFactory getFactory(); + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/AttributeProxy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/AttributeProxy.java new file mode 100644 index 0000000..4e231f6 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/AttributeProxy.java @@ -0,0 +1,80 @@ + +/* + * @(#)AttributeProxy.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.attr; + +import org.w3c.dom.Node; + + +/** + * Used by the AttributeFactory to create new attributes. + * Typically a new proxy class is created which in turn knows how to create + * a specific kind of attribute, and then this proxy class is installed in + * the AttributeFactory. + * + * @since 1.0 + * @author Seth Proctor + */ +public interface AttributeProxy +{ + + /** + * Tries to create a new AttributeValue based on the given + * DOM root node. + * + * @param root the DOM root of some attribute data + * + * @return an AttributeValue representing the given data + * + * @throws Exception if the data couldn't be used (the exception is + * typically wrapping some other exception) + */ + public AttributeValue getInstance(Node root) throws Exception; + + /** + * Tries to create a new AttributeValue based on the given + * String data. + * + * @param value the text form of some attribute data + * + * @return an AttributeValue representing the given data + * + * @throws Exception if the data couldn't be used (the exception is + * typically wrapping some other exception) + */ + public AttributeValue getInstance(String value) throws Exception; + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/AttributeSelector.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/AttributeSelector.java new file mode 100644 index 0000000..fde8e12 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/AttributeSelector.java @@ -0,0 +1,421 @@ + +/* + * @(#)AttributeSelector.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.attr; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.Indenter; +import com.sun.xacml.ParsingException; +import com.sun.xacml.PolicyMetaData; + +import com.sun.xacml.cond.Evaluatable; +import com.sun.xacml.cond.EvaluationResult; +import com.sun.xacml.cond.Expression; + +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.apache.log4j.Logger; + +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; + + +/** + * Supports the standard selector functionality in XACML, which uses XPath + * expressions to resolve values from the Request or elsewhere. All selector + * queries are done by AttributeFinderModules so that it's easy + * to plugin different XPath implementations. + * + * @since 1.0 + * @author Seth Proctor + */ +public class AttributeSelector implements Evaluatable +{ + + // the data type returned by this selector + private URI type; + + // the XPath to search + private String contextPath; + + // must resolution find something + private boolean mustBePresent; + + // the xpath version we've been told to use + private String xpathVersion; + + // the policy root, where we get namespace mapping details + private Node policyRoot; + + private RuntimeInfo src; + + // the logger we'll use for all messages + private static final Logger logger = + Logger.getLogger(AttributeSelector.class.getName()); + + /** + * Creates a new AttributeSelector with no policy root. + * + * @param type the data type of the attribute values this selector + * looks for + * @param contextPath the XPath to query + * @param mustBePresent must resolution find a match + * @param xpathVersion the XPath version to use, which must be a valid + * XPath version string (the identifier for XPath 1.0 + * is provided in PolicyMetaData) + */ + public AttributeSelector(URI type, String contextPath, + boolean mustBePresent, String xpathVersion) { + this(type, contextPath, null, mustBePresent, xpathVersion); + } + + /** + * Creates a new AttributeSelector. + * + * @param type the data type of the attribute values this selector + * looks for + * @param contextPath the XPath to query + * @param policyRoot the root DOM Element for the policy containing this + * selector, which defines namespace mappings + * @param mustBePresent must resolution find a match + * @param xpathVersion the XPath version to use, which must be a valid + * XPath version string (the identifier for XPath 1.0 + * is provided in PolicyMetaData) + */ + public AttributeSelector(URI type, String contextPath, Node policyRoot, + boolean mustBePresent, String xpathVersion) { + this.type = type; + this.contextPath = contextPath; + this.mustBePresent = mustBePresent; + this.xpathVersion = xpathVersion; + this.policyRoot = policyRoot; + } + + /** + * Creates a new AttributeSelector based on the DOM root + * of the XML type. Note that as of XACML 1.1 the XPathVersion element + * is required in any policy that uses a selector, so if the + * xpathVersion string is null, then this will throw + * an exception. + * + * @param root the root of the DOM tree for the XML AttributeSelectorType + * XML type + * @param metaData the meta-data associated with the containing policy + * + * @return an AttributeSelector + * + * @throws ParsingException if the AttributeSelectorType was invalid + */ + public static AttributeSelector getInstance(Node root, + PolicyMetaData metaData) + throws ParsingException { + RuntimeInfo src = RuntimeInfo.getRuntimeInfo(root, ELEMENT_TYPE.ATTRIBUTE_SELECTOR); + if (root.getNodeType() != Node.ELEMENT_NODE || + !root.getLocalName().equals("AttributeSelector")) { + throw new ParsingException("Can't create an AttributeSelector" + + " from a " + root.getLocalName() + " element" + + (src != null ? src.getLocationMsgForError() : "")); + } + URI type = null; + String contextPath = null; + boolean mustBePresent = false; + String xpathVersion = metaData.getXPathIdentifier(); + + // make sure we were given an xpath version + if (xpathVersion == null) { + throw new ParsingException("An XPathVersion is required for "+ + "any policies that use selectors" + + (src != null ? src.getLocationMsgForError() : "")); + } + NamedNodeMap attrs = root.getAttributes(); + + try { + // there's always a DataType attribute + type = new URI(attrs.getNamedItem("DataType").getNodeValue()); + } catch (Exception e) { + throw new ParsingException("Error parsing required DataType " + + "attribute in AttributeSelector" + + (src != null ? src.getLocationMsgForError() : ""), e); + } + + try { + // there's always a RequestPath + contextPath = + attrs.getNamedItem("RequestContextPath").getNodeValue(); + } catch (Exception e) { + throw new ParsingException("Error parsing required " + + "RequestContextPath attribute in AttributeSelector" + + (src != null ? src.getLocationMsgForError() : ""), e); + } + + try { + // there may optionally be a MustBePresent + Node node = attrs.getNamedItem("MustBePresent"); + if (node != null) + if (node.getNodeValue().equals("true")) { + mustBePresent = true; + } + } catch (Exception e) { + // this shouldn't happen, since we check the cases, but still... + throw new ParsingException("Error parsing optional attributes " + + "in AttributeSelector" + + (src != null ? src.getLocationMsgForError() : ""), e); + } + + // as of 1.2 we need the root element of the policy so we can get + // the namespace mapping, but in order to leave the APIs unchanged, + // we'll walk up the tree to find the root rather than pass this + // element around through all the code + Node policyRoot = null; + Node node = root.getParentNode(); + + while ((node != null) && (node.getNodeType() == Node.ELEMENT_NODE)) { + policyRoot = node; + node = node.getParentNode(); + } + + // create the new selector + AttributeSelector attrSelector = new AttributeSelector(type, + contextPath, policyRoot, mustBePresent, xpathVersion); + if ( src != null ) { + attrSelector.src = src; + src.setXACMLObject(attrSelector); + } + return attrSelector; + } + + /** + * Returns the data type of the attribute values that this selector + * will resolve + * + * @return the data type of the values found by this selector + */ + public URI getType() { + return this.type; + } + + /** + * Returns the XPath query used to resolve attribute values. + * + * @return the XPath query + */ + public String getContextPath() { + return this.contextPath; + } + + /** + * Returns whether or not a value is required to be resolved by this + * selector. + * + * @return true if a value is required, false otherwise + */ + public boolean mustBePresent() { + return this.mustBePresent; + } + + /** + * Always returns true, since a selector always returns a bag of + * attribute values. + * + * @return true + */ + public boolean returnsBag() { + return true; + } + + /** + * Always returns an empty list since selectors never have children. + * + * @return an empty List + */ + public List getChildren() { + return Expression.EMPTY_LIST; + } + + /** + * Returns the XPath version this selector is supposed to use. This is + * typically provided by the defaults section of the policy containing + * this selector. + * + * @return the XPath version + */ + public String getXPathVersion() { + return this.xpathVersion; + } + + /** + * Returns the policy root node, from where we get namespace + * mapping details. + * + * @return a Node object + */ + public Node getPolicyRoot() { + return this.policyRoot; + } + + public RuntimeInfo getRuntimeInfo() { + return src; + } + + + /** + * Invokes the AttributeFinder used by the given + * EvaluationCtx to try to resolve an attribute value. If + * the selector is defined with MustBePresent as true, then failure + * to find a matching value will result in Indeterminate, otherwise it + * will result in an empty bag. To support the basic selector + * functionality defined in the XACML specification, use a finder that + * has only the SelectorModule as a module that supports + * selector finding. + * + * @param context representation of the request to search + * + * @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 evaluate(EvaluationCtx context) { + context.newEvent(this); + // query the context + EvaluationResult result = context.getAttribute(this.contextPath, + this.policyRoot, + this.type, + this.xpathVersion); + + // see if we got anything + if (! result.indeterminate()) { + BagAttribute bag = (BagAttribute)(result.getAttributeValue()); + + // see if it's an empty bag + if (bag.isEmpty()) { + // see if this is an error or not + if (this.mustBePresent) { + // this is an error +// if (logger.isLoggable(Level.INFO)) { + logger.info("AttributeSelector failed to resolve a " + + "value for a required attribute: " + + this.contextPath); +// } + ArrayList code = new ArrayList(); + code.add(Status.STATUS_MISSING_ATTRIBUTE); + String message = "couldn't resolve XPath expression " + + this.contextPath + " for type " + this.type.toString(); + EvaluationResult evaluationResult + = new EvaluationResult(new Status(code, message)); + context.closeCurrentEvent(evaluationResult); + return evaluationResult; + } + // return the empty bag + context.closeCurrentEvent(); + return result; + } + // return the values + context.closeCurrentEvent(result); + return result; + } + // return the error + context.closeCurrentEvent(result); + return result; + } + + /** + * Encodes this selector into its XML representation and + * writes this encoding to the given OutputStream 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 selector into its XML representation and + * writes this encoding to the given OutputStream 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(); + + String tag = "AttributeValues. If you want to + * provide a new type, extend this class and implement the + * equals(Object) and hashCode methods from + * Object, which are used for equality checking. + * + * @since 1.0 + * @author Seth Proctor + */ +public abstract class AttributeValue implements Evaluatable +{ + + // the type of this attribute + private URI type; + + private RuntimeInfo src; + + /** + * Constructor that takes the specific attribute type. + * + * @param type the attribute's type + */ + protected AttributeValue(URI type) { + this.type = type; + } + + /** + * Returns the type of this attribute value. By default this always + * returns the type passed to the constructor. + * + * @return the attribute's type + */ + public URI getType() { + return this.type; + } + + /** + * Returns whether or not this value is actually a bag of values. This + * is a required interface from Expression, but the + * more meaningful isBag method is used by + * AttributeValues, so this method is declared as final + * and calls the isBag method for this value. + * + * @return true if this is a bag of values, false otherwise + */ + public final boolean returnsBag() { + return isBag(); + } + + /** + * Returns whether or not this value is actually a bag of values. This + * is a required interface from Evaluatable, but the + * more meaningful isBag method is used by + * AttributeValues, so this method is declared as final + * and calls the isBag method for this value. + * + * + * @deprecated As of 2.0, you should use the returnsBag + * method from the super-interface Expression. + * + * @return true if this is a bag of values, false otherwise + */ + public final boolean evaluatesToBag() { + return isBag(); + } + + /** + * Always returns an empty list since values never have children. + * + * @return an empty List + */ + public List getChildren() { + return Expression.EMPTY_LIST; + } + + /** + * Returns whether or not this value is actually a bag of values. By + * default this returns false. Typically, only the + * BagAttribute should ever override this to return + * true. + * + * @return true if this is a bag of values, false otherwise + */ + public boolean isBag() { + return false; + } + + /** + * Implements the required interface from Evaluatable. + * Since there is nothing to evaluate in an attribute value, the default + * result is just this instance. Override this method if you want + * special behavior, like a dynamic value. + * + * @param context the representation of the request + * + * @return a successful evaluation containing this value + */ + public EvaluationResult evaluate(EvaluationCtx context) { + return new EvaluationResult(this); + } + + /** + * Encodes the value in a form suitable for including in XML data like + * a request or an obligation. This must return a value that could in + * turn be used by the factory to create a new instance with the same + * value. + * + * @return a String form of the value + */ + public abstract String encode(); + + /** + * Encodes this AttributeValue into its XML representation + * and writes this encoding to the given OutputStream with + * no indentation. This will always produce the version used in a + * policy rather than that used in a request, so this is equivalent + * to calling encodeWithTags(true) and then stuffing that + * into a stream. + * + * @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 AttributeValue into its XML representation + * and writes this encoding to the given OutputStream with + * indentation. This will always produce the version used in a + * policy rather than that used in a request, so this is equivalent + * to calling encodeWithTags(true) and then stuffing that + * into a stream. + * + * @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); + } + out.println(indenter.makeString() + encodeWithTags(true)); + } + + /** + * Encodes the value and includes the AttributeValue XML tags so that + * the resulting string can be included in a valid XACML policy or + * Request/Response. The boolean parameter lets you include + * the DataType attribute, which is required in a policy but not allowed + * in a Request or Response. + * + * @param includeType include the DataType XML attribute if + * true, exclude if false + * + * @return a String encoding including the XML tags + */ + public String encodeWithTags(boolean includeType) { + if (includeType) { + return "" + + encode() + ""; + } + return "" + encode() + ""; + } + + /** + * defines if this attribute is dynamic, i.e., if it has to be evaluated at runtime + * @return + */ + public boolean isDynamic() { + return false; + } + + public RuntimeInfo getRuntimeInfo() { + return this.src; + } + + public void setSrcLocFromFactory(RuntimeInfo src) { + this.src = src; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/BagAttribute.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/BagAttribute.java new file mode 100644 index 0000000..d840bfa --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/BagAttribute.java @@ -0,0 +1,265 @@ + +/* + * @(#)BagAttribute.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.attr; + +import java.net.URI; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.NoSuchElementException; + + +/** + * Represents a bag used in the XACML spec as return values from functions + * and designators/selectors that provide more than one value. All values in + * the bag are of the same type, and the bag may be empty. The bag is + * immutable, although its contents may not be. + *

+ * NOTE: This is the one standard attribute type that can't be created from + * the factory, since you can't have this in an XML block (it is used only + * in return values & dynamic inputs). I think this is right, but we may need + * to add some functionality to let this go into the factory. + * + * @since 1.0 + * @author Seth Proctor + * @author Steve Hanna + */ +public class BagAttribute extends AttributeValue +{ + + // The Collection of AttributeValues that this object encapsulates + private Collection bag; + + /** + * Creates a new BagAttribute that represents + * the Collection of AttributeValues supplied. + * If the set is null or empty, then the new bag is empty. + * + * @param type the data type of all the attributes in the set + * @param bag a Collection of AttributeValues + */ + public BagAttribute(URI type, Collection bag) { + super(type); + + if (type == null) { + throw new IllegalArgumentException("Bags require a non-null " + + "type be provided"); + } + + // see if the bag is empty/null + if ((bag == null) || (bag.size() == 0)) { + // empty bag + this.bag = new ArrayList(); + } else { + // go through the collection to make sure it's a valid bag + Iterator it = bag.iterator(); + + while (it.hasNext()) { + AttributeValue attr = it.next(); + + // a bag cannot contain other bags, so make sure that each + // value isn't actually another bag + if (attr.isBag()) { + throw new IllegalArgumentException("bags cannot contain " + + "other bags"); + } + + // make sure that they're all the same type + if (! type.equals(attr.getType())) { + throw new + IllegalArgumentException("Bag items must all be of " + + "the same type"); + } + } + + // if we get here, then they're all the same type + this.bag = bag; + } + } + + /** + * Overrides the default method to always return true. + * + * @return a value of true + */ + public boolean isBag() { + return true; + } + + /** + * Convenience function that returns a bag with no elements + * + * @param type the types contained in the bag + * + * @return a new empty bag + */ + public static BagAttribute createEmptyBag(URI type) { + return new BagAttribute(type, null); + } + + /** + * A convenience function that returns whether or not the bag is empty + * (ie, whether or not the size of the bag is zero) + * + * @return whether or not the bag is empty + */ + public boolean isEmpty() { + return (this.bag.size() == 0); + } + + /** + * Returns the number of elements in this bag + * + * @return the number of elements in this bag + */ + public int size() { + return this.bag.size(); + } + + /** + * Returns true if this set contains the specified value. More formally, + * returns true if and only if this bag contains a value v such that + * (value==null ? v==null : value.equals(v)). Note that this will only + * work correctly if the AttributeValue has overridden the + * equals method. + * + * @param value the value to look for + * + * @return true if the value is in the bag + */ + public boolean contains(AttributeValue value) { + return this.bag.contains(value); + } + + /** + * Returns true if this bag contains all of the values of the specified bag. + * Note that this will only work correctly if the + * AttributeValue type contained in the bag has overridden + * the equals method. + * + * @param bag the bag to compare + * + * @return true if the input is a subset of this bag + */ + public boolean containsAll(BagAttribute bag) { + return this.bag.containsAll(bag.bag); + } + + + /** + * Returns an iterator over the bag. + * + * @return The iterator. + */ + public Iterator iterator() { + return new ImmutableIterator(this.bag.iterator()); + } + + + /** + * Returns an iterator over the bag. + * + * @return The iterator. + */ + public Iterable iterable() { + return this.bag; + } + + + + /** + * This is a version of Iterator that overrides the remove + * method so that items can't be taken out of the bag. + */ + private static class ImmutableIterator implements Iterator { + + // the iterator we're wrapping + private Iterator iterator; + + /** + * Create a new ImmutableIterator + * + * @param iterator The iterator that shall be made immutable. + */ + public ImmutableIterator(Iterator iterator) { + this.iterator = iterator; + } + + /** + * Standard hasNext method + * + * @return true of this iterator has a next element, false otherwise. + */ + public boolean hasNext() { + return this.iterator.hasNext(); + } + + /** + * Standard next method + * + * @return The next Object pointed to by the iterator. + * + * @throws NoSuchElementException + */ + public AttributeValue next() throws NoSuchElementException { + return this.iterator.next(); + } + + /** + * Makes sure that no one can remove any elements from the bag + * + * @throws UnsupportedOperationException + */ + public void remove() throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + } + + /** + * Because a bag cannot be included in a request/response or a + * policy, this will always throw an + * UnsupportedOperationException. + * + * @return The String that would encode this bag. + */ + public String encode() { + throw new UnsupportedOperationException("Bags cannot be encoded"); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/Base64.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/Base64.java new file mode 100644 index 0000000..51eb3be --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/Base64.java @@ -0,0 +1,379 @@ + +/* + * @(#)Base64.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.attr; + +import java.io.IOException; +import java.io.ByteArrayOutputStream; + + + +/** + * Class that knows how to encode and decode Base64 values. Base64 + * Content-Transfer-Encoding rules are defined in Section 6.8 of IETF RFC 2045 + * Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet + * Message Bodies, available at + * ftp://ftp.isi.edu/in-notes/rfc2045.txt. + *

+ * All methods of this class are static and thread-safe. + * + * @since 1.0 + * @author Anne Anderson + */ +class Base64 +{ + /* + * ASCII white-space characters. These are the ones recognized by the + * C and Java language [pre-processors]. + */ + private static final char SPACE = 0x20; /* space, or blank, character */ + private static final char ETX = 0x04; /* end-of-text character */ + private static final char VTAB = 0x0b; /* vertical tab character */ + private static final char FF = 0x0c; /* form-feed character */ + private static final char HTAB = 0x09; /* horizontal tab character */ + private static final char LF = 0x0a; /* line feed character */ + private static final char ALTLF = 0x13; /* line feed on some systems */ + private static final char CR = 0x0d; /* carriage-return character */ + + + /* + * String used for BASE64 encoding and decoding. + * + * For index values 0-63, the character at each index is the Base-64 + * encoded value of the index value. Index values beyond 63 are never + * referenced during encoding, but are used in this implementation to + * help in decoding. The character at index 64 is the Base64 pad + * character '='. + * + * Charaters in index positions 0-64 MUST NOT be moved or altered, as + * this will break the implementation. + * + * The characters after index 64 are white space characters that should be + * ignored in Base64-encoded input strings while doing decoding. Note that + * the white-space character set should include values used on various + * platforms, since a Base64-encoded value may have been generated on a + * non-Java platform. The values included here are those used in Java and + * in C. + * + * The white-space character set may be modified without affecting the + * implementation of the encoding algorithm. + */ + private static final String BASE64EncodingString = + "ABCDEFGHIJ" + + "KLMNOPQRST" + + "UVWXYZabcd" + + "efghijklmn" + + "opqrstuvwx" + + "yz01234567" + + "89+/" + + "=" + + SPACE + ETX + VTAB + FF + HTAB + LF + ALTLF + CR; + + // Index of pad character in Base64EncodingString + private static final int PAD_INDEX = 64; + + /* + * The character in Base64EncodingString with the maximum + * character value in Unicode. + */ + private static final int MAX_BASE64_CHAR = 'z'; + + /* + * Array for mapping encoded characters to decoded values. + * This array is initialized when needed by calling + * initDecodeArray(). Only includes entries up to + * MAX_BASE64_CHAR. + */ + private static int [] Base64DecodeArray = null; + + /* + * State values used for decoding a quantum of four encoded input + * characters as follows. + * + * Initial state: NO_CHARS_DECODED + * NO_CHARS_DECODED: no characters have been decoded + * on encoded char: decode char into output quantum; + * new state: ONE_CHAR_DECODED + * otherwise: Exception + * ONE_CHAR_DECODED: one character has been decoded + * on encoded char: decode char into output quantum; + * new state: TWO_CHARS_DECODED + * otherwise: Exception + * TWO_CHARS_DECODED: two characters have been decoded + * on encoded char: decode char into output quantum; + * new state: THREE_CHARS_DECODED + * on pad: write quantum byte 0 to output; + * new state: PAD_THREE_READ + * THREE_CHARS_DECODED: three characters have been decoded + * on encoded char: decode char into output quantum; + * write quantum bytes 0-2 to output; + * new state: NO_CHARS_DECODED + * on pad: write quantum bytes 0-1 to output; + * new state: PAD_FOUR_READ + * PAD_THREE_READ: pad character has been read as 3rd of 4 chars + * on pad: new state: PAD_FOUR_READ + * otherwise: Exception + * PAD_FOUR_READ: pad character has been read as 4th of 4 char + * on any char: Exception + * + * The valid terminal states are NO_CHARS_DECODED and PAD_FOUR_READ. + */ + private static final int NO_CHARS_DECODED = 0; + private static final int ONE_CHAR_DECODED = 1; + private static final int TWO_CHARS_DECODED = 2; + private static final int THREE_CHARS_DECODED = 3; + private static final int PAD_THREE_READ = 5; + private static final int PAD_FOUR_READ = 6; + + /** + * The maximum number of groups that should be encoded + * onto a single line (so we don't exceed 76 characters + * per line). + */ + private static final int MAX_GROUPS_PER_LINE = 76/4; + + /** + * Encodes the input byte array into a Base64-encoded + * String. The output String + * has a CR LF (0x0d 0x0a) after every 76 bytes, but + * not at the end. + *

+ * WARNING: If the input byte array is modified + * while encoding is in progress, the output is undefined. + * + * @param binaryValue the byte array to be encoded + * + * @return the Base64-encoded String + */ + public static String encode(byte[] binaryValue) { + + int binaryValueLen = binaryValue.length; + // Estimated output length (about 1.4x input, due to CRLF) + int maxChars = (binaryValueLen * 7) / 5; + // Buffer for encoded output + StringBuffer sb = new StringBuffer(maxChars); + + int groupsToEOL = MAX_GROUPS_PER_LINE; + // Convert groups of 3 input bytes, with pad if < 3 in final + for (int binaryValueNdx = 0; binaryValueNdx < binaryValueLen; + binaryValueNdx += 3) { + + // Encode 1st 6-bit group + int group1 = (binaryValue[binaryValueNdx] >> 2) & 0x3F; + sb.append(BASE64EncodingString.charAt(group1)); + + // Encode 2nd 6-bit group + int group2 = (binaryValue[binaryValueNdx] << 4) & 0x030; + if ((binaryValueNdx+1) < binaryValueLen) { + group2 = group2 + | ((binaryValue[binaryValueNdx+1] >> 4) & 0xF); + } + sb.append(BASE64EncodingString.charAt(group2)); + + // Encode 3rd 6-bit group + int group3; + if ((binaryValueNdx+1) < binaryValueLen) { + group3 = (binaryValue[binaryValueNdx+1] << 2) & 0x03C; + if ((binaryValueNdx+2) < binaryValueLen) { + group3 = group3 + | ((binaryValue[binaryValueNdx+2] >> 6) & 0x3); + } + } else { + group3 = PAD_INDEX; + } + sb.append(BASE64EncodingString.charAt(group3)); + + // Encode 4th 6-bit group + int group4; + if ((binaryValueNdx+2) < binaryValueLen) { + group4 = binaryValue[binaryValueNdx+2] & 0x3F; + } else { + group4 = PAD_INDEX; + } + sb.append(BASE64EncodingString.charAt(group4)); + + // After every MAX_GROUPS_PER_LINE groups, insert CR LF. + // Unless this is the final line, in which case we skip that. + groupsToEOL = groupsToEOL - 1; + if (groupsToEOL == 0) { + groupsToEOL = MAX_GROUPS_PER_LINE; + if ((binaryValueNdx+3) <= binaryValueLen) { + sb.append(CR); + sb.append(LF); + } + } + } + return sb.toString(); + } + + /** + * Initializes Base64DecodeArray, if this hasn't already been + * done. + */ + private static synchronized void initDecodeArray() { + if (Base64DecodeArray != null) { + return; + } + + int [] ourArray = new int [MAX_BASE64_CHAR+1]; + for (int i = 0; i <= MAX_BASE64_CHAR; i++) { + ourArray[i] = BASE64EncodingString.indexOf(i); + } + Base64DecodeArray = ourArray; + } + + /** + * Decodes a Base64-encoded String. The result + * is returned in a byte array that should match the original + * binary value (before encoding). Whitespace characters + * in the input String are ignored. + *

+ * If the ignoreBadChars parameter is + * true, characters that are not allowed + * in a BASE64-encoded string are ignored. Otherwise, + * they cause an IOException to be raised. + * + * @param encoded a String containing a + * Base64-encoded value + * @param ignoreBadChars If true, bad characters + * are ignored. Otherwise, they cause + * an IOException to be + * raised. + * + * @return a byte array containing the decoded value + * + * @throws IOException if the input String is not + * a valid Base64-encoded value + */ + public static byte[] decode(String encoded, boolean ignoreBadChars) + throws IOException + { + int encodedLen = encoded.length(); + int maxBytes = (encodedLen/4)*3; /* Maximum possible output bytes */ + ByteArrayOutputStream ba = /* Buffer for decoded output */ + new ByteArrayOutputStream(maxBytes); + byte[] quantum = new byte[3]; /* one output quantum */ + + // ensure Base64DecodeArray is initialized + initDecodeArray(); + + /* + * Every 4 encoded characters in input are converted to 3 bytes of + * output. This is called one "quantum". Each encoded character is + * mapped to one 6-bit unit of the output. Whitespace characters in + * the input are passed over; they are not included in the output. + */ + + int state = NO_CHARS_DECODED; + for (int encodedNdx = 0; encodedNdx < encodedLen; encodedNdx++) { + // Turn encoded char into decoded value + int encodedChar = encoded.charAt(encodedNdx); + int decodedChar; + if (encodedChar > MAX_BASE64_CHAR) { + decodedChar = -1; + } else { + decodedChar = Base64DecodeArray[encodedChar]; + } + + // Handle white space and invalid characters + if (decodedChar == -1) { + if (ignoreBadChars) { + continue; + } + throw new IOException("Invalid character"); + } + if (decodedChar > PAD_INDEX) { /* whitespace */ + continue; + } + + // Handle valid characters + switch (state) { + case NO_CHARS_DECODED: + if (decodedChar == PAD_INDEX) { + throw new IOException("Pad character in invalid position"); + } + quantum[0] = (byte) ((decodedChar << 2) & 0xFC); + state = ONE_CHAR_DECODED; + break; + case ONE_CHAR_DECODED: + if (decodedChar == PAD_INDEX) { + throw new IOException("Pad character in invalid position"); + } + quantum[0] = (byte) (quantum[0] | ((decodedChar >> 4) & 0x3)); + quantum[1] = (byte) ((decodedChar << 4) & 0xF0); + state = TWO_CHARS_DECODED; + break; + case TWO_CHARS_DECODED: + if (decodedChar == PAD_INDEX) { + ba.write(quantum, 0, 1); + state = PAD_THREE_READ; + } else { + quantum[1] = + (byte) (quantum[1] | ((decodedChar >> 2) & 0x0F)); + quantum[2] = (byte) ((decodedChar << 6) & 0xC0); + state = THREE_CHARS_DECODED; + } + break; + case THREE_CHARS_DECODED: + if (decodedChar == PAD_INDEX) { + ba.write(quantum, 0, 2); + state = PAD_FOUR_READ; + } else { + quantum[2] = (byte) (quantum[2] | decodedChar); + ba.write(quantum, 0, 3); + state = NO_CHARS_DECODED; + } + break; + case PAD_THREE_READ: + if (decodedChar != PAD_INDEX) { + throw new IOException("Missing pad character"); + } + state = PAD_FOUR_READ; + break; + case PAD_FOUR_READ: + throw new IOException("Invalid input follows pad character"); + } + } + + // Test valid terminal states + if (state != NO_CHARS_DECODED && state != PAD_FOUR_READ) { + throw new IOException("Invalid sequence of input characters"); + } + + return ba.toByteArray(); + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/Base64BinaryAttribute.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/Base64BinaryAttribute.java new file mode 100644 index 0000000..07cbc4f --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/Base64BinaryAttribute.java @@ -0,0 +1,251 @@ + +/* + * @(#)Base64BinaryAttribute.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.attr; + +import com.sun.xacml.Constants; +import com.sun.xacml.ParsingException; + +import java.io.IOException; + +import java.net.URI; + +import java.util.Arrays; + +import org.w3c.dom.Node; + + +/** + * Representation of an xsi:base64Binary value. This class supports parsing + * xsi:base64Binary values. All objects of this class are immutable and + * all methods of the class are thread-safe. + * + * @since 1.0 + * @author Steve Hanna + */ +public class Base64BinaryAttribute extends AttributeValue +{ + /** + * Official name of this type + */ + public static final String identifier = + TypeIdentifierConstants.BASE64BINARY; + + /** + * URI version of name for this type + *

+ * This field is initialized by a static initializer so that + * we can catch any exceptions thrown by URI(String) and + * transform them into a RuntimeException, since this should + * never happen but should be reported properly if it ever does. + */ + private static URI identifierURI; + + /** + * RuntimeException that wraps an Exception thrown during the + * creation of identifierURI, null if none. + */ + private static RuntimeException earlyException; + + /** + * Static initializer that initializes the identifierURI + * class field so that we can catch any exceptions thrown + * by URI(String) and transform them into a RuntimeException. + * Such exceptions should never happen but should be reported + * properly if they ever do. + */ + static { + try { + identifierURI = URI.create(identifier); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * The actual binary value that this object represents. + */ + private byte [] value; + + /** + * The value returned by toString(). Cached, but only + * generated if needed. + */ + private String strValue; + + /** + * Creates a new Base64BinaryAttribute that represents + * the byte [] value supplied. + * + * @param value the byte [] value to be represented + */ + public Base64BinaryAttribute(byte [] value) { + super(identifierURI); + + // Shouldn't happen, but just in case... + if (earlyException != null) { + throw earlyException; + } + // This will throw a NullPointerException if value == null. + // That's what we want in that case. + this.value = (byte[])value.clone(); + } + + /** + * Returns a new Base64BinaryAttribute that represents + * the xsi:base64Binary at a particular DOM node. + * + * @param root the Node that contains the desired value + * @return a new Base64BinaryAttribute representing the + * appropriate value + * @exception ParsingException if a parsing error occurs + */ + public static Base64BinaryAttribute getInstance(Node root) + throws ParsingException { + if (root.getFirstChild() != null) { + return getInstance(root.getFirstChild().getNodeValue()); + } + throw new ParsingException("Error while parsing" + + "a Base64BinaryAttribute"); + } + + /** + * Returns a new Base64BinaryAttribute that represents + * the xsi:base64Binary value indicated by the string provided. + * + * @param value a string representing the desired value + * @return a new Base64BinaryAttribute representing the + * desired value + * @exception ParsingException if a parsing error occurs + */ + public static Base64BinaryAttribute getInstance(String value) + throws ParsingException { + if (value == null) { + throw new ParsingException("Can't create a " + + "Base64BinaryAttribute from null input"); + } + byte [] bytes = null; + + try { + bytes = Base64.decode(value, false); + } catch (IOException e) { + throw new ParsingException("Couldn't parse purported " + + "Base64 string: " + value, e); + } + + return new Base64BinaryAttribute(bytes); + } + + /** + * Returns the byte [] value represented by this object. + * Note that this value is cloned before returning to prevent + * unauthorized modifications. + * + * @return the byte [] value + */ + public byte [] getValue() { + return (byte[])this.value.clone(); + } + + /** + * Returns true if the input is an instance of this class and if its + * value equals the value contained in this class. + * + * @param o the object to compare + * + * @return true if this object and the input represent the same value + */ + public boolean equals(Object o) { + if (! (o instanceof Base64BinaryAttribute)) { + return false; + } + Base64BinaryAttribute other = (Base64BinaryAttribute)o; + + return Arrays.equals(this.value, other.value); + } + + /** + * Returns the hashcode value used to index and compare this object with + * others of the same type. Typically this is the hashcode of the backing + * data object. + * + * @return the object's hashcode value + */ + public int hashCode() { + int code = this.value[0]; + + for (int i = 1; i < this.value.length; i++) { + code *= 31; + code += this.value[i]; + } + + return code; + } + + /** + * Make the String representation of this object. + * + * @return the String representation + */ + private String makeStringRep() { + return Base64.encode(this.value); + } + + /** + * Returns a String representation. + * + * @return the String representation + */ + public String toString() { + if (this.strValue == null) { + this.strValue = makeStringRep(); + } + return "Base64BinaryAttribute: [" + Constants.nl + + this.strValue + "]" + Constants.nl; + } + + /** + * @return The String encoding this AttributeValue. + */ + public String encode() { + if (this.strValue == null) { + this.strValue = makeStringRep(); + } + + return this.strValue; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/BaseAttributeFactory.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/BaseAttributeFactory.java new file mode 100644 index 0000000..d90d439 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/BaseAttributeFactory.java @@ -0,0 +1,267 @@ + +/* + * @(#)BaseAttributeFactory.java + * + * Copyright 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.attr; + +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; +import com.sun.xacml.debug.RuntimeInfo; +import com.sun.xacml.debug.RuntimeInfo.ELEMENT_TYPE; + +import java.net.URI; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.w3c.dom.Node; + + +/** + * This is a basic implementation of AttributeFactory. It + * implements the insertion and retrieval methods, but doesn't actually + * setup the factory with any datatypes. + *

+ * Note that while this class is thread-safe on all creation methods, it + * is not safe to add support for a new datatype while creating an instance + * of a value. This follows from the assumption that most people will + * initialize these factories up-front, and then start processing without + * ever modifying the factories. If you need these mutual operations to + * be thread-safe, then you should write a wrapper class that implements + * the right synchronization. + * + * @since 1.2 + * @author Seth Proctor + */ +public class BaseAttributeFactory extends AttributeFactory +{ + + // the map of proxies + private HashMap attributeMap; + + /** + * Default constructor. + */ + public BaseAttributeFactory() { + this.attributeMap = new HashMap(); + } + + /** + * Constructor that configures this factory with an initial set of + * supported datatypes. + * + * @param attributes a Map of Strings to + * AttributeProxys + * + * @throws IllegalArgumentException if any elements of the Map are not + * AttributeProxys + */ + public BaseAttributeFactory(Map attributes) { + this.attributeMap = new HashMap(); + + Iterator it = attributes.keySet().iterator(); + while (it.hasNext()) { + try { + String id = it.next(); + AttributeProxy proxy = attributes.get(id); + this.attributeMap.put(id, proxy); + } catch (ClassCastException cce) { + throw new IllegalArgumentException("an element of the map " + + "was not an instance of " + + "AttributeProxy"); + } + } + } + + /** + * Adds a proxy to the factory, which in turn will allow new attribute + * types to be created using the factory. Typically the proxy is + * provided as an anonymous class that simply calls the getInstance + * methods (or something similar) of some AttributeValue + * class. + * + * @param id the name of the attribute type + * @param proxy the proxy used to create new attributes of the given type + */ + public void addDatatype(String id, AttributeProxy proxy) { + // make sure this doesn't already exist + if (this.attributeMap.containsKey(id)) { + throw new IllegalArgumentException("datatype already exists"); + } + + this.attributeMap.put(id, proxy); + } + + /** + * Returns the datatype identifiers supported by this factory. + * + * @return a Set of Strings + */ + public Set getSupportedDatatypes() { + return Collections.unmodifiableSet(this.attributeMap.keySet()); + } + + /** + * Creates a value based on the given DOM root node. The type of the + * attribute is assumed to be present in the node as an XACML attribute + * named DataType, as is the case with the + * AttributeValueType in the policy schema. The value is assumed to be + * the first child of this node. + * + * @param root the DOM root of an attribute value + * + * @return a new AttributeValue + * + * @throws UnknownIdentifierException if the type in the node isn't + * known to the factory + * @throws ParsingException if the node is invalid or can't be parsed + * by the appropriate proxy + */ + public AttributeValue createValue(Node root) + throws UnknownIdentifierException, ParsingException { + if (root.getNodeType() != Node.ELEMENT_NODE || + root.getAttributes().getNamedItem("DataType") == null) { + RuntimeInfo src = RuntimeInfo.getRuntimeInfo(root, ELEMENT_TYPE.ATTRIBUTE_VALUE); + String message = ""; + if ( root.getNodeType() != Node.ELEMENT_NODE ) { + message = ": received element is not a node (" + root.toString() + ")"; + } else if ( root.getAttributes().getNamedItem("DataType") == null) { + message = ": missing attribute \"DataType\""; + } + + throw new ParsingException("Error while parsing AttributeValue" + message + + ( src == null ? "" : src.getLocationMsgForError())); + } + Node node = root.getAttributes().getNamedItem("DataType"); + + return createValue(root, node.getNodeValue()); + } + + /** + * Creates a value based on the given DOM root node and data type. + * + * @param root the DOM root of an attribute value + * @param dataType the type of the attribute + * + * @return a new AttributeValue + * + * @throws UnknownIdentifierException if the data type isn't known to + * the factory + * @throws ParsingException if the node is invalid or can't be parsed + * by the appropriate proxy + */ + public AttributeValue createValue(Node root, URI dataType) + throws UnknownIdentifierException, ParsingException + { + return createValue(root, dataType.toString()); + } + + /** + * Creates a value based on the given DOM root node and data type. + * + * @param root the DOM root of an attribute value + * @param type the type of the attribute + * + * @return a new AttributeValue + * + * @throws UnknownIdentifierException if the type isn't known to + * the factory + * @throws ParsingException if the node is invalid or can't be parsed + * by the appropriate proxy + */ + public AttributeValue createValue(Node root, String type) + throws UnknownIdentifierException, ParsingException + { + AttributeProxy proxy = (AttributeProxy)(this.attributeMap.get(type)); + + RuntimeInfo src = RuntimeInfo.getRuntimeInfo(root, ELEMENT_TYPE.ATTRIBUTE_VALUE); + + if (proxy != null) { + try { + AttributeValue val = proxy.getInstance(root); + if ( src != null ) { + val.setSrcLocFromFactory(src); + src.setXACMLObject(val); + } + return val; + } catch (Exception e) { + throw new ParsingException("couldn't create " + type + + " attribute based on DOM node" + + (src != null ? src.getLocationMsgForError() : ""), e); + } + } + throw new UnknownIdentifierException("Attributes of type " + type + + " aren't supported." + + (src != null ? src.getLocationMsgForError() : "")); + } + + /** + * Creates a value based on the given data type and text-encoded value. + * Used primarily by code that does an XPath query to get an + * attribute value, and then needs to turn the resulting value into + * an Attribute class. + * + * @param dataType the type of the attribute + * @param value the text-encoded representation of an attribute's value + * + * @return a new AttributeValue + * + * @throws UnknownIdentifierException if the data type isn't known to + * the factory + * @throws ParsingException if the text is invalid or can't be parsed + * by the appropriate proxy + */ + public AttributeValue createValue(URI dataType, String value) + throws UnknownIdentifierException, ParsingException + { + String type = dataType.toString(); + AttributeProxy proxy = (AttributeProxy)(this.attributeMap.get(type)); + + if (proxy != null) { + try { + return proxy.getInstance(value); + } catch (Exception e) { + throw new ParsingException("couldn't create " + type + + " attribute from input: " + value, e); + } + } + throw new UnknownIdentifierException("Attributes of type " + type + + " aren't supported."); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/BooleanAttribute.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/BooleanAttribute.java new file mode 100644 index 0000000..6b17a4b --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/BooleanAttribute.java @@ -0,0 +1,308 @@ + +/* + * @(#)BooleanAttribute.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.attr; + +import com.sun.xacml.ParsingException; + +import java.net.URI; + +import org.w3c.dom.Node; + + +/** + * Representation of an xs:boolean value. This class supports parsing + * xs:boolean values. All objects of this class are immutable and + * all methods of the class are thread-safe. + * + * @since 1.0 + * @author Marco Barreno + * @author Steve Hanna + */ +public class BooleanAttribute extends AttributeValue +{ + + /** + * Official name of this type + */ + public static final String identifier = TypeIdentifierConstants.BOOLEAN; + + /** + * URI version of name for this type + *

+ * This field is initialized by a static initializer so that + * we can catch any exceptions thrown by URI(String) and + * transform them into a RuntimeException, since this should + * never happen but should be reported properly if it ever does. + */ + private static URI identifierURI; + + /** + * RuntimeException that wraps an Exception thrown during the + * creation of identifierURI, null if none. + */ + private static RuntimeException earlyException; + + /** + * Single instance of BooleanAttribute that represents true. + * Initialized by the static initializer below. + */ + private static BooleanAttribute trueInstance; + + /** + * Single instance of BooleanAttribute that represents false. + * Initialized by the static initializer below. + */ + private static BooleanAttribute falseInstance; + + /** + * TODO hack? required for null value for defining missing + * attributes in the statusDetail + */ + private static BooleanAttribute invalidInstance; + + /** + * Static initializer that initializes many static fields. + *

+ * It is possible identifierURI + * class field so that we can catch any exceptions thrown + * by URI(String) and transform them into a RuntimeException. + * Such exceptions should never happen but should be reported + * properly if they ever do. + */ + static { + try { + identifierURI = URI.create(identifier); + trueInstance = new BooleanAttribute(true); + falseInstance = new BooleanAttribute(false); + invalidInstance = new BooleanAttribute(); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * The actual boolean value that this object represents. + */ + private boolean value; + + private boolean valid = true; + + /** + * Creates a new BooleanAttribute that represents + * the boolean value supplied. + *

+ * This constructor is private because it should not be used by + * anyone other than the static initializer in this class. + * Instead, please use one of the getInstance methods, which + * will ensure that only two BooleanAttribute objects are created, + * thus avoiding excess object creation. + */ + protected BooleanAttribute(boolean value) { + super(identifierURI); + + this.value = value; + } + + private BooleanAttribute() { + super(identifierURI); + + this.valid = false; + this.value = false; + } + + /** + * Returns a BooleanAttribute that represents + * the xs:boolean at a particular DOM node. + * + * @param root the Node that contains the desired value + * @return a BooleanAttribute representing the + * appropriate value (null if there is a parsing error) + * + * @throws ParsingException + */ + public static BooleanAttribute getInstance(Node root) + throws ParsingException { + if (root.getFirstChild() != null) { + return getInstance(root.getFirstChild().getNodeValue()); + } + throw new ParsingException("Error while parsing" + + "a BooleanAttribute"); + } + + /** + * Returns a BooleanAttribute that represents + * the xs:boolean value indicated by the string provided. + * + * @param value a string representing the desired value + * @return a BooleanAttribute representing the + * appropriate value (null if there is a parsing error) + * + * @throws ParsingException + */ + public static BooleanAttribute getInstance(String value) + throws ParsingException { + if (value == null) { + return invalidInstance; +// throw new ParsingException("Can't create a " +// + "BooleanAttribute from null input"); + } + // Shouldn't happen, but just in case... + if (earlyException != null) { + throw earlyException; + } + if (value.equals("true")) { + return trueInstance; + } + if (value.equals("false")) { + return falseInstance; + } + if (value.equals("")) { + return invalidInstance; + } + + throw new ParsingException("Boolean string must be true or false"); + } + + /** + * Returns a BooleanAttribute that represents + * the boolean value provided. + * + * @param value a boolean representing the desired value + * @return a BooleanAttribute representing the + * appropriate value + */ + public static BooleanAttribute getInstance(boolean value) { + + // Shouldn't happen, but just in case... + if (earlyException != null) { + throw earlyException; + } + + if (value) { + return trueInstance; + } + return falseInstance; + } + + /** + * Returns a BooleanAttribute that represents + * a true value. + * + * @return a BooleanAttribute representing a + * true value + */ + public static BooleanAttribute getTrueInstance() { + + // Shouldn't happen, but just in case... + if (earlyException != null) { + throw earlyException; + } + return trueInstance; + } + + /** + * Returns a BooleanAttribute that represents + * a false value. + * + * @return a BooleanAttribute representing a + * false value + */ + public static BooleanAttribute getFalseInstance() { + + // Shouldn't happen, but just in case... + if (earlyException != null) { + throw earlyException; + } + + return falseInstance; + } + + /** + * Returns the boolean value represented by this object. + * + * @return the boolean value + */ + public boolean getValue() { + if (!valid) { + throw new RuntimeException("Accessing invalid attribute"); + } + return this.value; + } + + /** + * Returns true if the input is an instance of this class and if its + * value equals the value contained in this class. + * + * @param o the object to compare + * + * @return true if this object and the input represent the same value + */ + public boolean equals(Object o) { + if (! (o instanceof BooleanAttribute)) { + return false; + } + + BooleanAttribute other = (BooleanAttribute)o; + + return (this.value == other.value && this.valid == other.valid); + } + + /** + * Returns the hashcode value used to index and compare this object with + * others of the same type. Typically this is the hashcode of the backing + * data object. + * + * @return the object's hashcode value + */ + public int hashCode() { + // these numbers come from the javadoc for java.lang.Boolean...no, + // really, they do. I can't imagine what they were thinking... + return (this.value ? 1231 : 1237); + } + + /** + * @return The String encoding this AttributeValue. + */ + public String encode() { + if (valid ) { + return (this.value ? "true" : "false"); + } else { + return ""; + } + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DNSNameAttribute.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DNSNameAttribute.java new file mode 100644 index 0000000..2601673 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DNSNameAttribute.java @@ -0,0 +1,292 @@ + +/* + * @(#)DNSNameAttribute.java + * + * Copyright 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.attr; + +import java.net.URI; + +import org.w3c.dom.DOMException; +import org.w3c.dom.Node; + +import com.sun.xacml.ParsingException; + + +/** + * Represents the DNSName datatype introduced in XACML 2.0. All objects of + * this class are immutable and all methods of the class are thread-safe. + * + * @since 2.0 + * @author Seth Proctor + */ +public class DNSNameAttribute extends AttributeValue +{ + + /** + * Official name of this type + */ + public static final String identifier = + TypeIdentifierConstants.DNSNAME; + + /** + * URI version of name for this type + *

+ * This field is initialized by a static initializer so that + * we can catch any exceptions thrown by URI(String) and + * transform them into a RuntimeException, since this should + * never happen but should be reported properly if it ever does. + */ + private static URI identifierURI; + + /** + * RuntimeException that wraps an Exception thrown during the + * creation of identifierURI, null if none. + */ + private static RuntimeException earlyException; + + /** + * Static initializer that initializes the identifierURI + * class field so that we can catch any exceptions thrown + * by URI(String) and transform them into a RuntimeException. + * Such exceptions should never happen but should be reported + * properly if they ever do. + */ + static { + try { + identifierURI = new URI(identifier); + } catch (Exception e) { + earlyException = new IllegalArgumentException(); + earlyException.initCause(e); + } + } + + // the required hostname + private String hostname; + + // the optional port range + private PortRange range; + + // true if the hostname starts with a '*' + private boolean isSubdomain = false; + + /** + * Creates the new DNSNameAttribute with only the required + * hostname component. + * + * @param hostname the host name component of the address + */ + public DNSNameAttribute(String hostname) { + this(hostname, new PortRange()); + } + + /** + * Creates the new DNSNameAttribute with the optional + * port range component. + * + * @param hostname the host name component of the address + * @param range the port range + */ + public DNSNameAttribute(String hostname, PortRange range) { + super(identifierURI); + + // shouldn't happen, but just in case... + if (earlyException != null) { + throw earlyException; + } + // verify that the hostname is valid before we store it + if (! isValidHostName(hostname)) { + System.err.println("FIXME: throw error about bad hostname"); + } + // see if it started with a '*' character + if (hostname.charAt(0) == '*') { + this.isSubdomain = true; + } + this.hostname = hostname; + this.range = range; + } + + /** + * Private helper that tests whether the given string is valid. + */ + private boolean isValidHostName(String hostname) { + /* + hostname = *( domainlabel "." ) toplabel [ "." ] + domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum + toplabel = alpha | alpha *( alphanum | "-" ) alphanum + */ + + String domainlabel = "\\w[[\\w|\\-]*\\w]?"; + String toplabel = "[a-zA-Z][[\\w|\\-]*\\w]?"; + String pattern = "[\\*\\.]?[" + domainlabel + "\\.]*" + toplabel + + "\\.?"; + + return hostname.matches(pattern); + } + + /** + * Returns a new DNSNameAttribute that represents + * the name at a particular DOM node. + * + * @param root the Node that contains the desired value + * + * @return a new DNSNameAttribute representing the + * appropriate value (null if there is a parsing error) + * @throws ParsingException + * @throws DOMException + */ + public static DNSNameAttribute getInstance(Node root) + throws DOMException, ParsingException { + if (root.getFirstChild() != null) { + return getInstance(root.getFirstChild().getNodeValue()); + } + throw new ParsingException("Error while parsing" + + "a DNSNameAttribute"); + } + + /** + * Returns a new DNSNameAttribute that represents + * the name indicated by the String provided. + * + * @param value a string representing the name + * + * @return a new DNSNameAttribute + * @throws ParsingException + */ + public static DNSNameAttribute getInstance(String value) + throws ParsingException { + if (value == null) { + throw new ParsingException("Can't create a " + + "DNSNameAttribute from null input"); + } + int portSep = value.indexOf(':'); + + if (portSep == -1) { + // there is no port range, so just use the name + return new DNSNameAttribute(value); + } + // split the name and the port range + String hostname = value.substring(0, portSep); + PortRange range = + PortRange.getInstance(value.substring(portSep + 1, + value.length())); + return new DNSNameAttribute(hostname, range); + } + + /** + * Returns the host name represented by this object. + * + * @return the host name + */ + public String getHostName() { + return this.hostname; + } + + /** + * Returns the port range represented by this object which will be + * unbound if no range was specified. + * + * @return the port range + */ + public PortRange getPortRange() { + return this.range; + } + + /** + * Returns true if the leading character in the hostname is a '*', and + * therefore represents a matching subdomain, or false otherwise. + * + * @return true if the name represents a subdomain, false otherwise + */ + public boolean isSubdomain() { + return this.isSubdomain; + } + + /** + * Returns true if the input is an instance of this class and if its + * value equals the value contained in this class. + * + * @param o the object to compare + * + * @return true if this object and the input represent the same value + */ + public boolean equals(Object o) { + if (! (o instanceof DNSNameAttribute)) { + return false; + } + DNSNameAttribute other = (DNSNameAttribute)o; + + if (! this.hostname.toUpperCase().equals( + other.hostname.toUpperCase())) { + return false; + } + + if (! this.range.equals(other.range)) { + return false; + } + + return true; + } + + /** + * Returns the hashcode value used to index and compare this object with + * others of the same type. + * + * @return the object's hashcode value + */ + public int hashCode() { + return encode().hashCode(); + } + + /** + * Converts to a String representation. + * + * @return the String representation + */ + public String toString() { + return "DNSNameAttribute: \"" + encode() + "\""; + } + + /** + * @return The String encoding this AttributeValue. + */ + public String encode() { + if (this.range.isUnbound()) { + return this.hostname; + } + + return this.hostname + ":" + this.range.encode(); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DateAttribute.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DateAttribute.java new file mode 100644 index 0000000..8c22abd --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DateAttribute.java @@ -0,0 +1,714 @@ + +/* + * @(#)DateAttribute.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.attr; + +import java.net.URI; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.ParsePosition; +import java.text.SimpleDateFormat; + +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +import org.w3c.dom.Node; + +import com.sun.xacml.Constants; +import com.sun.xacml.ParsingException; + + +/** + * Representation of an xs:date value. This class supports parsing + * xs:date values. All objects of this class are immutable and + * thread-safe. The Date objects returned are not, but + * these objects are cloned before being returned. + * + * @since 1.0 + * @author Marco Barreno + * @author Seth Proctor + * @author Steve Hanna + */ +public class DateAttribute extends AttributeValue +{ + /** + * Official name of this type + */ + public static final String identifier = TypeIdentifierConstants.DATE; + + /** + * URI version of name for this type + *

+ * This field is initialized by a static initializer so that + * we can catch any exceptions thrown by URI(String) and + * transform them into a RuntimeException, since this should + * never happen but should be reported properly if it ever does. + *

+ * This object is used for synchronization whenever we need + * protection across this whole class. + */ + private static URI identifierURI; + + /** + * RuntimeException that wraps an Exception thrown during the + * creation of identifierURI, null if none. + */ + private static RuntimeException earlyException; + + /** + * Static initializer that initializes the identifierURI + * class field so that we can catch any exceptions thrown + * by URI(String) and transform them into a RuntimeException. + * Such exceptions should never happen but should be reported + * properly if they ever do. + */ + static { + try { + identifierURI = URI.create(identifier); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * Parser for dates with no time zones + *

+ * This field is only initialized if needed (by initParsers()). + *

+ * NOTE: This object should only be accessed from code that + * has synchronized on it, since SimpleDateFormat objects are not + * thread-safe. + */ + private DateFormat simpleParser; + + /** + * Parser for dates with RFC 822 time zones (like +0300) + *

+ * This field is only initialized if needed (by initParsers()). + *

+ * NOTE: This object should only be accessed from code that + * has a lock on it, since SimpleDateFormat objects are not + * thread-safe. + */ + private DateFormat zoneParser; + + /** + * Calendar for GMT + *

+ * NOTE: This object should only be accessed from code that + * has a lock on it, since Calendar objects are not generally + * thread-safe. + */ + private Calendar gmtCalendar; + + /** + * Number of nanoseconds per millisecond + * (shared by other classes in this package) + */ + static final int NANOS_PER_MILLI = 1000000; + + /** + * Number of milliseconds per second + * (shared by other classes in this package) + */ + static final int MILLIS_PER_SECOND = 1000; + + /** + * Number of seconds in a minute + * (shared by other classes in this package) + */ + static final int SECONDS_PER_MINUTE = 60; + + /** + * Number of minutes in an hour + * (shared by other classes in this package) + */ + static final int MINUTES_PER_HOUR = 60; + + /** + * Number of hours in a day + * (shared by other classes in this package) + */ + static final int HOURS_PER_DAY = 24; + + /** + * Number of nanoseconds per second + * (shared by other classes in this package) + */ + static final int NANOS_PER_SECOND = NANOS_PER_MILLI * MILLIS_PER_SECOND; + + /** + * Number of milliseconds in a minute + * (shared by other classes in this package) + */ + static final int MILLIS_PER_MINUTE = + MILLIS_PER_SECOND * SECONDS_PER_MINUTE; + + /** + * Number of milliseconds in an hour + * (shared by other classes in this package) + */ + static final int MILLIS_PER_HOUR = + MILLIS_PER_MINUTE * MINUTES_PER_HOUR; + + /** + * Number of milliseconds in a day + * (shared by other classes in this package) + */ + static final long MILLIS_PER_DAY = MILLIS_PER_HOUR * HOURS_PER_DAY; + + /** + * Time zone value that indicates that the time zone was not + * specified. + */ + public static final int TZ_UNSPECIFIED = -1000000; + + /** + * The instant (in GMT) at which the specified date began (midnight) + * in the specified time zone. If no time zone was specified, + * the local time zone is used. + */ + private Date value; + + /** + * The time zone specified for this object (or TZ_UNSPECIFIED if + * unspecified). The offset to GMT, in minutes. + */ + private int timeZone; + + /** + * The time zone actually used for this object (if it was + * originally unspecified, the default time zone used). + * The offset to GMT, in minutes. + */ + private int defaultedTimeZone; + + /** + * Cached encoded value (null if not cached yet). + */ + private String encodedValue = null; + + /** + * Creates a new TimeAttribute that represents + * the current date in the default time zone. + */ + public DateAttribute() { + this(new Date()); + } + + /** + * Creates a new TimeAttribute that represents + * the given date with default timezone values. + * + * @param date a Date object representing the + * instant at which the specified date began (midnight) + * in the specified time zone (the actual time value + * will be forced to midnight) + */ + public DateAttribute(Date date) { + super(identifierURI); + + // Get the current time and GMT offset + int currOffset = DateTimeAttribute.getDefaultTZOffset(date); + long millis = date.getTime(); + + // Now find out the last time it was midnight local time + // (actually the last time it was midnight with the current + // GMT offset, but that's good enough). + + // Skip back by time zone offset. + // Multiplication with 1L to avoid overflows in the + // integer multiplication, since it's converted to long anyway + millis += 1L * currOffset * MILLIS_PER_MINUTE; + // Reset to last GMT midnight + millis -= millis % MILLIS_PER_DAY; + // Skip forward by time zone offset. + // Multiplication with 1L to avoid overflows in the + // integer multiplication, since it's converted to long anyway + millis -= 1L * currOffset * MILLIS_PER_MINUTE; + date.setTime(millis); + init(date, currOffset, currOffset); + } + + /** + * Creates a new DateAttribute that represents + * the date supplied. + * + * @param date a Date object representing the + * instant at which the specified date began (midnight) + * in the specified time zone + * @param timeZone the time zone specified for this object + * (or TZ_UNSPECIFIED if unspecified). The + * offset to GMT, in minutes. + * @param defaultedTimeZone the time zone actually used for this + * object (if it was originally unspecified, + * the default time zone used). + * The offset to GMT, in minutes. + */ + public DateAttribute(Date date, int timeZone, int defaultedTimeZone) { + super(identifierURI); + + init(date, timeZone, defaultedTimeZone); + } + + /** + * Initialization code shared by constructors. + * + * @param date a Date object representing the + * instant at which the specified date began (midnight) + * in the specified time zone. + * @param timeZone the time zone specified for this object + * (or TZ_UNSPECIFIED if unspecified). The + * offset to GMT, in minutes. + * @param defaultedTimeZone the time zone actually used for this + * object (if it was originally unspecified, + * the default time zone used). + * The offset to GMT, in minutes. + */ + private void init(Date date, int timeZone, int defaultedTimeZone) { + + // Shouldn't happen, but just in case... + if (earlyException != null) { + throw earlyException; + } + + this.value = (Date) date.clone(); + this.timeZone = timeZone; + this.defaultedTimeZone = defaultedTimeZone; + } + + /** + * Returns a new DateAttribute that represents + * the xs:date at a particular DOM node. + * + * @param root the Node that contains the desired value + * @return a new DateAttribute representing the + * appropriate value (null if there is a parsing error) + * + * @throws ParseException + * @throws ParsingException + */ + public static DateAttribute getInstance(Node root) + throws ParseException, ParsingException { + if (root.getFirstChild() != null) { + return getInstance(root.getFirstChild().getNodeValue()); + } + throw new ParsingException("Error while parsing" + + "a DateAttribute"); + } + + /** + * Returns a new DateAttribute that represents + * the xs:date value indicated by the string provided. + * + * @param value a string representing the desired value + * @return a new DateAttribute representing the + * desired value (null if there is a parsing error) + * + * @throws ParseException + * @throws ParsingException + */ + public static DateAttribute getInstance(String value) + throws ParseException, ParsingException { + if (value == null) { + throw new ParsingException("Can't create a " + + "DateAttribute from null input"); + } + Date dateValue = null; + int timeZone; + int defaultedTimeZone; + + // This simple parser has no time zone + DateFormat simpleParser = new SimpleDateFormat("yyyy-MM-dd"); + simpleParser.setLenient(false); + + // This parser has a four digit offset to GMT with sign + DateFormat zoneParser = new SimpleDateFormat("yyyy-MM-ddZ"); + // FIXME: temporarily we need to set this to true + // this is a problem with Java 1.5, if you now + // of good documentation about the differnces between + // SimpleDateFormat in 1.4 and 1.5 let me (ludwig) know. + zoneParser.setLenient(true); + + // If string ends with Z, it's in GMT. Chop off the Z and + // add +0000 to make the time zone explicit, then parse it + // with the timezone parser. + if (value.endsWith("Z")) { + value = value.substring(0, value.length()-1) + "+0000"; + dateValue = strictParse(zoneParser, value); + timeZone = 0; + defaultedTimeZone = 0; + } else { + // If string ends with :XX, it must have a time zone + // or be invalid. Strip off the possible time zone and + // make sure what's left is a valid simple date. If so, + // reformat the time zone by stripping out the colon + // and parse the whole thing with the timezone parser. + int len = value.length(); + + if ((len > 6) && (value.charAt(len-3) == ':')) { + Date gmtValue = strictParse(zoneParser, + value.substring(0,len-6) + + "+0000"); + value = value.substring(0, len-3) + + value.substring(len-2, len); + dateValue = strictParse(zoneParser, value); + timeZone = + (int) (gmtValue.getTime() - dateValue.getTime()); + timeZone = timeZone / 60000; + defaultedTimeZone = timeZone; + } else { + // No funny business. This must be a simple date. + dateValue = strictParse(simpleParser, value); + timeZone = TZ_UNSPECIFIED; + Date gmtValue = strictParse(zoneParser, value + "+0000"); + defaultedTimeZone = + (int) (gmtValue.getTime() - dateValue.getTime()); + defaultedTimeZone = defaultedTimeZone / 60000; + } + } + + // If parsing went OK, create a new DateAttribute object and + // return it. + DateAttribute attr = new DateAttribute(dateValue, timeZone, + defaultedTimeZone); + return attr; + } + + /** + * Parse a String using a DateFormat parser, requiring that + * the entire String be consumed by the parser. On success, + * return a Date. On failure, throw a ParseException. + *

+ * Synchronize on the parser object when using it, since we + * assume they're the shared static objects in this class. + */ + private static Date strictParse(DateFormat parser, String str) + throws ParseException { + ParsePosition pos = new ParsePosition(0); + Date ret; + synchronized (parser) { + ret = parser.parse(str, pos); + } + if (pos.getIndex() != str.length()) { + throw new ParseException("", 0); + } + return ret; + } + + /** + * Initialize the parser objects. + */ + private void initParsers() { + // If simpleParser is already set, we're done. + if (this.simpleParser != null) { + return; + } + + // Make sure that identifierURI is not null + if (earlyException != null) { + throw earlyException; + } + + // Synchronize on identifierURI while initializing parsers + // so we don't end up using a half-way initialized parser + synchronized (identifierURI) { + // This simple parser has no time zone + this.simpleParser = new SimpleDateFormat("yyyy-MM-dd"); + this.simpleParser.setLenient(false); + + // This parser has a four digit offset to GMT with sign + this.zoneParser = new SimpleDateFormat("yyyy-MM-ddZ"); + // FIXME: temporarily we need to set this to true + // this is a problem with Java 1.5, if you now + // of good documentation about the differnces between + // SimpleDateFormat in 1.4 and 1.5 let me (ludwig) know. + this.zoneParser.setLenient(true); + } + } + + /** + * Gets the date represented by this object. The return value is + * a Date object representing the + * instant at which the specified date began (midnight) + * in the time zone. + *

+ * NOTE: The Date object is cloned before it + * is returned to avoid unauthorized changes. + * + * @return a Date object representing the instant + * at which the date began + */ + public Date getValue() { + return (Date) this.value.clone(); + } + + /** + * Gets the specified time zone of this object (or + * TZ_UNSPECIFIED if unspecified). + * + * @return the offset to GMT in minutes (positive or negative) + */ + public int getTimeZone() { + return this.timeZone; + } + + /** + * Gets the time zone actually used for this object (if it was + * originally unspecified, the default time zone used). + * + * @return the offset to GMT in minutes (positive or negative) + */ + public int getDefaultedTimeZone() { + return this.defaultedTimeZone; + } + + /** + * Returns true if the input is an instance of this class and if its + * value equals the value contained in this class. + *

+ * Two DateAttributes are equal if and only if the + * instant on which the date began is equal. This means that they + * must have the same time zone. + * + * @param o the object to compare + * + * @return true if this object and the input represent the same value + */ + public boolean equals(Object o) { + if (! (o instanceof DateAttribute)) { + return false; + } + + DateAttribute other = (DateAttribute)o; + + return this.value.equals(other.value); + } + + /** + * Returns the hashcode value used to index and compare this object with + * others of the same type. + * + * @return the object's hashcode value + */ + public int hashCode() { + // Only the value field is considered by the equals method, so only + // that field should be considered by this method. + return this.value.hashCode(); + } + + /** + * Converts to a String representation. + * + * @return the String representation + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + + sb.append("DateAttribute: [" + Constants.nl); + sb.append(" Date: " + this.value + " local time"); + sb.append(" TimeZone: " + this.timeZone); + sb.append(" Defaulted TimeZone: " + this.defaultedTimeZone); + sb.append("]"); + + return sb.toString(); + } + + /** + * Encodes the value in a form suitable for including in XML data like + * a request or an obligation. This must return a value that could in + * turn be used by the factory to create a new instance with the same + * value. + * + * @return a String form of the value + */ + public String encode() { + if (this.encodedValue != null) { + return this.encodedValue; + } + + if (this.timeZone == TZ_UNSPECIFIED) { + // If no time zone was specified, format Date value in + // local time with no time zone string. + initParsers(); + synchronized (this.simpleParser) { + this.encodedValue = this.simpleParser.format(this.value); + } + } else { + // If a time zone was specified, don't use SimpleParser + // because it can only format dates in the local (default) + // time zone. And the offset between that time zone and the + // time zone we need to display can vary in complicated ways. + + // Instead, do it ourselves using our formatDateWithTZ method. + this.encodedValue = formatDateWithTZ(); + } + return this.encodedValue; + } + + /** + * Encodes the value of this object as an xsi:date. + * Only for use when the time zone is specified. + * + * @return a String form of the value + */ + private String formatDateWithTZ() { + if (this.gmtCalendar == null) { + TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT"); + + // Locale doesn't make much difference here. We don't use + // any of the strings in the Locale and we don't do anything + // that depends on week count conventions. We use the US + // locale because it's always around and it ensures that we + // will always get a Gregorian calendar, which is necessary + // for compliance with ISO 8501. + this.gmtCalendar = Calendar.getInstance(gmtTimeZone, Locale.US); + } + + // "YYYY-MM-DD+hh:mm".length() = 16 + // Length may be longer if years < -999 or > 9999 + StringBuffer buf = new StringBuffer(16); + + // Start with the GMT instant when the date started in the + // specified time zone (would be 7:00 PM the preceding day + // if the specified time zone was +0500). + this.gmtCalendar.setTime(this.value); + // Bump by the timeZone (so we get the right date/time that + // that we want to format) + this.gmtCalendar.add(Calendar.MINUTE, this.timeZone); + + // Now, assemble the string + int year = this.gmtCalendar.get(Calendar.YEAR); + buf.append(zeroPadInt(year, 4)); + buf.append('-'); + // JANUARY is 0 + int month = this.gmtCalendar.get(Calendar.MONTH) + 1; + buf.append(zeroPadInt(month, 2)); + buf.append('-'); + int dom = this.gmtCalendar.get(Calendar.DAY_OF_MONTH); + buf.append(zeroPadInt(dom, 2)); + + int tzNoSign = this.timeZone; + if (this.timeZone < 0) { + tzNoSign = -tzNoSign; + buf.append('-'); + } else { + buf.append('+'); + } + int tzHours = tzNoSign / 60; + buf.append(zeroPadInt(tzHours, 2)); + buf.append(':'); + int tzMinutes = tzNoSign % 60; + buf.append(zeroPadInt(tzMinutes, 2)); + + return buf.toString(); + } + + /** + * Takes a String representation of an integer (an optional + * sign followed by digits) and pads it with zeros on the left + * until it has at least the specified number of digits. + * Note that this function will work for an integer of + * any size: int, long, etc. + * + * @param unpadded the unpadded String + * (must have length of at least one) + * @param minDigits the minimum number of digits desired + * @return the padded String + */ + static String zeroPadIntString(String unpadded, int minDigits) { + int len = unpadded.length(); + + // Get the sign character (or 0 if none) + char sign = unpadded.charAt(0); + if ((sign != '-') && (sign != '+')) { + sign = 0; + } + + // The number of characters required is the number of digits, + // plus one for the sign if present. + int minChars = minDigits; + if (sign != 0) { + minChars++; + } + + // If we already have that many characters, we're done. + if (len >= minChars) { + return unpadded; + } + + // Otherwise, create the buffer + StringBuffer buf = new StringBuffer(); + + // Copy in the sign first, if present + if (sign != 0) { + buf.append(sign); + } + + // Add the zeros + int zerosNeeded = minChars - len; + while (zerosNeeded-- != 0) { + buf.append('0'); + } + // Copy the rest of the unpadded string + if (sign != 0) { + // Skip sign + buf.append(unpadded.substring(1, len)); + } else { + buf.append(unpadded); + } + + return buf.toString(); + } + + /** + * Converts an integer to a base 10 string and pads it with + * zeros on the left until it has at least the specified + * number of digits. Note that the length of the resulting + * string will be greater than minDigits if the number is + * negative since the string will start with a minus sign. + * + * @param intValue the integer to convert + * @param minDigits the minimum number of digits desired + * @return the padded String + */ + static String zeroPadInt(int intValue, int minDigits) { + return zeroPadIntString(Integer.toString(intValue), minDigits); + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DateTimeAttribute.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DateTimeAttribute.java new file mode 100644 index 0000000..1fdb231 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DateTimeAttribute.java @@ -0,0 +1,754 @@ + +/* + * @(#)DateTimeAttribute.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.attr; + +import com.sun.xacml.Constants; +import com.sun.xacml.ParsingException; + +import java.net.URI; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.ParsePosition; +import java.text.SimpleDateFormat; + +import java.util.Calendar; +import java.util.Date; +import java.util.Locale; +import java.util.TimeZone; + +import org.w3c.dom.Node; + + +/** + * Representation of an xs:dateTime value. This class supports parsing + * xs:dateTime values. All objects of this class are immutable and + * thread-safe. The Date objects returned are not, but + * these objects are cloned before being returned. + * + * @since 1.0 + * @author Marco Barreno + * @author Seth Proctor + * @author Steve Hanna + * @author Ludwig Seitz + */ +public class DateTimeAttribute extends AttributeValue implements Cloneable +{ + /** + * Official name of this type + */ + public static final String identifier = + TypeIdentifierConstants.DATETIME; + + + /** + * URI version of name for this type + *

+ * This field is initialized by a static initializer so that + * we can catch any exceptions thrown by URI(String) and + * transform them into a RuntimeException, since this should + * never happen but should be reported properly if it ever does. + *

+ * This object is used for synchronization whenever we need + * protection across this whole class. + */ + private static URI identifierURI; + + /** + * RuntimeException that wraps an Exception thrown during the + * creation of identifierURI, null if none. + */ + private static RuntimeException earlyException; + + /** + * Static initializer that initializes the identifierURI + * class field so that we can catch any exceptions thrown + * by URI(String) and transform them into a RuntimeException. + * Such exceptions should never happen but should be reported + * properly if they ever do. + */ + static { + try { + identifierURI = URI.create(identifier); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * Parser for dates with no time zones + *

+ * This field is only initialized if needed (by initParsers()). + *

+ * NOTE: This object should only be accessed from code that + * has synchronized on it, since SimpleDateFormat objects are not + * thread-safe. + */ + private DateFormat simpleParser; + + /** + * Parser for dates with RFC 822 time zones (like +0300) + *

+ * This field is only initialized if needed (by initParsers()). + *

+ * NOTE: This object should only be accessed from code that + * has synchronized on it, since SimpleDateFormat objects are not + * thread-safe. + */ + private DateFormat zoneParser; + + /** + * Calendar for GMT + *

+ * NOTE: This object should only be accessed from code that + * has a lock on it, since Calendar objects are not generally + * thread-safe. + */ + private Calendar gmtCalendar; + + /** + * Time zone value that indicates that the time zone was not + * specified. + */ + public static final int TZ_UNSPECIFIED = -1000000; + + /** + * The actual date and time that this object represents (in GMT, + * as with all Date objects). If no time zone was specified, the + * local time zone is used to convert to GMT. + *

+ * This Date does not include fractions of a second. Those are + * handled by the separate nanoseconds field, since Date only + * provides millisecond accuracy and the XML Query spec requires + * at least 100 nanosecond accuracy. + */ + private Date value; + + /** + * The number of nanoseconds beyond the Date given by the value + * field. The XML Query document says that fractional seconds + * must be supported down to at least 100 nanosecond resolution. + * The Date class only supports milliseconds, so we include here + * support for nanosecond resolution. + */ + private int nanoseconds; + + /** + * The time zone specified for this object (or TZ_UNSPECIFIED if + * unspecified). The offset to GMT, in minutes. + */ + private int timeZone; + + /** + * The time zone actually used for this object (if it was + * originally unspecified, the default time zone used). + * The offset to GMT, in minutes. + */ + private int defaultedTimeZone; + + /** + * Cached encoded value (null if not cached yet). + */ + private String encodedValue = null; + + /** + * Creates a new DateTimeAttribute that represents + * the current date in the default time zone. + */ + public DateTimeAttribute() { + this(new Date()); + } + + /** + * Creates a new DateTimeAttribute that represents + * the supplied date but uses default timezone and offset values. + * + * @param dateTime a Date object representing the + * specified date and time down to second + * resolution. If this object has non-zero + * milliseconds, they are combined + * with the nanoseconds parameter. + */ + public DateTimeAttribute(Date dateTime) { + super(identifierURI); + + int currOffset = getDefaultTZOffset(dateTime); + init(dateTime, 0, currOffset, currOffset); + } + + /** + * Creates a new DateTimeAttribute that represents + * the date supplied. + * + * @param dateTime a Date object representing the + * specified date and time down to second + * resolution. If this object has non-zero + * milliseconds, they are combined + * with the nanoseconds parameter. + * @param nanoseconds the number of nanoseconds beyond the + * Date specified in the date parameter + * @param timeZone the time zone specified for this object + * (or TZ_UNSPECIFIED if unspecified). The + * offset to GMT, in minutes. + * @param defaultedTimeZone the time zone actually used for this + * object (if it was originally unspecified, + * the default time zone used). + * The offset to GMT, in minutes. + */ + public DateTimeAttribute(Date dateTime, int nanoseconds, int timeZone, + int defaultedTimeZone) { + super(identifierURI); + + init(dateTime, nanoseconds, timeZone, defaultedTimeZone); + } + + /** + * The clone method. + * + * @return a copy of this object. + */ + public Object clone() { + try { + DateTimeAttribute clone = (DateTimeAttribute)super.clone(); + clone.value = (Date)this.value.clone(); + clone.nanoseconds = this.nanoseconds; + clone.timeZone = this.timeZone; + clone.defaultedTimeZone = this.defaultedTimeZone; + clone.encodedValue = this.encodedValue; + return clone; + } catch (CloneNotSupportedException e) {//this should never happen + throw new RuntimeException("Couldn't clone DateTimeAttribute"); + } + } + + /** + * Initialization code shared by constructors. + * + * @param date a Date object representing the + * specified date and time down to second + * resolution. If this object has non-zero + * milliseconds, they are combined + * with the nanoseconds parameter. + * @param nanoseconds the number of nanoseconds beyond the + * Date specified in the date parameter + * @param timeZone the time zone specified for this object + * (or TZ_UNSPECIFIED if unspecified). The + * offset to GMT, in minutes. + * @param defaultedTimeZone the time zone actually used for this + * object (if it was originally unspecified, + * the default time zone used). + * The offset to GMT, in minutes. + */ + private void init(Date date, int nanoseconds, int timeZone, + int defaultedTimeZone) { + + // Shouldn't happen, but just in case... + if (earlyException != null) { + throw earlyException; + } + + // Make a new Date object + this.value = (Date) date.clone(); + // Combine the nanoseconds so they are between 0 and 999,999,999 + this.nanoseconds = combineNanos(this.value, nanoseconds); + this.timeZone = timeZone; + this.defaultedTimeZone = defaultedTimeZone; + } + + /** + * Returns a new DateTimeAttribute that represents + * the xs:dateTime at a particular DOM node. + * + * @param root the Node that contains the desired value + * @return a new DateTimeAttribute representing the + * appropriate value + * + * @throws ParsingException if any problems occurred while parsing + * @throws NumberFormatException + * @throws ParseException + */ + public static DateTimeAttribute getInstance(Node root) + throws ParsingException, NumberFormatException, ParseException { + if (root.getFirstChild() != null) { + return getInstance(root.getFirstChild().getNodeValue()); + } + throw new ParsingException("Error while parsing" + + "a DayTimeAttribute"); + } + + /** + * Returns a new DateTimeAttribute that represents + * the xs:dateTime value indicated by the string provided. + * + * @param value a string representing the desired value + * @return a new DateTimeAttribute representing the + * desired value + * @throws ParsingException if the text is formatted incorrectly + * @throws NumberFormatException if the nanosecond format is incorrect + * @throws ParseException + */ + public static DateTimeAttribute getInstance(String value) + throws ParsingException, NumberFormatException, ParseException { + if (value == null) { + throw new ParsingException("Can't create a " + + "DayTimeAttribute from null input"); + } + Date dateValue = null; + int nanoseconds = 0; + int timeZone; + int defaultedTimeZone; + + // This simple parser has no time zone + DateFormat simpleParser + = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); + simpleParser.setLenient(false); + + // This parser has a four digit offset to GMT with sign + DateFormat zoneParser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + //FIXME: temporarily we need to set this to true + // this is a problem with Java 1.5, if you now + // of good documentation about the differnces between SimpleDateFormat + // in 1.4 and 1.5 let me (ludwig) know. + zoneParser.setLenient(true); + + // If string ends with Z, it's in GMT. Chop off the Z and + // add +00:00 to make the time zone explicit. + if (value.endsWith("Z")) { + value = value.substring(0, value.length()-1) + "+00:00"; + } + + // Figure out if the string has a time zone. + // If string ends with +XX:XX or -XX:XX, it must have + // a time zone or be invalid. + int len = value.length(); // This variable is often not up-to-date + boolean hasTimeZone = ((value.charAt(len-3) == ':') && + ((value.charAt(len-6) == '-') || + (value.charAt(len-6) == '+'))); + + // If string contains a period, it must have fractional + // seconds (or be invalid). Strip them out and put the + // value in nanoseconds. + int dotIndex = value.indexOf('.'); + if (dotIndex != -1) { + // Decide where fractional seconds end. + int secondsEnd = value.length(); + if (hasTimeZone) { + secondsEnd -= 6; + } + // Copy the fractional seconds out of the string. + String nanoString = value.substring(dotIndex+1, secondsEnd); + // Check that all those characters are ASCII digits. + for (int i = nanoString.length()-1; i >= 0; i--) { + char c = nanoString.charAt(i); + if ((c < '0') || (c > '9')) { + throw new ParsingException("non-ascii digit found"); + } + } + // If there are less than 9 digits in the fractional seconds, + // pad with zeros on the right so it's nanoseconds. + while (nanoString.length() < 9) { + nanoString += "0"; + } + // If there are more than 9 digits in the fractional seconds, + // drop the least significant digits. + if (nanoString.length() > 9) { + nanoString = nanoString.substring(0, 9); + } + // Parse the fractional seconds. + nanoseconds = Integer.parseInt(nanoString); + + // Remove the fractional seconds from the string. + value = value.substring(0, dotIndex) + + value.substring(secondsEnd, value.length()); + } + + // this is the code that may trow a ParseException + if (hasTimeZone) { + // Strip off the purported time zone and make sure what's + // left is a valid unzoned date and time (by parsing in GMT). + // If so, reformat the time zone by stripping out the colon + // and parse the revised string with the timezone parser. + + len = value.length(); + + Date gmtValue = strictParse(zoneParser, + value.substring(0,len-6) + "+0000"); + value = value.substring(0, len-3) + + value.substring(len-2, len); + dateValue = strictParse(zoneParser, value); + timeZone = + (int) (gmtValue.getTime() - dateValue.getTime()); + timeZone = timeZone / 60000; + defaultedTimeZone = timeZone; + } else { + // No funny business. This must be a simple date and time. + dateValue = strictParse(simpleParser, value); + timeZone = TZ_UNSPECIFIED; + // Figure out what time zone was used. + Date gmtValue = strictParse(zoneParser, value + "+0000"); + defaultedTimeZone = + (int) (gmtValue.getTime() - dateValue.getTime()); + defaultedTimeZone = defaultedTimeZone / 60000; + } + + // If parsing went OK, create a new DateTimeAttribute object and + // return it. + + DateTimeAttribute attr = new DateTimeAttribute(dateValue, nanoseconds, + timeZone, + defaultedTimeZone); + return attr; + } + + /** + * Parse a String using a DateFormat parser, requiring that + * the entire String be consumed by the parser. On success, + * return a Date. On failure, throw a ParseException. + *

+ * Synchronize on the parser object when using it, since we + * assume they're the shared static objects in this class. + */ + private static Date strictParse(DateFormat parser, String str) + throws ParseException { + ParsePosition pos = new ParsePosition(0); + Date ret; + synchronized (parser) { + ret = parser.parse(str, pos); + } + if (pos.getIndex() != str.length()) { + throw new ParseException("", 0); + } + return ret; + } + + /** + * Initialize the parser objects. + */ + private void initParsers() { + // If simpleParser is already set, we're done. + if (this.simpleParser != null) { + return; + } + + // Make sure that identifierURI is not null + if (earlyException != null) { + throw earlyException; + } + + // Synchronize on identifierURI while initializing parsers + // so we don't end up using a half-way initialized parser + synchronized (identifierURI) { + // This simple parser has no time zone + this.simpleParser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); + this.simpleParser.setLenient(false); + + // This parser has a four digit offset to GMT with sign + this.zoneParser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ"); + //FIXME: temporarily we need to set this to true + // this is a problem with Java 1.5, if you now + // of good documentation about the differnces between SimpleDateFormat + // in 1.4 and 1.5 let me (ludwig) know. + this.zoneParser.setLenient(true); + } + } + + /** + * Gets the date and time represented by this object. The return + * value is a Date object representing the + * specified date and time down to second resolution. + * Subsecond values are handled by the + * {@link #getNanoseconds getNanoseconds} method. + *

+ * NOTE: The Date object is cloned before it + * is returned to avoid unauthorized changes. + * + * @return a Date object representing the date and + * time represented by this object + */ + public Date getValue() { + return (Date) this.value.clone(); + } + + /** + * Gets the nanoseconds of this object. + * + * @return the number of nanoseconds + */ + public int getNanoseconds() { + return this.nanoseconds; + } + + /** + * Gets the time zone of this object (or TZ_UNSPECIFIED if + * unspecified). + * + * @return the offset to GMT in minutes (positive or negative) + */ + public int getTimeZone() { + return this.timeZone; + } + + /** + * Gets the time zone actually used for this object (if it was + * originally unspecified, the default time zone used). + * + * @return the offset to GMT in minutes (positive or negative) + */ + public int getDefaultedTimeZone() { + return this.defaultedTimeZone; + } + + /** + * Returns true if the input is an instance of this class and if its + * value equals the value contained in this class. + *

+ * Two DateTimeAttributes are equal if and only if the + * dates and times represented are identical (down to the nanosecond). + * + * @param o the object to compare + * + * @return true if this object and the input represent the same value + */ + public boolean equals(Object o) { + if (! (o instanceof DateTimeAttribute)) { + return false; + } + + DateTimeAttribute other = (DateTimeAttribute)o; + + // Since the value field is normalized into GMT, this is a + // good way to compare. + return (this.value.equals(other.value) && + (this.nanoseconds == other.nanoseconds)); + } + + /** + * Returns the hashcode value used to index and compare this object with + * others of the same type. + * + * @return the object's hashcode value + */ + public int hashCode() { + // Both the value field and the nanoseconds field are considered + // by the equals method, so it's best if the hashCode is derived + // from both of those fields. + int hashCode = this.value.hashCode(); + hashCode = 31*hashCode + this.nanoseconds; + return hashCode; + } + + /** + * Converts to a String representation. + * + * @return the String representation + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + + sb.append("DateTimeAttribute: [" + Constants.nl); + sb.append(" Date: " + this.value + " local time"); + sb.append(" Nanoseconds: " + this.nanoseconds); + sb.append(" TimeZone: " + this.timeZone); + sb.append(" Defaulted TimeZone: " + this.defaultedTimeZone); + sb.append("]"); + + return sb.toString(); + } + + /** + * Encodes the value in a form suitable for including in XML data like + * a request or an obligation. This must return a value that could in + * turn be used by the factory to create a new instance with the same + * value. + * + * @return a String form of the value + */ + public String encode() { + if (this.encodedValue != null) { + return this.encodedValue; + } + + if (this.timeZone == TZ_UNSPECIFIED) { + // If no time zone was specified, format Date value in + // local time with no time zone string. + initParsers(); + synchronized (this.simpleParser) { + this.encodedValue = this.simpleParser.format(this.value); + } + if (this.nanoseconds != 0) { + this.encodedValue = this.encodedValue + "." + + DateAttribute.zeroPadInt(this.nanoseconds, 9); + } + } else { + // If a time zone was specified, don't use SimpleParser + // because it can only format dates in the local (default) + // time zone. And the offset between that time zone and the + // time zone we need to display can vary in complicated ways. + + // Instead, do it ourselves using our formatDateWithTZ method. + this.encodedValue = formatDateTimeWithTZ(); + } + return this.encodedValue; + } + + /** + * Encodes the value of this object as an xsi:dateTime. + * Only for use when the time zone is specified. + * + * @return a String form of the value + */ + private String formatDateTimeWithTZ() { + if (this.gmtCalendar == null) { + TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT"); + + // Locale doesn't make much difference here. We don't use + // any of the strings in the Locale and we don't do anything + // that depends on week count conventions. We use the US + // locale because it's always around and it ensures that we + // will always get a Gregorian calendar, which is necessary + // for compliance with ISO 8501. + this.gmtCalendar = Calendar.getInstance(gmtTimeZone, Locale.US); + } + + // "YYYY-MM-DDThh:mm:ss.sssssssss+hh:mm".length() = 35 + // Length may be longer if years < -999 or > 9999 + StringBuffer buf = new StringBuffer(35); + + // Start with the proper time in GMT. + this.gmtCalendar.setTime(this.value); + // Bump by the timeZone, since we're going to be extracting + // the value in GMT + this.gmtCalendar.add(Calendar.MINUTE, this.timeZone); + + // Now, assemble the string + int year = this.gmtCalendar.get(Calendar.YEAR); + buf.append(DateAttribute.zeroPadInt(year, 4)); + buf.append('-'); + // JANUARY is 0 + int month = this.gmtCalendar.get(Calendar.MONTH) + 1; + buf.append(DateAttribute.zeroPadInt(month, 2)); + buf.append('-'); + int dom = this.gmtCalendar.get(Calendar.DAY_OF_MONTH); + buf.append(DateAttribute.zeroPadInt(dom, 2)); + buf.append('T'); + int hour = this.gmtCalendar.get(Calendar.HOUR_OF_DAY); + buf.append(DateAttribute.zeroPadInt(hour, 2)); + buf.append(':'); + int minute = this.gmtCalendar.get(Calendar.MINUTE); + buf.append(DateAttribute.zeroPadInt(minute, 2)); + buf.append(':'); + int second = this.gmtCalendar.get(Calendar.SECOND); + buf.append(DateAttribute.zeroPadInt(second, 2)); + + if (this.nanoseconds != 0) { + buf.append('.'); + buf.append(DateAttribute.zeroPadInt(this.nanoseconds, 9)); + } + + int tzNoSign = this.timeZone; + if (this.timeZone < 0) { + tzNoSign = -tzNoSign; + buf.append('-'); + } else { + buf.append('+'); + } + int tzHours = tzNoSign / 60; + buf.append(DateAttribute.zeroPadInt(tzHours, 2)); + buf.append(':'); + int tzMinutes = tzNoSign % 60; + buf.append(DateAttribute.zeroPadInt(tzMinutes, 2)); + + return buf.toString(); + } + + /** + * Gets the offset in minutes between the default time zone and + * UTC for the specified date. + * + * @param date the Date whose offset is desired + * + * @return the offset in minutes + */ + static int getDefaultTZOffset(Date date) { + int offset = TimeZone.getDefault().getOffset(date.getTime()); + offset = offset / DateAttribute.MILLIS_PER_MINUTE; + return offset; + } + + /** + * Combines a number of nanoseconds with a Date + * so that the Date has no fractional seconds and the number + * of nanoseconds is non-negative and less than a second. + *

+ * WARNING: This function changes the value stored in + * the date parameter! + * + * @param date the Date to be combined + * (value may be modified!) + * @param nanoseconds the nanoseconds to be combined + * + * @return the resulting number of nanoseconds + */ + static int combineNanos(Date date, int nanoseconds) { + long millis = date.getTime(); + int milliCarry = (int) (millis % DateAttribute.MILLIS_PER_SECOND); + + // If nothing needs fixing, get out quick + if ((milliCarry == 0) && (nanoseconds > 0) + && (nanoseconds < DateAttribute.NANOS_PER_SECOND)) { + return nanoseconds; + } + + // Remove any non-zero milliseconds from the date. + millis -= milliCarry; + // Add them into the nanoseconds. + long nanoTemp = nanoseconds; + // Multiplication with 1L to avoid overflows in the + // integer multiplication, since it's converted to long anyway + nanoTemp += 1L * milliCarry * DateAttribute.NANOS_PER_MILLI; + // Get the nanoseconds that represent fractional seconds. + // This we'll return. + int nanoResult = (int) (nanoTemp % DateAttribute.NANOS_PER_SECOND); + // Get nanoseconds that represent whole seconds. + nanoTemp -= nanoResult; + // Convert that to milliseconds and add it back to the date. + millis += nanoTemp / DateAttribute.NANOS_PER_MILLI; + date.setTime(millis); + + return nanoResult; + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DayTimeDurationAttribute.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DayTimeDurationAttribute.java new file mode 100644 index 0000000..ea952d9 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DayTimeDurationAttribute.java @@ -0,0 +1,585 @@ + +/* + * @(#)DayTimeDurationAttribute.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.attr; + +import com.sun.xacml.Constants; +import com.sun.xacml.ParsingException; + +import java.math.BigInteger; + +import java.net.URI; + +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; +import java.util.regex.Matcher; + +import org.w3c.dom.Node; + + +/** + * Representation of an xf:dayTimeDuration value. This class supports parsing + * xd:dayTimeDuration values. All objects of this class are immutable and + * thread-safe. The Date objects returned are not, but + * these objects are cloned before being returned. + * + * @since 1.0 + * @author Steve Hanna + */ +public class DayTimeDurationAttribute extends AttributeValue +{ + /** + * Official name of this type + */ + public static final String identifier = + TypeIdentifierConstants.DAYTIMEDURATION; + + /** + * URI version of name for this type + *

+ * This field is initialized by a static initializer so that + * we can catch any exceptions thrown by URI(String) and + * transform them into a RuntimeException, since this should + * never happen but should be reported properly if it ever does. + */ + private static URI identifierURI; + + /** + * RuntimeException that wraps an Exception thrown during the + * creation of identifierURI, null if none. + */ + private static RuntimeException earlyException; + + /** + * Static initializer that initializes the identifierURI + * class field so that we can catch any exceptions thrown + * by URI(String) and transform them into a RuntimeException. + * Such exceptions should never happen but should be reported + * properly if they ever do. + */ + static { + try { + identifierURI = URI.create(identifier); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * Regular expression for dayTimeDuration (a la java.util.regex) + */ + private static final String patternString = + "(\\-)?P((\\d+)?D)?(T((\\d+)?H)?((\\d+)?M)?((\\d+)?(.(\\d+)?)?S)?)?"; + + /** + * The index of the capturing group for the negative sign. + */ + private static final int GROUP_SIGN = 1; + + /** + * The index of the capturing group for the number of days. + */ + private static final int GROUP_DAYS = 3; + + /** + * The index of the capturing group for the number of hours. + */ + private static final int GROUP_HOURS = 6; + + /** + * The index of the capturing group for the number of minutes. + */ + private static final int GROUP_MINUTES = 8; + + /** + * The index of the capturing group for the number of seconds. + */ + private static final int GROUP_SECONDS = 10; + + /** + * The index of the capturing group for the number of nanoseconds. + */ + private static final int GROUP_NANOSECONDS = 12; + + /** + * Static BigInteger values. We only use these if one of + * the components is bigger than Integer.MAX_LONG and we + * want to detect overflow. + */ + private static BigInteger big24 = BigInteger.valueOf(24); + private static BigInteger big60 = BigInteger.valueOf(60); + private static BigInteger big1000 = BigInteger.valueOf(1000); + private static BigInteger bigMaxLong = BigInteger.valueOf(Long.MAX_VALUE); + + /** + * A shared Pattern object, only initialized if needed + */ + private static Pattern pattern; + + /** + * Negative flag. true if duration is negative, false otherwise + */ + private boolean negative; + + /** + * Number of days + */ + private long days; + + /** + * Number of hours + */ + private long hours; + + /** + * Number of minutes + */ + private long minutes; + + /** + * Number of seconds + */ + private long seconds; + + /** + * Number of nanoseconds + */ + private int nanoseconds; + + /** + * Total number of round seconds (in milliseconds) + */ + private long totalMillis; + + /** + * Cached encoded value (null if not cached yet). + */ + private String encodedValue = null; + + /** + * Creates a new DayTimeDurationAttribute that represents + * the duration supplied. + * + * @param negative true if the duration is negative, false otherwise + * @param days the number of days in the duration + * @param hours the number of hours in the duration + * @param minutes the number of minutes in the duration + * @param seconds the number of seconds in the duration + * @param nanoseconds the number of nanoseconds in the duration + * @throws IllegalArgumentException if the total number of milliseconds + * exceeds Long.MAX_LONG + */ + public DayTimeDurationAttribute(boolean negative, long days, long hours, + long minutes, long seconds, + int nanoseconds) + throws IllegalArgumentException { + super(identifierURI); + + // Shouldn't happen, but just in case... + if (earlyException != null) { + throw earlyException; + } + this.negative = negative; + this.days = days; + this.hours = hours; + this.minutes = minutes; + this.seconds = seconds; + this.nanoseconds = nanoseconds; + + // Convert all the components except nanoseconds to milliseconds + + // If any of the components is big (too big to be an int), + // use the BigInteger class to do the math so we can detect + // overflow. + if ((days > Integer.MAX_VALUE) || (hours > Integer.MAX_VALUE) || + (minutes > Integer.MAX_VALUE) || (seconds > Integer.MAX_VALUE)) { + + BigInteger bigDays = BigInteger.valueOf(days); + BigInteger bigHours = BigInteger.valueOf(hours); + BigInteger bigMinutes = BigInteger.valueOf(minutes); + BigInteger bigSeconds = BigInteger.valueOf(seconds); + + BigInteger bigTotal = bigDays.multiply(big24).add(bigHours) + .multiply(big60).add(bigMinutes).multiply(big60) + .add(bigSeconds).multiply(big1000); + + // If the result is bigger than Long.MAX_VALUE, we have an + // overflow. Indicate an error (should be a processing error, + // since it can be argued that we should handle gigantic + // values for this). + if (bigTotal.compareTo(bigMaxLong) == 1) { + throw new IllegalArgumentException("total number of " + + "milliseconds " + + "exceeds Long.MAX_VALUE"); + } + // If no overflow, convert to a long. + this.totalMillis = bigTotal.longValue(); + } else { + // The numbers are small, so do it the fast way. + this.totalMillis = ((((((days * 24) + hours) * 60) + minutes) * 60) + + seconds) * 1000; + } + } + + /** + * Returns a new DayTimeDurationAttribute that represents + * the xf:dayTimeDuration at a particular DOM node. + * + * @param root the Node that contains the desired value + * @return a new DayTimeDurationAttribute representing the + * appropriate value (null if there is a parsing error) + * + * @throws ParsingException + * @throws NumberFormatException + */ + public static DayTimeDurationAttribute getInstance(Node root) + throws ParsingException, NumberFormatException { + if (root.getFirstChild() != null) { + return getInstance(root.getFirstChild().getNodeValue()); + } + throw new ParsingException("Error while parsing" + + "a DayTimeDurationAttribute"); + } + + /** + * Returns the long value for the capturing group groupNumber. + * This method takes a Matcher that has been used to match a + * Pattern against a String, fetches the value for the specified + * capturing group, converts that value to an long, and returns + * the value. If that group did not match, 0 is returned. + * If the matched value is not a valid long, NumberFormatException + * is thrown. + * + * @param matcher the Matcher from which to fetch the group + * @param groupNumber the group number to fetch + * @return the long value for that groupNumber + * @throws NumberFormatException if the string value for that + * groupNumber is not a valid long + */ + private static long parseGroup(Matcher matcher, int groupNumber) + throws NumberFormatException { + long groupLong = 0; + + if (matcher.start(groupNumber) != -1) { + String groupString = matcher.group(groupNumber); + groupLong = Long.parseLong(groupString); + } + return groupLong; + } + + /** + * Returns a new DayTimeDurationAttribute that represents + * the xf:dayTimeDuration value indicated by the string provided. + * + * @param value a string representing the desired value + * @return a new DayTimeDurationAttribute representing the + * desired value (null if there is a parsing error) + * + * @throws ParsingException + * @throws NumberFormatException + */ + public static DayTimeDurationAttribute getInstance(String value) + throws ParsingException, NumberFormatException { + if (value == null) { + throw new ParsingException("Can't create a " + + "DayTimeDurationAttribute from null input"); + } + boolean negative = false; + long days = 0; + long hours = 0; + long minutes = 0; + long seconds = 0; + int nanoseconds = 0; + + // Compile the pattern, if not already done. + // No thread-safety problem here. The worst that can + // happen is that we initialize pattern several times. + if (pattern == null) { + try { + pattern = Pattern.compile(patternString); + } catch (PatternSyntaxException e) { + // This should never happen + throw new ParsingException("unexpected pattern match error"); + } + } + + // See if the value matches the pattern. + Matcher matcher = pattern.matcher(value); + boolean matches = matcher.matches(); + + // If not, syntax error! + if (!matches) { + throw new ParsingException("Syntax error in dayTimeDuration"); + } + + // If the negative group matched, the value is negative. + if (matcher.start(GROUP_SIGN) != -1) { + negative = true; + } + + try { + // If the days group matched, parse that value. + days = parseGroup(matcher, GROUP_DAYS); + + // If the hours group matched, parse that value. + hours = parseGroup(matcher, GROUP_HOURS); + + // If the minutes group matched, parse that value. + minutes = parseGroup(matcher, GROUP_MINUTES); + + // If the seconds group matched, parse that value. + seconds = parseGroup(matcher, GROUP_SECONDS); + + // Special handling for fractional seconds, since + // they can have any resolution. + if (matcher.start(GROUP_NANOSECONDS) != -1) { + String nanosecondString = matcher.group(GROUP_NANOSECONDS); + + // If there are less than 9 digits in the fractional seconds, + // pad with zeros on the right so it's nanoseconds. + while (nanosecondString.length() < 9) { + nanosecondString += "0"; + } + + // If there are more than 9 digits in the fractional seconds, + // drop the least significant digits. + if (nanosecondString.length() > 9) { + nanosecondString = nanosecondString.substring(0, 9); + } + + nanoseconds = Integer.parseInt(nanosecondString); + } + } catch (NumberFormatException e) { + // If we run into a number that's too big to be a long + // that's an error. Really, it's a processing error, + // since one can argue that we should handle that. + throw e; + } + + // Here's a requirement that's not checked for in the pattern. + // The designator 'T' must be absent if all the time + // items are absent. So the string can't end in 'T'. + // Note that we don't have to worry about a zero length + // string, since the pattern won't allow that. + if (value.charAt(value.length()-1) == 'T') { + throw new ParsingException("'T' must be absent if all" + + "time items are absent"); + } + // If parsing went OK, create a new DayTimeDurationAttribute object and + // return it. + return new DayTimeDurationAttribute(negative, days, hours, minutes, + seconds, nanoseconds); + } + + /** + * Returns true if the duration is negative. + * + * @return true if the duration is negative, false otherwise + */ + public boolean isNegative() { + return this.negative; + } + + /** + * Gets the number of days. + * + * @return the number of days + */ + public long getDays() { + return this.days; + } + + /** + * Gets the number of hours. + * + * @return the number of hours + */ + public long getHours() { + return this.hours; + } + + /** + * Gets the number of minutes. + * + * @return the number of minutes + */ + public long getMinutes() { + return this.minutes; + } + + /** + * Gets the number of seconds. + * + * @return the number of seconds + */ + public long getSeconds() { + return this.seconds; + } + + /** + * Gets the number of nanoseconds. + * + * @return the number of nanoseconds + */ + public int getNanoseconds() { + return this.nanoseconds; + } + + /** + * Gets the total number of round seconds (in milliseconds). + * + * @return the total number of seconds (in milliseconds) + */ + public long getTotalSeconds() { + return this.totalMillis; + } + + /** + * Returns true if the input is an instance of this class and if its + * value equals the value contained in this class. + * + * @param o the object to compare + * + * @return true if this object and the input represent the same value + */ + public boolean equals(Object o) { + if (! (o instanceof DayTimeDurationAttribute)) { + return false; + } + + DayTimeDurationAttribute other = (DayTimeDurationAttribute)o; + + return ((this.totalMillis == other.totalMillis) && + (this.nanoseconds == other.nanoseconds) && + (this.negative == other.negative)); + } + + /** + * Returns the hashcode value used to index and compare this object with + * others of the same type. Typically this is the hashcode of the backing + * data object. + * + * @return the object's hashcode value + */ + public int hashCode() { + // The totalMillis, nanoseconds, and negative fields are all considered + // by the equals method, so it's best if the hashCode is derived + // from all of those fields. + int hashCode = (int) this.totalMillis ^ (int) (this.totalMillis >> 32); + hashCode = 31*hashCode + this.nanoseconds; + if (this.negative) { + hashCode = -hashCode; + } + return hashCode; + } + + /** + * Converts to a String representation. + * + * @return the String representation + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + + sb.append("DayTimeDurationAttribute: [" + Constants.nl); + sb.append(" Negative: " + this.negative); + sb.append(" Days: " + this.days); + sb.append(" Hours: " + this.hours); + sb.append(" Minutes: " + this.minutes); + sb.append(" Seconds: " + this.seconds); + sb.append(" Nanoseconds: " + this.nanoseconds); + sb.append(" TotalSeconds: " + this.totalMillis); + sb.append("]"); + + return sb.toString(); + } + + /** + * Encodes the value in a form suitable for including in XML data like + * a request or an obligation. This must return a value that could in + * turn be used by the factory to create a new instance with the same + * value. + * + * @return a String form of the value + */ + public String encode() { + if (this.encodedValue != null) { + return this.encodedValue; + } + + // Length is quite variable + StringBuffer buf = new StringBuffer(10); + + if (this.negative) { + buf.append('-'); + } + buf.append('P'); + if (this.days != 0) { + buf.append(Long.toString(this.days)); + buf.append('D'); + } + if ((this.hours != 0) || (this.minutes != 0) + || (this.seconds != 0) || (this.nanoseconds != 0)) { + // Only include the T if there are some time fields + buf.append('T'); + } else { + // Make sure that there's always at least one field specified + if (this.days == 0) { + buf.append("0D"); + } + } + if (this.hours != 0) { + buf.append(Long.toString(this.hours)); + buf.append('H'); + } + if (this.minutes != 0) { + buf.append(Long.toString(this.minutes)); + buf.append('M'); + } + if ((this.seconds != 0) || (this.nanoseconds != 0)) { + buf.append(Long.toString(this.seconds)); + if (this.nanoseconds != 0) { + buf.append('.'); + buf.append(DateAttribute.zeroPadInt(this.nanoseconds, 9)); + } + buf.append('S'); + } + + this.encodedValue = buf.toString(); + + return this.encodedValue; + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DecisionAttribute.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DecisionAttribute.java new file mode 100644 index 0000000..ba404c7 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DecisionAttribute.java @@ -0,0 +1,99 @@ + +/* + * @(#)DecisionAttribute.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.attr; + +import java.net.URI; + +import com.sun.xacml.ctx.Attribute; +import com.sun.xacml.ctx.Result; + +/** + * Convenience class that represents the Decision attribute. + * + * @author Ludwig Seitz + * + */ +public class DecisionAttribute extends Attribute { + + + /** + * The static id URI of the Decision attribute + */ + private static URI idURI; + + /** + * RuntimeException that wraps an Exception thrown during the + * creation of idURI, null if none. + */ + private static RuntimeException earlyException; + + /** + * Static initializer that initializes the identifierURI + * class field so that we can catch any exceptions thrown + * by URI(String) and transform them into a RuntimeException. + * Such exceptions should never happen but should be reported + * properly if they ever do. + */ + static { + try { + idURI = URI.create(TypeIdentifierConstants.DECISION); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * Constructor that creates a Decision Attribute. + * + * @param decision The decision code from the Result class. + */ + public DecisionAttribute(int decision) { + super(DecisionAttribute.idURI, null, + new StringAttribute((String)Result.DECISIONS.get(decision))); + if (earlyException != null) { + throw earlyException; + } + if (decision != Result.DECISION_DENY + && decision != Result.DECISION_PERMIT) { + throw new IllegalArgumentException("Decision attribute value must" + + " be 'PERMIT' or 'DENY'"); + + } + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DoubleAttribute.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DoubleAttribute.java new file mode 100644 index 0000000..ca9e595 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/DoubleAttribute.java @@ -0,0 +1,218 @@ + +/* + * @(#)DoubleAttribute.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.attr; + +import java.net.URI; + +import org.w3c.dom.Node; + +import com.sun.xacml.ParsingException; + + +/** + * Representation of an xsi:double value. This class supports parsing + * xsi:double values. All objects of this class are immutable and + * all methods of the class are thread-safe. + * + * @since 1.0 + * @author Marco Barreno + * @author Seth Proctor + * @author Steve Hanna + */ +public class DoubleAttribute extends AttributeValue +{ + /** + * Official name of this type + */ + public static final String identifier = + TypeIdentifierConstants.DOUBLE; + + /** + * URI version of name for this type + *

+ * This field is initialized by a static initializer so that + * we can catch any exceptions thrown by URI(String) and + * transform them into a RuntimeException, since this should + * never happen but should be reported properly if it ever does. + */ + private static URI identifierURI; + + /** + * RuntimeException that wraps an Exception thrown during the + * creation of identifierURI, null if none. + */ + private static RuntimeException earlyException; + + /** + * Static initializer that initializes the identifierURI + * class field so that we can catch any exceptions thrown + * by URI(String) and transform them into a RuntimeException. + * Such exceptions should never happen but should be reported + * properly if they ever do. + */ + static { + try { + identifierURI = URI.create(identifier); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * The actual double value that this object represents. + */ + private double value; + + /** + * Creates a new DoubleAttribute that represents + * the double value supplied. + * + * @param value the double value to be represented + */ + public DoubleAttribute(double value) { + super(identifierURI); + + // Shouldn't happen, but just in case... + if (earlyException != null) { + throw earlyException; + } + this.value = value; + } + + /** + * Returns a new DoubleAttribute that represents + * the xsi:double at a particular DOM node. + * + * @param root the Node that contains the desired value + * @return a new DoubleAttribute representing the + * appropriate value (null if there is a parsing error) + * @throws NumberFormatException if the string form is not a double + * @throws ParsingException + */ + public static DoubleAttribute getInstance(Node root) + throws NumberFormatException, ParsingException { + if (root.getFirstChild() != null) { + return getInstance(root.getFirstChild().getNodeValue()); + } + throw new ParsingException("Error while parsing" + + "a DoubleAttribute"); + } + + /** + * Returns a new DoubleAttribute that represents + * the xsi:double value indicated by the string provided. + * + * @param value a string representing the desired value + * @return a new DoubleAttribute representing the + * desired value (null if there is a parsing error) + * @throws ParsingException + * @throws NumberFormatException if the value is not a double + */ + public static DoubleAttribute getInstance(String value) + throws ParsingException { + if (value == null) { + throw new ParsingException("Can't create a " + + "DoubleAttribute from null input"); + } + // Convert "INF" to "Infinity" + if (value.endsWith("INF")) { + int infIndex = value.lastIndexOf("INF"); + value = value.substring(0, infIndex) + "Infinity"; + } + + return new DoubleAttribute(Double.parseDouble(value)); + } + + /** + * Returns the double value represented by this object. + * + * @return the double value + */ + public double getValue() { + return this.value; + } + + /** + * Returns true if the input is an instance of this class and if its + * value equals the value contained in this class. + * + * @param o the object to compare + * + * @return true if this object and the input represent the same value + */ + public boolean equals(Object o) { + if (! (o instanceof DoubleAttribute)) { + return false; + } + + DoubleAttribute other = (DoubleAttribute)o; + + // Handle the NaN case, where Java says NaNs are never + // equal and XML Query says they always are + if (Double.isNaN(this.value)) { + // this is a NaN, so see if the other is as well + if (Double.isNaN(other.value)) { + // they're both NaNs, so they're equal + return true; + } + // they're not both NaNs, so they're not equal + return false; + } + // not NaNs, so we can do a normal comparison + return (this.value == other.value); + } + + /** + * Returns the hashcode value used to index and compare this object with + * others of the same type. Typically this is the hashcode of the backing + * data object. + * + * @return the object's hashcode value + */ + public int hashCode() { + long v = Double.doubleToLongBits(this.value); + return (int)(v ^ (v >>> 32)); + } + + /** + * @return The String encoding this AttributeValue. + */ + public String encode() { + return String.valueOf(this.value); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/HexBinaryAttribute.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/HexBinaryAttribute.java new file mode 100644 index 0000000..9e6bd79 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/HexBinaryAttribute.java @@ -0,0 +1,326 @@ + +/* + * @(#)HexBinaryAttribute.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.attr; + +import com.sun.xacml.Constants; +import com.sun.xacml.ParsingException; + +import java.net.URI; + +import java.util.Arrays; + +import org.w3c.dom.Node; + + +/** + * Representation of an xsi:hexBinary value. This class supports parsing + * xsi:hexBinary values. All objects of this class are immutable and + * all methods of the class are thread-safe. + * + * @since 1.0 + * @author Steve Hanna + */ +public class HexBinaryAttribute extends AttributeValue +{ + /** + * Official name of this type + */ + public static final String identifier = + TypeIdentifierConstants.HEXBINARY; + + /** + * URI version of name for this type + *

+ * This field is initialized by a static initializer so that + * we can catch any exceptions thrown by URI(String) and + * transform them into a RuntimeException, since this should + * never happen but should be reported properly if it ever does. + */ + private static URI identifierURI; + + /** + * RuntimeException that wraps an Exception thrown during the + * creation of identifierURI, null if none. + */ + private static RuntimeException earlyException; + + /** + * Static initializer that initializes the identifierURI + * class field so that we can catch any exceptions thrown + * by URI(String) and transform them into a RuntimeException. + * Such exceptions should never happen but should be reported + * properly if they ever do. + */ + static { + try { + identifierURI = URI.create(identifier); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * The actual binary value that this object represents. + */ + private byte [] value; + + /** + * The value returned by toString(). Cached, but only + * generated if needed. + */ + private String strValue; + + /** + * Creates a new HexBinaryAttribute that represents + * the byte [] value supplied. + * + * @param value the byte [] value to be represented + */ + public HexBinaryAttribute(byte [] value) { + super(identifierURI); + + // Shouldn't happen, but just in case... + if (earlyException != null) { + throw earlyException; + } + // This will throw a NullPointerException if value == null. + // That's what we want in that case. + this.value = (byte[])value.clone(); + } + + /** + * Returns a new HexBinaryAttribute that represents + * the xsi:hexBinary at a particular DOM node. + * + * @param root the Node that contains the desired value + * @return a new HexBinaryAttribute representing the + * appropriate value + * @exception ParsingException if a parsing error occurs + */ + public static HexBinaryAttribute getInstance(Node root) + throws ParsingException { + if (root.getFirstChild() != null) { + return getInstance(root.getFirstChild().getNodeValue()); + } + throw new ParsingException("Error while parsing" + + "a HexBinaryAttribute"); + } + + /** + * Returns a new HexBinaryAttribute that represents + * the xsi:hexBinary value indicated by the string provided. + * + * @param value a string representing the desired value + * @return a new HexBinaryAttribute representing the + * desired value + * @exception ParsingException if a parsing error occurs + */ + public static HexBinaryAttribute getInstance(String value) + throws ParsingException { + if (value == null) { + throw new ParsingException("Can't create a " + + "HexBinaryAttribute from null input"); + } + byte [] bytes = hexToBin(value); + + if (bytes == null) { + throw new ParsingException("Couldn't parse purported " + + "hex string: " + value); + } + return new HexBinaryAttribute(bytes); + } + + /** + * Returns the byte [] value represented by this object. + * Note that this value is cloned before returning to prevent + * unauthorized modifications. + * + * @return the byte [] value + */ + public byte [] getValue() { + return (byte[])this.value.clone(); + } + + /** + * Returns the hashcode value used to index and compare this object with + * others of the same type. Typically this is the hashcode of the backing + * data object. + * + * @return the object's hashcode value + */ + public int hashCode() { + int code = this.value[0]; + + for (int i = 1; i < this.value.length; i++) { + code *= 31; + code += this.value[i]; + } + + return code; + } + + /** + * Returns true if the input is an instance of this class and if its + * value equals the value contained in this class. + * + * @param o the object to compare + * + * @return true if this object and the input represent the same value + */ + public boolean equals(Object o) { + if (! (o instanceof HexBinaryAttribute)) { + return false; + } + HexBinaryAttribute other = (HexBinaryAttribute)o; + + return Arrays.equals(this.value, other.value); + } + + /** + * Return the int value of a hex character. Return -1 if the + * character is not a valid hex character. + */ + private static int hexToBinNibble(char c) { + int result = -1; + + if ((c >= '0') && (c <= '9')) { + result = (c - '0'); + } else { + if ((c >= 'a') && (c <= 'f')) { + result = (c - 'a') + 10; + } else { + if ((c >= 'A') && (c <= 'F')) { + result = (c - 'A') + 10; + } + // else pick up the -1 value set above + } + } + return result; + } + + /** + * Parse a hex string, returning a new byte array containing the + * value. Return null in case of a parsing error. + * + * @param hex the hex string + * @return a new byte array containing the value (or null) + */ + private static byte [] hexToBin(String hex) { + int len = hex.length(); + // Must have an even number of hex digits + if (len % 2 != 0) { + return null; + } + int byteCount = len / 2; + byte [] bytes = new byte [byteCount]; + + int charIndex = 0; + for (int byteIndex = 0; byteIndex < byteCount; byteIndex++) { + int hiNibble = hexToBinNibble(hex.charAt(charIndex++)); + int loNibble = hexToBinNibble(hex.charAt(charIndex++)); + if ((hiNibble < 0) || (loNibble < 0)) { + return null; + } + bytes[byteIndex] = (byte) (hiNibble * 16 + loNibble); + } + return bytes; + } + + /** + * Return the hex character for a particular nibble (half a byte). + * + * @param nibble a value 0-15 + * @return hex character for that nibble (using A-F for 10-15) + */ + private static char binToHexNibble(int nibble) { + char result = (char) 0; + + if (nibble < 10) { + result = (char) (nibble + '0'); + } else { + result = (char) ((nibble - 10) + 'A'); + } + return result; + } + + /** + * Return a straight hexadecimal conversion of a byte array. + * This is a String containing only hex digits. + * + * @param bytes the byte array + * @return the hex version + */ + private static String binToHex(byte [] bytes) { + int byteLength = bytes.length; + char [] chars = new char [byteLength * 2]; + int charIndex = 0; + + for (int byteIndex = 0; byteIndex < byteLength; byteIndex++) { + byte b = bytes[byteIndex]; + chars[charIndex++] = binToHexNibble((b >> 4) & 0xf); + chars[charIndex++] = binToHexNibble(b & 0xf); + } + + return new String(chars); + } + + /** + * Returns a String representation. + * + * @return the String representation + */ + public String toString() { + if (this.strValue == null) { + this.strValue = binToHex(this.value); + } + + return "HexBinaryAttribute: [" + Constants.nl + + this.strValue + "]" + Constants.nl; + } + + /** + * @return The String encoding this AttributeValue. + */ + public String encode() { + if (this.strValue == null) { + this.strValue = binToHex(this.value); + } + + return this.strValue; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/IPAddressAttribute.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/IPAddressAttribute.java new file mode 100644 index 0000000..cb44cf2 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/IPAddressAttribute.java @@ -0,0 +1,269 @@ + +/* + * @(#)IPAddressAttribute.java + * + * Copyright 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.attr; + +import com.sun.xacml.ParsingException; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.net.URI; + +import org.w3c.dom.Node; + + +/** + * Represents the IPAddress datatype introduced in XACML 2.0. All objects of + * this class are immutable and all methods of the class are thread-safe. + *

+ * To create an instance of an ipAddress from an encoded String or a DOM + * Node you should use the getInstance methods provided by + * this class. To construct an ipAddress instance directly, you must use + * the constructors provided by IPv4AddressAttribute and + * IPv6AddressAttribute. These will both create an attribute + * of XACML type ipAddress, but will handle the differences in these + * two representations correctly. + * + * @since 2.0 + * @author Seth Proctor + */ +public abstract class IPAddressAttribute extends AttributeValue +{ + + /** + * Official name of this type + */ + public static final String identifier = + TypeIdentifierConstants.IPADDRESS; + + /** + * URI version of name for this type + *

+ * This field is initialized by a static initializer so that + * we can catch any exceptions thrown by URI(String) and + * transform them into a RuntimeException, since this should + * never happen but should be reported properly if it ever does. + */ + private static URI identifierURI; + + /** + * RuntimeException that wraps an Exception thrown during the + * creation of identifierURI, null if none. + */ + private static RuntimeException earlyException; + + /** + * Static initializer that initializes the identifierURI + * class field so that we can catch any exceptions thrown + * by URI(String) and transform them into a RuntimeException. + * Such exceptions should never happen but should be reported + * properly if they ever do. + */ + static { + try { + identifierURI = new URI(identifier); + } catch (Exception e) { + earlyException = new IllegalArgumentException(); + earlyException.initCause(e); + } + } + + // the required address + private InetAddress address; + + // the optional mask + private InetAddress mask; + + // this is the optional port-range + private PortRange range; + + /** + * Creates the new IPAddressAttribute with all the optional + * components. + * + * @param address a non-null InetAddress + * @param mask an InetAddress or null if there is no mask + * @param range a non-null PortRange + */ + protected IPAddressAttribute(InetAddress address, InetAddress mask, + PortRange range) { + super(identifierURI); + + // shouldn't happen, but just in case... + if (earlyException != null) { + throw earlyException; + } + this.address = address; + this.mask = mask; + this.range = range; + } + + /** + * Returns a new IPAddressAttribute that represents + * the name at a particular DOM node. + * + * @param root the Node that contains the desired value + * + * @return a new IPAddressAttribute representing the + * appropriate value (null if there is a parsing error) + * + * @throws ParsingException if any of the address components is invalid + */ + public static IPAddressAttribute getInstance(Node root) + throws ParsingException { + if (root.getFirstChild() != null) { + return getInstance(root.getFirstChild().getNodeValue()); + } + throw new ParsingException("Error while parsing" + + "a IPAddressAttribute"); + } + + /** + * Returns a new IPAddressAttribute that represents + * the name indicated by the String provided. + * + * @param value a string representing the address + * + * @return a new IPAddressAttribute + * + * @throws ParsingException if any of the address components is invalid + */ + public static IPAddressAttribute getInstance(String value) + throws ParsingException { + if (value == null) { + throw new ParsingException("Can't create a " + + "IPAddressAttribute from null input"); + } + try { + // an IPv6 address starts with a '[' + if (value.indexOf('[') == 0) { + return IPv6AddressAttribute.getV6Instance(value); + } + return IPv4AddressAttribute.getV4Instance(value); + } catch (UnknownHostException uhe) { + throw new ParsingException("Failed to parse an IPAddress", uhe); + } + } + + /** + * Returns the address represented by this object. + * + * @return the address + */ + public InetAddress getAddress() { + return this.address; + } + + /** + * Returns the mask represented by this object, or null if there is no + * mask. + * + * @return the mask or null + */ + public InetAddress getMask() { + return this.mask; + } + + /** + * Returns the port range represented by this object which will be + * unbound if no range was specified. + * + * @return the range + */ + public PortRange getRange() { + return this.range; + } + + /** + * Returns true if the input is an instance of this class and if its + * value equals the value contained in this class. + * + * @param o the object to compare + * + * @return true if this object and the input represent the same value + */ + public boolean equals(Object o) { + if (! (o instanceof IPAddressAttribute)) { + return false; + } + + IPAddressAttribute other = (IPAddressAttribute)o; + + if (! this.address.equals(other.address)) { + return false; + } + + if (this.mask != null) { + if (other.mask == null) { + return false; + } + + if (! this.mask.equals(other.mask)) { + return false; + } + } else { + if (other.mask != null) { + return false; + } + } + + if (! this.range.equals(other.range)) { + return false; + } + + return true; + } + + /** + * Returns the hashcode value used to index and compare this object with + * others of the same type. + * + * @return the object's hashcode value + */ + public int hashCode() { + return encode().hashCode(); + } + + /** + * Converts to a String representation. + * + * @return the String representation + */ + public String toString() { + return "IPAddressAttribute: \"" + encode() + "\""; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/IPv4AddressAttribute.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/IPv4AddressAttribute.java new file mode 100644 index 0000000..3cecaf9 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/IPv4AddressAttribute.java @@ -0,0 +1,179 @@ + +/* + * @(#)IPv4AddressAttribute.java + * + * Copyright 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.attr; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +import com.sun.xacml.ParsingException; + + +/** + * Subclass of IPAddressAttribute that handles the specifics + * of IPv4. In general, you shouldn't need to interact with this class + * except to create an instance directly. + * + * @since 2.0 + * @author Seth Proctor + */ +public class IPv4AddressAttribute extends IPAddressAttribute +{ + + /** + * Creates the new IPv4AddressAttribute with just the required + * address component. + * + * @param address a non-null InetAddress + */ + public IPv4AddressAttribute(InetAddress address) { + this(address, null, new PortRange()); + } + + /** + * Creates the new IPv4AddressAttribute with the optional + * address mask. + * + * @param address a non-null InetAddress + * @param mask an InetAddress or null if there is no mask + */ + public IPv4AddressAttribute(InetAddress address, InetAddress mask) { + this(address, mask, new PortRange()); + } + + /** + * Creates the new IPv4AddressAttribute with the optional + * port range. + * + * @param address a non-null InetAddress + * @param range a non-null PortRange + */ + public IPv4AddressAttribute(InetAddress address, PortRange range) { + this(address, null, range); + } + + /** + * Creates the new IPv4AddressAttribute with all the optional + * components. + * + * @param address a non-null InetAddress + * @param mask an InetAddress or null if there is no mask + * @param range a non-null PortRange + */ + public IPv4AddressAttribute(InetAddress address, InetAddress mask, + PortRange range) { + super(address, mask, range); + } + + /** + * Returns a new IPv4AddressAttribute that represents + * the name indicated by the String provided. This is a + * protected method because you should never call it directly. + * Instead, you should call getInstance on + * IPAddressAttribute which provides versions that + * take both a String and a Node and + * will determine the protocol version correctly. + * + * @param value a string representing the address + * + * @return a new IPAddressAttribute + * + * @throws UnknownHostException if the address components is invalid + * @throws ParsingException + */ + protected static IPAddressAttribute getV4Instance(String value) + throws UnknownHostException, ParsingException { + if (value == null) { + throw new ParsingException("Can't create a " + + "IPv4AddressAttribute from null input"); + } + InetAddress address = null; + InetAddress mask = null; + PortRange range = null; + + // start out by seeing where the delimiters are + int maskPos = value.indexOf("/"); + int rangePos = value.indexOf(":"); + + // now check to see which components we have + if (maskPos == rangePos) { + // the sting is just an address + address = InetAddress.getByName(value); + } else if (maskPos != -1) { + // there is also a mask (and maybe a range) + address = InetAddress.getByName(value.substring(0, maskPos)); + if (rangePos != -1) { + // there's a range too, so get it and the mask + mask = + InetAddress.getByName(value.substring(maskPos + 1, + rangePos)); + range = + PortRange.getInstance(value.substring(rangePos + 1, + value.length())); + } else { + // there's no range, so just get the mask + mask = InetAddress.getByName(value.substring(maskPos + 1, + value.length())); + } + } else { + // there is a range, but no mask + address = InetAddress.getByName(value.substring(0, rangePos)); + range = PortRange.getInstance(value.substring(rangePos + 1, + value.length())); + } + + // if the range is null, then create it as unbound + range = new PortRange(); + + return new IPv4AddressAttribute(address, mask, range); + } + + /** + * @return The String encoding this AttributeValue. + */ + public String encode() { + String str = getAddress().getHostAddress(); + + if (getMask() != null) { + str += getMask().getHostAddress(); + } + if (! getRange().isUnbound()) { + str += ":" + getRange().encode(); + } + return str; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/IPv6AddressAttribute.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/IPv6AddressAttribute.java new file mode 100644 index 0000000..0d54f8a --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/IPv6AddressAttribute.java @@ -0,0 +1,170 @@ + +/* + * @(#)IPv6AddressAttribute.java + * + * Copyright 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.attr; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +import com.sun.xacml.ParsingException; + + +/** + * Subclass of IPAddressAttribute that handles the specifics + * of IPv6. In general, you shouldn't need to interact with this class + * except to create an instance directly. + * + * @since 2.0 + * @author Seth Proctor + */ +public class IPv6AddressAttribute extends IPAddressAttribute +{ + + /** + * Creates the new IPv6AddressAttribute with just the required + * address component. + * + * @param address a non-null InetAddress + */ + public IPv6AddressAttribute(InetAddress address) { + this(address, null, new PortRange()); + } + + /** + * Creates the new IPv6AddressAttribute with the optional + * address mask. + * + * @param address a non-null InetAddress + * @param mask an InetAddress or null if there is no mask + */ + public IPv6AddressAttribute(InetAddress address, InetAddress mask) { + this(address, mask, new PortRange()); + } + + /** + * Creates the new IPv6AddressAttribute with the optional + * port range. + * + * @param address a non-null InetAddress + * @param range a non-null PortRange + */ + public IPv6AddressAttribute(InetAddress address, PortRange range) { + this(address, null, range); + } + + /** + * Creates the new IPv6AddressAttribute with all the optional + * components. + * + * @param address a non-null InetAddress + * @param mask an InetAddress or null if there is no mask + * @param range a non-null PortRange + */ + public IPv6AddressAttribute(InetAddress address, InetAddress mask, + PortRange range) { + super(address, mask, range); + } + + /** + * Returns a new IPv6AddressAttribute that represents + * the name indicated by the String provided. This is a + * protected method because you should never call it directly. + * Instead, you should call getInstance on + * IPAddressAttribute which provides versions that + * take both a String and a Node and + * will determine the protocol version correctly. + * + * @param value a string representing the address + * + * @return a new IPAddressAttribute + * + * @throws UnknownHostException if the address components is invalid + * @throws ParsingException + */ + protected static IPAddressAttribute getV6Instance(String value) + throws UnknownHostException, ParsingException { + if (value == null) { + throw new ParsingException("Can't create a " + + "IPv6AddressAttribute from null input"); + } + InetAddress address = null; + InetAddress mask = null; + PortRange range = null; + int len = value.length(); + + // get the required address component + int endIndex = value.indexOf(']'); + address = InetAddress.getByName(value.substring(1, endIndex)); + + // see if there's anything left in the string + if (endIndex != (len - 1)) { + // if there's a mask, it's also an IPv6 address + if (value.charAt(endIndex + 1) == '/') { + int startIndex = endIndex + 3; + endIndex = value.indexOf(']', startIndex); + mask = InetAddress.getByName(value.substring(startIndex, + endIndex)); + } + + // finally, see if there's a port range, if we're not finished + if ((endIndex != (len - 1)) && (value.charAt(endIndex + 1) == ':')) { + range = PortRange.getInstance(value.substring(endIndex + 2, + len)); + } + } + + // if the range is null, then create it as unbound + range = new PortRange(); + + return new IPv6AddressAttribute(address, mask, range); + } + + /** + * @return The String encoding this AttributeValue. + */ + public String encode() { + String str = "[" + getAddress().getHostAddress() + "]"; + + if (getMask() != null) { + str += "/[" + getMask().getHostAddress() + "]"; + } + if (! getRange().isUnbound()) { + str += ":" + getRange().encode(); + } + return str; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/IntegerAttribute.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/IntegerAttribute.java new file mode 100644 index 0000000..ac0f890 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/IntegerAttribute.java @@ -0,0 +1,202 @@ + +/* + * @(#)IntegerAttribute.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.attr; + +import java.net.URI; + +import org.w3c.dom.Node; + +import com.sun.xacml.ParsingException; + + +/** + * Representation of an xs:integer value. This class supports parsing + * xs:integer values. All objects of this class are immutable and + * all methods of the class are thread-safe. + * + * @since 1.0 + * @author Marco Barreno + * @author Steve Hanna + */ +public class IntegerAttribute extends AttributeValue +{ + /** + * Official name of this type + */ + public static final String identifier = + TypeIdentifierConstants.INTEGER; + + /** + * URI version of name for this type + *

+ * This field is initialized by a static initializer so that + * we can catch any exceptions thrown by URI(String) and + * transform them into a RuntimeException, since this should + * never happen but should be reported properly if it ever does. + */ + private static URI identifierURI; + + /** + * RuntimeException that wraps an Exception thrown during the + * creation of identifierURI, null if none. + */ + private static RuntimeException earlyException; + + /** + * Static initializer that initializes the identifierURI + * class field so that we can catch any exceptions thrown + * by URI(String) and transform them into a RuntimeException. + * Such exceptions should never happen but should be reported + * properly if they ever do. + */ + static { + try { + identifierURI = URI.create(identifier); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * The actual long value that this object represents. + */ + private long value; + + /** + * Creates a new IntegerAttribute that represents + * the long value supplied. + * + * @param value the long value to be represented + */ + public IntegerAttribute(long value) { + super(identifierURI); + + // Shouldn't happen, but just in case... + if (earlyException != null) { + throw earlyException; + } + this.value = value; + } + + /** + * Returns a new IntegerAttribute that represents + * the xs:integer at a particular DOM node. + * + * @param root the Node that contains the desired value + * @return a new IntegerAttribute representing the + * appropriate value (null if there is a parsing error) + * @throws NumberFormatException if the string form isn't a number + * @throws ParsingException + */ + public static IntegerAttribute getInstance(Node root) + throws NumberFormatException, ParsingException { + if (root.getFirstChild() != null) { + return getInstance(root.getFirstChild().getNodeValue()); + } + throw new ParsingException("Error while parsing" + + "an IntegerAttribute"); + } + + /** + * Returns a new IntegerAttribute that represents + * the xs:integer value indicated by the string provided. + * + * @param value a string representing the desired value + * @return a new IntegerAttribute representing the + * appropriate value (null if there is a parsing error) + * @throws NumberFormatException if the string isn't a number + * @throws ParsingException + */ + public static IntegerAttribute getInstance(String value) + throws NumberFormatException, ParsingException { + if (value == null) { + throw new ParsingException("Can't create a " + + "IntegerAttribute from null input"); + } + // Leading '+' is allowed per XML schema and not + // by Long.parseLong. Strip it, if present. + if ((value.length() >= 1) && (value.charAt(0) == '+')) { + value = value.substring(1); + } + return new IntegerAttribute(Long.parseLong(value)); + } + + /** + * Returns the long value represented by this object. + * + * @return the long value + */ + public long getValue() { + return this.value; + } + + /** + * Returns true if the input is an instance of this class and if its + * value equals the value contained in this class. + * + * @param o the object to compare + * + * @return true if this object and the input represent the same value + */ + public boolean equals(Object o) { + if (! (o instanceof IntegerAttribute)) { + return false; + } + IntegerAttribute other = (IntegerAttribute)o; + + return (this.value == other.value); + } + + /** + * Returns the hashcode value used to index and compare this object with + * others of the same type. Typically this is the hashcode of the backing + * data object. + * + * @return the object's hashcode value + */ + public int hashCode() { + return (int)this.value; + } + + /** + * @return The String encoding this AttributeValue. + */ + public String encode() { + return String.valueOf(this.value); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/PortRange.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/PortRange.java new file mode 100644 index 0000000..7690afb --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/PortRange.java @@ -0,0 +1,264 @@ + +/* + * @(#)PortRange.java + * + * Copyright 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.attr; + +import com.sun.xacml.ParsingException; + + +/** + * This class represents a port range as specified in the XACML 2.0 description + * of dnsName and ipAddress. The range may have + * upper and lower bounds, be specified by a single port number, or may be + * unbound. + * + * @since 2.0 + * @author Seth Proctor + */ +public class PortRange +{ + + /** + * Constant used to specify that the range is unbound on one side. + */ + public static final int UNBOUND = -1; + + // the port bound values + private int lowerBound; + private int upperBound; + + /** + * Default constructor used to represent an unbound range. This is + * typically used when an address has no port information. + */ + public PortRange() { + this(UNBOUND, UNBOUND); + } + + /** + * Creates a PortRange that represents a single port value + * instead of a range of values. + * + * @param singlePort the single port number + */ + public PortRange(int singlePort) { + this(singlePort, singlePort); + } + + /** + * Creates a PortRange with upper and lower bounds. Either + * of the parameters may have the value UNBOUND meaning + * that there is no bound at the respective end. + * + * @param lowerBound the lower-bound port number or UNBOUND + * @param upperBound the upper-bound port number or UNBOUND + */ + public PortRange(int lowerBound, int upperBound) { + this.lowerBound = lowerBound; + this.upperBound = upperBound; + } + + /** + * Creates an instance of PortRange based on the given value. + * + * @param value a String representing the range + * + * @return a new PortRange + * + * @throws NumberFormatException if a port value isn't an integer + */ + public static PortRange getInstance(String value) + throws ParsingException { + if (value == null) { + throw new ParsingException("Can't create PortRange" + + " from null input"); + } + int lowerBound = UNBOUND; + int upperBound = UNBOUND; + + // first off, make sure there's actually content here + if ((value.length() == 0) || (value.equals("-"))) { + return new PortRange(); + } + + // there's content, so figure where the '-' is, if at all + int dashPos = value.indexOf('-'); + + if (dashPos == -1) { + // there's no dash, so it's just a single number + lowerBound = upperBound = Integer.parseInt(value); + } else if (dashPos == 0) { + // it starts with a dash, so it's just upper-range bound + upperBound = Integer.parseInt(value.substring(1)); + } else { + // it's a number followed by a dash, so get the lower-bound... + lowerBound = Integer.parseInt(value.substring(0, dashPos)); + int len = value.length(); + + // ... and see if there is a second port number + if (dashPos != (len - 1)) { + // the dash wasn't at the end, so there's an upper-bound + upperBound = Integer.parseInt(value.substring(dashPos + 1, + len)); + } + } + + return new PortRange(lowerBound, upperBound); + } + + /** + * Returns the lower-bound port value. If the range is not lower-bound, + * then this returns UNBOUND. If the range is actually a + * single port number, then this returns the same value as + * getUpperBound. + * + * @return the upper-bound + */ + public int getLowerBound() { + return this.lowerBound; + } + + /** + * Returns the upper-bound port value. If the range is not upper-bound, + * then this returns UNBOUND. If the range is actually a + * single port number, then this returns the same value as + * getLowerBound. + * + * @return the upper-bound + */ + public int getUpperBound() { + return this.upperBound; + } + + /** + * Returns whether the range is bounded by a lower port number. + * + * @return true if lower-bounded, false otherwise + */ + public boolean isLowerBounded() { + return (this.lowerBound != -1); + } + + /** + * Returns whether the range is bounded by an upper port number. + * + * @return true if upper-bounded, false otherwise + */ + public boolean isUpperBounded() { + return (this.upperBound != -1); + } + + /** + * Returns whether the range is actually a single port number. + * + * @return true if the range is a single port number, false otherwise + */ + public boolean isSinglePort() { + return ((this.lowerBound == this.upperBound) + && (this.lowerBound != UNBOUND)); + } + + /** + * Returns whether the range is unbound, which means that it specifies + * no port number or range. This is typically used with addresses that + * include no port information. + * + * @return true if the range is unbound, false otherwise + */ + public boolean isUnbound() { + return ((this.lowerBound == UNBOUND) && (this.upperBound == UNBOUND)); + } + + /** + * Returns true if the input is an instance of this class and if its + * value equals the value contained in this class. + * + * @param o the object to compare + * + * @return true if this object and the input represent the same value + */ + public boolean equals(Object o) { + if (! (o instanceof PortRange)) { + return false; + } + + PortRange other = (PortRange)o; + + if (this.lowerBound != other.lowerBound) { + return false; + } + + if (this.upperBound != other.upperBound) { + return false; + } + + return true; + } + + /** + * Override the hashCode method. + * + * @return The hashCode. + */ + public int hashCode() { + return this.upperBound + this.lowerBound; + } + + /** + * @return The String encoding this AttributeValue. + */ + public String encode() { + if (isUnbound()) { + return ""; + } + + if (isSinglePort()) { + return String.valueOf(this.lowerBound); + } + + if (! isLowerBounded()) { + return "-" + String.valueOf(this.upperBound); + } + + if (! isUpperBounded()) { + return String.valueOf(this.lowerBound) + "-"; + } + + return String.valueOf(this.lowerBound) + "-" + + String.valueOf(this.upperBound); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/RFC822NameAttribute.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/RFC822NameAttribute.java new file mode 100644 index 0000000..d1ef4bf --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/RFC822NameAttribute.java @@ -0,0 +1,199 @@ + +/* + * @(#)RFC822NameAttribute.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.attr; + +import java.net.URI; + +import org.w3c.dom.Node; + +import com.sun.xacml.ParsingException; + + +/** + * Representation of an rfc822Name (ie, an email address). + * + * @since 1.0 + * @author Seth Proctor + */ +public class RFC822NameAttribute extends AttributeValue +{ + + /** + * Official name of this type + */ + public static final String identifier = + TypeIdentifierConstants.RFC822NAME; + + /** + * URI version of name for this type + *

+ * This field is initialized by a static initializer so that + * we can catch any exceptions thrown by URI(String) and + * transform them into a RuntimeException, since this should + * never happen but should be reported properly if it ever does. + */ + private static URI identifierURI; + + /** + * RuntimeException that wraps an Exception thrown during the + * creation of identifierURI, null if none. + */ + private static RuntimeException earlyException; + + /** + * Static initializer that initializes the identifierURI + * class field so that we can catch any exceptions thrown + * by URI(String) and transform them into a RuntimeException. + * Such exceptions should never happen but should be reported + * properly if they ever do. + */ + static { + try { + identifierURI = URI.create(identifier); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + // the actual value being stored + private String value; + + /** + * Creates a new RFC822NameAttribute that represents the + * value supplied. + * + * @param value the email address to be represented + */ + public RFC822NameAttribute(String value) { + super(identifierURI); + + // Shouldn't happen, but just in case... + if (earlyException != null) { + throw earlyException; + } + + if (value == null) { + throw new IllegalArgumentException("Can't create RFC822Name from" + + "null input"); + } + // check that the string is an address, ie, that it has one and only + // one '@' character in it + String [] parts = value.split("@"); + if (parts.length != 2) { + // this is malformed input + throw new IllegalArgumentException("invalid RFC822Name: " + value); + } + + // cannonicalize the name + this.value = parts[0] + "@" + parts[1].toLowerCase(); + } + + /** + * Returns a new RFC822NameAttribute that represents + * the email address at a particular DOM node. + * + * @param root the Node that contains the desired value + * @return a new RFC822NameAttribute representing the + * appropriate value + * @throws ParsingException + */ + public static RFC822NameAttribute getInstance(Node root) + throws ParsingException { + if (root.getFirstChild() != null) { + return getInstance(root.getFirstChild().getNodeValue()); + } + throw new ParsingException("Error while parsing" + + "a RFC822NameAttribute"); + } + + /** + * Returns a new RFC822NameAttribute that represents + * the email address value indicated by the string provided. + * + * @param value a string representing the desired value + * @return a new RFC822NameAttribute representing the + * appropriate value + */ + public static RFC822NameAttribute getInstance(String value) { + return new RFC822NameAttribute(value); + } + + /** + * Returns the name value represented by this object + * + * @return the name + */ + public String getValue() { + return this.value; + } + + /** + * Returns true if the input is an instance of this class and if its + * value equals the value contained in this class. + * + * @param o the object to compare + * + * @return true if this object and the input represent the same value + */ + public boolean equals(Object o) { + if (! (o instanceof RFC822NameAttribute)) { + return false; + } + RFC822NameAttribute other = (RFC822NameAttribute)o; + + return this.value.equals(other.value); + } + + /** + * Returns the hashcode value used to index and compare this object with + * others of the same type. Typically this is the hashcode of the backing + * data object. + * + * @return the object's hashcode value + */ + public int hashCode() { + return this.value.hashCode(); + } + + /** + * @return The String encoding this AttributeValue. + */ + public String encode() { + return this.value; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/StandardAttributeFactory.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/StandardAttributeFactory.java new file mode 100644 index 0000000..c8f8220 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/StandardAttributeFactory.java @@ -0,0 +1,265 @@ + +/* + * @(#)StandardAttributeFactory + * + * Copyright 2004-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.attr; + +import com.sun.xacml.Constants; +import com.sun.xacml.UnknownIdentifierException; + +import com.sun.xacml.attr.proxy.AnyURIAttributeProxy; +import com.sun.xacml.attr.proxy.Base64BinaryAttributeProxy; +import com.sun.xacml.attr.proxy.BooleanAttributeProxy; +import com.sun.xacml.attr.proxy.DateAttributeProxy; +import com.sun.xacml.attr.proxy.DateTimeAttributeProxy; +import com.sun.xacml.attr.proxy.DayTimeDurationAttributeProxy; +import com.sun.xacml.attr.proxy.DNSNameAttributeProxy; +import com.sun.xacml.attr.proxy.DoubleAttributeProxy; +import com.sun.xacml.attr.proxy.HexBinaryAttributeProxy; +import com.sun.xacml.attr.proxy.IntegerAttributeProxy; +import com.sun.xacml.attr.proxy.IPAddressAttributeProxy; +import com.sun.xacml.attr.proxy.RFC822NameAttributeProxy; +import com.sun.xacml.attr.proxy.StringAttributeProxy; +import com.sun.xacml.attr.proxy.TimeAttributeProxy; +import com.sun.xacml.attr.proxy.YearMonthDurationAttributeProxy; +import com.sun.xacml.attr.proxy.X500NameAttributeProxy; + +//import foo.xacml.attr.proxy.EmergencyLevelAttributeProxy; +//import foo.xacml.attr.proxy.EvaluationIdAttributeProxy; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.apache.log4j.Logger; + + + +/** + * This factory supports the standard set of datatypes specified in XACML +! * 1.x and 2.0. It is the default factory used by the system, and imposes + * a singleton pattern insuring that there is only ever one instance of + * this class. + *

+ * Note that because this supports only the standard datatypes, this + * factory does not allow the addition of any other datatypes. If you call + * addDatatype on an instance of this class, an exception + * will be thrown. If you need a standard factory that is modifiable, you + * should create a new BaseAttributeFactory (or some other + * AttributeFactory) and configure it with the standard + * datatypes using addStandardDatatypes (or, in the case of + * BaseAttributeFactory, by providing the datatypes in the + * constructor). + * + * @since 1.2 + * @author Seth Proctor + */ +public class StandardAttributeFactory extends BaseAttributeFactory +{ + + // the one instance of this factory + private static StandardAttributeFactory factoryInstance = null; + + // the datatypes supported by this factory + private static HashMap supportedDatatypes = null; + + // the supported identifiers for each version of XACML + private static Set supportedV1Identifiers; + private static Set supportedV2Identifiers; + + // the logger we'll use for all messages + private static final Logger logger = + Logger.getLogger(StandardAttributeFactory.class.getName()); + + /** + * Private constructor that sets up proxies for all of the standard + * datatypes. + */ + private StandardAttributeFactory() { + super(supportedDatatypes); + } + + /** + * Private initializer for the supported datatypes. This isn't called + * until something needs these values, and is only called once. + */ + private static void initDatatypes() { + logger.debug("Initializing standard datatypes"); + + supportedDatatypes = new HashMap(); + + // the 1.x datatypes + supportedDatatypes.put(BooleanAttribute.identifier, + new BooleanAttributeProxy()); + supportedDatatypes.put(StringAttribute.identifier, + new StringAttributeProxy()); + supportedDatatypes.put(DateAttribute.identifier, + new DateAttributeProxy()); + supportedDatatypes.put(TimeAttribute.identifier, + new TimeAttributeProxy()); + supportedDatatypes.put(DateTimeAttribute.identifier, + new DateTimeAttributeProxy()); + supportedDatatypes.put(DayTimeDurationAttribute.identifier, + new DayTimeDurationAttributeProxy()); + supportedDatatypes.put(YearMonthDurationAttribute.identifier, + new YearMonthDurationAttributeProxy()); + supportedDatatypes.put(DoubleAttribute.identifier, + new DoubleAttributeProxy()); + supportedDatatypes.put(IntegerAttribute.identifier, + new IntegerAttributeProxy()); + supportedDatatypes.put(AnyURIAttribute.identifier, + new AnyURIAttributeProxy()); + supportedDatatypes.put(HexBinaryAttribute.identifier, + new HexBinaryAttributeProxy()); + supportedDatatypes.put(Base64BinaryAttribute.identifier, + new Base64BinaryAttributeProxy()); + supportedDatatypes.put(X500NameAttribute.identifier, + new X500NameAttributeProxy()); + supportedDatatypes.put(RFC822NameAttribute.identifier, + new RFC822NameAttributeProxy()); + /* + supportedDatatypes.put(EmergencyLevelAttribute.identifier, + new EmergencyLevelAttributeProxy()); + supportedDatatypes.put(EvaluationIdAttribute.identifier, + new EvaluationIdAttributeProxy()); + */ + + supportedV1Identifiers = + Collections.unmodifiableSet(supportedDatatypes.keySet()); + + // the 2.0 datatypes + supportedDatatypes.put(DNSNameAttribute.identifier, + new DNSNameAttributeProxy()); + supportedDatatypes.put(IPAddressAttribute.identifier, + new IPAddressAttributeProxy()); + + supportedV2Identifiers = + Collections.unmodifiableSet(supportedDatatypes.keySet()); + } + + /** + * Returns an instance of this factory. This method enforces a singleton + * model, meaning that this always returns the same instance, creating + * the factory if it hasn't been requested before. This is the default + * model used by the AttributeFactory, ensuring quick + * access to this factory. + * + * @return the factory instance + */ + public static synchronized StandardAttributeFactory getFactory() { + if (factoryInstance == null) { + initDatatypes(); + factoryInstance = new StandardAttributeFactory(); + } + return factoryInstance; + } + + /** + * A convenience method that returns a new instance of an + * that supports all of the standard + * datatypes. The new factory allows adding support for new datatypes. + * This method should only be used when you need a new, mutable instance + * (eg, when you want to create a new factory that extends the set of + * supported datatypes). In general, you should use + * getFactory which is more efficient and enforces a + * singleton pattern. + * + * @return a new factory supporting the standard datatypes + */ + public static AttributeFactory getNewFactory() { + // first we make sure that everything has been initialized... + getFactory(); + + // ...then we create the new instance + return new BaseAttributeFactory(supportedDatatypes); + } + + /** + * Returns the identifiers supported for the given version of XACML. + * Because this factory supports identifiers from all versions of the + * XACML specifications, this method is useful for getting a list of + * which specific identifiers are supported by a given version of XACML. + * + * @param xacmlVersion a standard XACML identifier string, as provided + * in PolicyMetaData + * + * @return a Set of identifiers + * + * @throws UnknownIdentifierException if the version string is unknown + */ + public static Set getStandardDatatypes(String xacmlVersion) + throws UnknownIdentifierException + { + if (xacmlVersion.equals(Constants.XACML_1_0_IDENTIFIER)) { + return supportedV1Identifiers; + } else if (xacmlVersion.equals(Constants.XACML_2_0_IDENTIFIER)) { + return supportedV2Identifiers; + } else if (xacmlVersion.equals(Constants.XACML_3_0_IDENTIFIER)) { + return supportedV2Identifiers; + } + + throw new UnknownIdentifierException("Unknown XACML version: " + + xacmlVersion); + } + + /** + * Returns all supported datatypes. + * + * + * @return a Map of attribute proxys keyed by their + * identifier. + */ + public static Map getStandardDatatypes() { + StandardAttributeFactory.initDatatypes(); + return new HashMap(StandardAttributeFactory.supportedDatatypes); + + } + + /** + * Throws an UnsupportedOperationException since you are not + * allowed to modify what a standard factory supports. + * + * @param id the name of the attribute type + * @param proxy the proxy used to create new attributes of the given type + * + * @throws UnsupportedOperationException always + */ + public void addDatatype(String id, AttributeProxy proxy) { + throw new UnsupportedOperationException("a standard factory cannot " + + "support new datatypes"); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/StringAttribute.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/StringAttribute.java new file mode 100644 index 0000000..bdf36f9 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/StringAttribute.java @@ -0,0 +1,228 @@ + +/* + * @(#)StringAttribute.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.attr; + +import java.net.URI; + +import org.w3c.dom.Node; + +import com.sun.xacml.ParsingException; + + +/** + * Representation of an xs:string value. This class supports parsing + * xs:string values. All objects of this class are immutable and + * all methods of the class are thread-safe. + *

+ * Note that there was some confusion in the XACML specification + * about whether this datatype should be able to handle XML elements (ie, + * whether <AttributeValue DataType="...string"><foo/> + * </AttributeValue> is valid). This has been clarified to provide + * the correct requirement that a string may not contain mixed content (ie, + * the example provided here is invalid). If you need to specify something + * like this with the string datatype, then you must escape the + * < and > characters. + * + * @since 1.0 + * @author Marco Barreno + * @author Seth Proctor + * @author Steve Hanna + */ +public class StringAttribute extends AttributeValue +{ + /** + * Official name of this type + */ + public static final String identifier = + TypeIdentifierConstants.STRING; + + /** + * URI version of name for this type + *

+ * This field is initialized by a static initializer so that + * we can catch any exceptions thrown by URI(String) and + * transform them into a RuntimeException, since this should + * never happen but should be reported properly if it ever does. + */ + private static URI identifierURI; + + /** + * RuntimeException that wraps an Exception thrown during the + * creation of identifierURI, null if none. + */ + private static RuntimeException earlyException; + + /** + * Static initializer that initializes the identifierURI + * class field so that we can catch any exceptions thrown + * by URI(String) and transform them into a RuntimeException. + * Such exceptions should never happen but should be reported + * properly if they ever do. + */ + static { + try { + identifierURI = URI.create(identifier); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * The actual String value that this object represents. + */ + private String value; + + /** + * Creates a new StringAttribute that represents + * the String value supplied. + * + * @param value the String value to be represented + */ + public StringAttribute(String value) { + super(identifierURI); + + // Shouldn't happen, but just in case... + if (earlyException != null) { + throw earlyException; + } + if (value == null) { + this.value = ""; + } else { + this.value = value; + } + } + + /** + * Returns a new StringAttribute that represents + * the xs:string at a particular DOM node. + * + * @param root the Node that contains the desired value + * @return a new StringAttribute representing the + * appropriate value (null if there is a parsing error) + * @throws ParsingException + */ + public static StringAttribute getInstance(Node root) + throws ParsingException { + Node node = root.getFirstChild(); + + // Strings are allowed to have an empty AttributeValue element and are + // just treated as empty strings...we have to handle this case + if (node == null) { + return new StringAttribute(""); + } + // get the type of the node + short type = node.getNodeType(); + + // now see if we have (effectively) a simple string value + if ((type == Node.TEXT_NODE) || (type == Node.CDATA_SECTION_NODE) || + (type == Node.COMMENT_NODE)) { + return getInstance(node.getNodeValue()); + } + + // there is some confusion in the specifications about what should + // happen at this point, but the strict reading of the XMLSchema + // specification suggests that this should be an error + throw new ParsingException("Can't create a StringAttribute from " + + "given xml node type: " + root.getNodeType()); + } + + /** + * Returns a new StringAttribute that represents + * the xs:string value indicated by the String provided. + * + * @param value a string representing the desired value + * @return a new StringAttribute representing the + * appropriate value + */ + public static StringAttribute getInstance(String value) { + return new StringAttribute(value); + } + + /** + * Returns the String value represented by this object. + * + * @return the String value + */ + public String getValue() { + return this.value; + } + + /** + * Returns true if the input is an instance of this class and if its + * value equals the value contained in this class. + * + * @param o the object to compare + * + * @return true if this object and the input represent the same value + */ + public boolean equals(Object o) { + if (! (o instanceof StringAttribute)) { + return false; + } + StringAttribute other = (StringAttribute)o; + + return this.value.equals(other.value); + } + + /** + * Returns the hashcode value used to index and compare this object with + * others of the same type. Typically this is the hashcode of the backing + * data object. + * + * @return the object's hashcode value + */ + public int hashCode() { + return this.value.hashCode(); + } + + /** + * Converts to a String representation. + * + * @return the String representation + */ + public String toString() { + return "StringAttribute: \"" + this.value + "\""; + } + + /** + * @return The String encoding this AttributeValue. + */ + public String encode() { + return this.value; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/TimeAttribute.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/TimeAttribute.java new file mode 100644 index 0000000..80eb3d4 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/TimeAttribute.java @@ -0,0 +1,522 @@ + +/* + * @(#)TimeAttribute.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.attr; + +import com.sun.xacml.Constants; +import com.sun.xacml.ParsingException; +import com.sun.xacml.ProcessingException; + +import java.net.URI; + +import java.text.ParseException; + +import java.util.Date; + +import org.w3c.dom.Node; + + +/** + * Representation of an xs:time value. This class supports parsing + * xs:time values. All objects of this class are immutable and + * thread-safe. The Date objects returned are not, but + * these objects are cloned before being returned. + * + * @since 1.0 + * @author Steve Hanna + * @author Seth Proctor + */ +public class TimeAttribute extends AttributeValue +{ + /** + * Official name of this type + */ + public static final String identifier = + TypeIdentifierConstants.TIME; + + /** + * URI version of name for this type + *

+ * This field is initialized by a static initializer so that + * we can catch any exceptions thrown by URI(String) and + * transform them into a RuntimeException, since this should + * never happen but should be reported properly if it ever does. + *

+ * This object is used for synchronization whenever we need + * protection across this whole class. + */ + private static URI identifierURI; + + /** + * RuntimeException that wraps an Exception thrown during the + * creation of identifierURI, null if none. + */ + private static RuntimeException earlyException; + + /** + * Static initializer that initializes the identifierURI + * class field so that we can catch any exceptions thrown + * by URI(String) and transform them into a RuntimeException. + * Such exceptions should never happen but should be reported + * properly if they ever do. + */ + static { + try { + identifierURI = URI.create(identifier); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * Time zone value that indicates that the time zone was not + * specified. + */ + public static final int TZ_UNSPECIFIED = -1000000; + + /** + * The time that this object represents in second resolution, in + * milliseconds GMT, with zero being midnight. If no time zone was + * specified, the local time zone is used to convert to milliseconds + * relative to GMT. + */ + private long timeGMT; + + /** + * The number of nanoseconds beyond the time given by the timeGMT + * field. The XML Query document says that fractional seconds + * must be supported down to at least 100 nanosecond resolution. + * The Date class only supports milliseconds, so we include here + * support for nanosecond resolution. + */ + private int nanoseconds; + + // NOTE: now that we're not using a Date object, the above two variables + // could be condensed, and the interface could be changed so we don't + // need to worry about tracking the time values separately + + /** + * The time zone specified for this object (or TZ_UNSPECIFIED if + * unspecified). The offset to GMT, in minutes. + */ + private int timeZone; + + /** + * The time zone actually used for this object (if it was + * originally unspecified, the default time zone used). + * The offset to GMT, in minutes. + */ + private int defaultedTimeZone; + + /** + * Cached encoded value (null if not cached yet). + */ + private String encodedValue = null; + + /** + * Creates a new TimeAttribute that represents + * the current time in the current time zone. + */ + public TimeAttribute() { + this(new Date()); + } + + /** + * Creates a new TimeAttribute that represents + * the given time but uses the default timezone and offset values. + * + * @param time a Date object representing the + * specified time down to second resolution. This + * date should have a date of 01/01/1970. If it does + * not, such a date will be forced. If this object + * has non-zero milliseconds, they are combined + * with the nanoseconds parameter. + */ + public TimeAttribute(Date time) { + super(identifierURI); + + int currOffset = DateTimeAttribute.getDefaultTZOffset(time); + init(time, 0, currOffset, currOffset); + } + + /** + * Creates a new TimeAttribute that represents + * the time supplied. + * + * @param time a Date object representing the + * specified time down to second resolution. This + * date should have a date of 01/01/1970. If it does + * not, such a date will be forced. If this object + * has non-zero milliseconds, they are combined + * with the nanoseconds parameter. + * @param nanoseconds the number of nanoseconds beyond the + * Date specified in the date parameter + * @param timeZone the time zone specified for this object + * (or TZ_UNSPECIFIED if unspecified). The + * offset to GMT, in minutes. + * @param defaultedTimeZone the time zone actually used for this + * object, which must be specified. + * The offset to GMT, in minutes. + */ + public TimeAttribute(Date time, int nanoseconds, int timeZone, + int defaultedTimeZone) { + super(identifierURI); + + // if the timezone is unspecified, it's illegal for the defaulted + // timezone to also be unspecified + if ((timeZone == TZ_UNSPECIFIED) && + (defaultedTimeZone == TZ_UNSPECIFIED)) { + throw new ProcessingException("default timezone must be specified" + + "when a timezone is provided"); + } + + init(time, nanoseconds, timeZone, defaultedTimeZone); + } + + /** + * Initialization code shared by constructors. + * + * @param date a Date object representing the + * specified time down to second resolution. This + * date should have a date of 01/01/1970. If it does + * not, such a date will be forced. If this object + * has non-zero milliseconds, they are combined + * with the nanoseconds parameter. + * @param nanoseconds the number of nanoseconds beyond the + * Date specified in the date parameter + * @param timeZone the time zone specified for this object + * (or TZ_UNSPECIFIED if unspecified). The + * offset to GMT, in minutes. + * @param defaultedTimeZone the time zone actually used for this + * object (if it was originally unspecified, + * the default time zone used). + * The offset to GMT, in minutes. + */ + private void init(Date date, int nanoseconds, int timeZone, + int defaultedTimeZone) { + + // Shouldn't happen, but just in case... + if (earlyException != null) { + throw earlyException; + } + + // get a temporary copy of the date + Date tmpDate = (Date)(date.clone()); + + // Combine the nanoseconds so they are between 0 and 999,999,999 + this.nanoseconds = + DateTimeAttribute.combineNanos(tmpDate, nanoseconds); + + // now that the date has been (potentially) updated, store the time + this.timeGMT = tmpDate.getTime(); + + // keep track of the timezone values + this.timeZone = timeZone; + this.defaultedTimeZone = defaultedTimeZone; + + // Check that the date is normalized to 1/1/70 + if ((this.timeGMT >= DateAttribute.MILLIS_PER_DAY) + || (this.timeGMT < 0)) { + this.timeGMT = this.timeGMT % DateAttribute.MILLIS_PER_DAY; + + // if we had a negative value then we need to shift by a day + if (this.timeGMT < 0) { + this.timeGMT += DateAttribute.MILLIS_PER_DAY; + } + } + } + + /** + * Returns a new TimeAttribute that represents + * the xs:time at a particular DOM node. + * + * @param root the Node that contains the desired value + * @return a new TimeAttribute representing the + * appropriate value (null if there is a parsing error) + * + * @throws ParsingException + * @throws NumberFormatException + * @throws ParseException + */ + public static TimeAttribute getInstance(Node root) + throws ParsingException, NumberFormatException, ParseException { + if (root.getFirstChild() != null) { + return getInstance(root.getFirstChild().getNodeValue()); + } + throw new IllegalArgumentException("Error while parsing" + + "a TimeAttribute"); + } + + /** + * Returns a new TimeAttribute that represents + * the xs:time value indicated by the string provided. + * + * @param value a string representing the desired value + * @return a new TimeAttribute representing the + * desired value (null if there is a parsing error) + * + * @throws ParsingException if any problems occurred while parsing + * @throws NumberFormatException + * @throws ParseException + */ + public static TimeAttribute getInstance(String value) + throws ParsingException, NumberFormatException, ParseException { + if (value == null) { + throw new ParsingException("Can't create a " + + "TimeAttribute from empty input"); + } + // Prepend date string for Jan 1 1970 and use the + // DateTimeAttribute parsing code. + + value = "1970-01-01T" + value; + + DateTimeAttribute dateTime = DateTimeAttribute.getInstance(value); + + // if there was no explicit TZ provided, then we want to make sure + // the that the defaulting is done correctly, especially since 1/1/70 + // is always out of daylight savings time + + Date dateValue = dateTime.getValue(); + int defaultedTimeZone = dateTime.getDefaultedTimeZone(); + if (dateTime.getTimeZone() == TZ_UNSPECIFIED) { + int newDefTimeZone = + DateTimeAttribute.getDefaultTZOffset(new Date()); + // Multiplication with 1L to avoid overflows in the + // integer multiplication, since it's converted to long anyway + dateValue = new Date(dateValue.getTime() - + 1L *(newDefTimeZone - defaultedTimeZone) * + DateAttribute.MILLIS_PER_MINUTE); + defaultedTimeZone = newDefTimeZone; + } + + return new TimeAttribute(dateValue, + dateTime.getNanoseconds(), + dateTime.getTimeZone(), + defaultedTimeZone); + } + + /** + * Gets the time represented by this object. The return + * value is a Date object representing the + * specified time down to second resolution with a date + * of January 1, 1970. Subsecond values are handled by the + * {@link #getNanoseconds getNanoseconds} method. + * + * @return a Date object representing the + * time represented by this object + */ + public Date getValue() { + return new Date(this.timeGMT); + } + + /** + * Gets the number of milliseconds since midnight GMT that this attribute + * value represents. This is the same time returned by + * getValue, and likewise the milliseconds are provided + * with second resolution. + * + * @return milliseconds since midnight GMT + */ + public long getMilliseconds() { + return this.timeGMT; + } + + /** + * Gets the nanoseconds of this object. + * + * @return the number of nanoseconds + */ + public int getNanoseconds() { + return this.nanoseconds; + } + + /** + * Gets the time zone of this object (or TZ_UNSPECIFIED if + * unspecified). + * + * @return the offset to GMT in minutes (positive or negative) + */ + public int getTimeZone() { + return this.timeZone; + } + + /** + * Gets the time zone actually used for this object (if it was + * originally unspecified, the default time zone used). + * + * @return the offset to GMT in minutes (positive or negative) + */ + public int getDefaultedTimeZone() { + return this.defaultedTimeZone; + } + + /** + * Returns true if the input is an instance of this class and if its + * value equals the value contained in this class. + * + * @param o the object to compare + * + * @return true if this object and the input represent the same value + */ + public boolean equals(Object o) { + if (! (o instanceof TimeAttribute)) { + return false; + } + TimeAttribute other = (TimeAttribute)o; + + return (this.timeGMT == other.timeGMT && + (this.nanoseconds == other.nanoseconds)); + } + + /** + * Returns the hashcode value used to index and compare this object with + * others of the same type. Typically this is the hashcode of the backing + * data object. + * + * @return the object's hashcode value + */ + public int hashCode() { + // the standard Date hashcode is used here... + int hashCode = (int)(this.timeGMT ^ (this.timeGMT >>> 32)); + + // ...but both the timeGMT and the nanoseconds fields are considered + // by the equals method, so it's best if the hashCode is derived + // from both of those fields. + hashCode = (31 * hashCode) + this.nanoseconds; + + return hashCode; + } + + /** + * Converts to a String representation. + * + * @return the String representation + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("TimeAttribute: [" + Constants.nl); + + // calculate the GMT value of this time + long secsGMT = this.timeGMT / 1000; + long minsGMT = secsGMT / 60; + secsGMT = secsGMT % 60; + long hoursGMT = minsGMT / 60; + minsGMT = minsGMT % 60; + + // put the right number of zeros in place + String hoursStr = (hoursGMT < 10) ? "0" + hoursGMT : "" + hoursGMT; + String minsStr = (minsGMT < 10) ? "0" + minsGMT : "" + minsGMT; + String secsStr = (secsGMT < 10) ? "0" + secsGMT : "" + secsGMT; + + sb.append(" Time GMT: " + hoursStr + ":" + minsStr + ":" + secsStr); + sb.append(" Nanoseconds: " + this.nanoseconds); + sb.append(" TimeZone: " + this.timeZone); + sb.append(" Defaulted TimeZone: " + this.defaultedTimeZone); + sb.append("]"); + + return sb.toString(); + } + + /** + * Encodes the value in a form suitable for including in XML data like + * a request or an obligation. This returns a time value that could in + * turn be used by the factory to create a new instance with the same + * value. + * + * @return a String form of the value + */ + public String encode() { + if (this.encodedValue != null) { + return this.encodedValue; + } + // "hh:mm:ss.sssssssss+hh:mm".length() = 27 + StringBuffer buf = new StringBuffer(27); + + // get the correct time for the timezone being used + int millis = (int)this.timeGMT; + if (this.timeZone == TZ_UNSPECIFIED) { + millis += (this.defaultedTimeZone + * DateAttribute.MILLIS_PER_MINUTE); + } else { + millis += (this.timeZone * DateAttribute.MILLIS_PER_MINUTE); + } + if (millis < 0) { + millis += DateAttribute.MILLIS_PER_DAY; + } else if (millis >= DateAttribute.MILLIS_PER_DAY) { + millis -= DateAttribute.MILLIS_PER_DAY; + } + + // now generate the time string + int hour = millis / DateAttribute.MILLIS_PER_HOUR; + millis = millis % DateAttribute.MILLIS_PER_HOUR; + buf.append(DateAttribute.zeroPadInt(hour, 2)); + buf.append(':'); + int minute = millis / DateAttribute.MILLIS_PER_MINUTE; + millis = millis % DateAttribute.MILLIS_PER_MINUTE; + buf.append(DateAttribute.zeroPadInt(minute, 2)); + buf.append(':'); + int second = millis / DateAttribute.MILLIS_PER_SECOND; + buf.append(DateAttribute.zeroPadInt(second, 2)); + + // add any nanoseconds + if (this.nanoseconds != 0) { + buf.append('.'); + buf.append(DateAttribute.zeroPadInt(this.nanoseconds, 9)); + } + + // if there is a specified timezone, then include that in the encoding + if (this.timeZone != TZ_UNSPECIFIED) { + int tzNoSign = this.timeZone; + if (this.timeZone < 0) { + tzNoSign = -tzNoSign; + buf.append('-'); + } else { + buf.append('+'); + } + int tzHours = tzNoSign / 60; + buf.append(DateAttribute.zeroPadInt(tzHours, 2)); + buf.append(':'); + int tzMinutes = tzNoSign % 60; + buf.append(DateAttribute.zeroPadInt(tzMinutes, 2)); + } + + // remember the encoding for later + this.encodedValue = buf.toString(); + + return this.encodedValue; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/TypeIdentifierConstants.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/TypeIdentifierConstants.java new file mode 100644 index 0000000..96f4023 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/TypeIdentifierConstants.java @@ -0,0 +1,78 @@ +package com.sun.xacml.attr; + +import java.net.URI; + +public class TypeIdentifierConstants { + + public static final String ANYURI = + "http://www.w3.org/2001/XMLSchema#anyURI"; + public static final String BASE64BINARY = + "http://www.w3.org/2001/XMLSchema#base64Binary"; + public static final String BOOLEAN = + "http://www.w3.org/2001/XMLSchema#boolean"; + public static final String DATE = + "http://www.w3.org/2001/XMLSchema#date"; + public static final String DATETIME = + "http://www.w3.org/2001/XMLSchema#dateTime"; + public static final String DAYTIMEDURATION = + "http://www.w3.org/TR/2002/WD-xquery-operators-20020816#dayTimeDuration"; + public static final String DECISION = + "urn:oasis:names:tc:xacml:3.0:delegation:decision"; + public static final String DNSNAME = + "urn:oasis:names:tc:xacml:2.0:data-type:dnsName"; + public static final String DOUBLE = + "http://www.w3.org/2001/XMLSchema#double"; + public static final String HEXBINARY = + "http://www.w3.org/2001/XMLSchema#hexBinary"; + public static final String INTEGER = + "http://www.w3.org/2001/XMLSchema#integer"; + public static final String IPADDRESS = + "urn:oasis:names:tc:xacml:2.0:data-type:ipAddress"; + public static final String RFC822NAME = + "urn:oasis:names:tc:xacml:1.0:data-type:rfc822Name"; + public static final String STRING = + "http://www.w3.org/2001/XMLSchema#string"; + public static final String TIME = + "http://www.w3.org/2001/XMLSchema#time"; + public static final String X500NAME = + "urn:oasis:names:tc:xacml:1.0:data-type:x500Name"; + public static final String YEARMONTHDURATION = + "http://www.w3.org/TR/2002/WD-xquery-operators-20020816#yearMonthDuration"; + + public static final URI ANYURI_URI = + URI.create(ANYURI); + public static final URI BASE64BINARY_URI = + URI.create(BASE64BINARY); + public static final URI BOOLEAN_URI = + URI.create(BOOLEAN); + public static final URI DATE_URI = + URI.create(DATE); + public static final URI DATETIME_URI = + URI.create(DATETIME); + public static final URI DAYTIMEDURATION_URI = + URI.create(DAYTIMEDURATION); + public static final URI DECISION_URI = + URI.create(DECISION); + public static final URI DNSNAME_URI = + URI.create(DNSNAME); + public static final URI DOUBLE_URI = + URI.create(DOUBLE); + public static final URI HEXBINARY_URI = + URI.create(HEXBINARY); + public static final URI INTEGER_URI = + URI.create(INTEGER); + public static final URI IPADDRESS_URI = + URI.create(IPADDRESS); + public static final URI RFC822NAME_URI = + URI.create(RFC822NAME); + public static final URI STRING_URI = + URI.create(STRING); + public static final URI TIME_URI = + URI.create(TIME); + public static final URI X500NAME_URI = + URI.create(X500NAME); + public static final URI YEARMONTHDURATION_URI = + URI.create(YEARMONTHDURATION); + + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/X500NameAttribute.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/X500NameAttribute.java new file mode 100644 index 0000000..66246e5 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/X500NameAttribute.java @@ -0,0 +1,203 @@ + +/* + * @(#)X500NameAttribute.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.attr; + +import java.net.URI; + +import javax.security.auth.x500.X500Principal; + +import org.w3c.dom.Node; + +import com.sun.xacml.ParsingException; + + +/** + * Representation of an X500 Name. + * + * @since 1.0 + * @author Marco Barreno + * @author Seth Proctor + */ +public class X500NameAttribute extends AttributeValue +{ + + /** + * Official name of this type + */ + public static final String identifier = + TypeIdentifierConstants.X500NAME; + + // the actual value being stored + private X500Principal value; + + /** + * URI version of name for this type + *

+ * This field is initialized by a static initializer so that + * we can catch any exceptions thrown by URI(String) and + * transform them into a RuntimeException, since this should + * never happen but should be reported properly if it ever does. + */ + private static URI identifierURI; + + /** + * RuntimeException that wraps an Exception thrown during the + * creation of identifierURI, null if none. + */ + private static RuntimeException earlyException; + + /** + * Static initializer that initializes the identifierURI + * class field so that we can catch any exceptions thrown + * by URI(String) and transform them into a RuntimeException. + * Such exceptions should never happen but should be reported + * properly if they ever do. + */ + static { + try { + identifierURI = URI.create(identifier); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * Creates a new X500NameAttribute that represents the + * value supplied. + * + * @param value the X500 Name to be represented + */ + public X500NameAttribute(X500Principal value) { + super(identifierURI); + + if (earlyException != null) { + throw earlyException; + } + + this.value = value; + } + + /** + * Returns a new that represents + * the X500 Name at a particular DOM node. + * + * @param root the Node that contains the desired value + * @return a new X500NameAttribute representing the + * appropriate value + * @throws IllegalArgumentException if value is improperly specified + */ + public static X500NameAttribute getInstance(Node root) + throws ParsingException { + if (root.getFirstChild() != null) { + return getInstance(root.getFirstChild().getNodeValue()); + } + throw new ParsingException("Error while parsing" + + "a X500NameAttribute"); + } + + /** + * Returns a new X500NameAttribute that represents + * the X500 Name value indicated by the string provided. + * + * @param value a string representing the desired value + * @return a new X500NameAttribute representing the + * appropriate value + * @throws IllegalArgumentException if value is improperly specified + */ + public static X500NameAttribute getInstance(String value) + throws IllegalArgumentException, ParsingException { + if (value == null) { + throw new ParsingException("Can't create a " + + "X500NameAttribute from null input"); + } + return new X500NameAttribute(new X500Principal(value)); + } + + /** + * Returns the name value represented by this object + * + * @return the name + */ + public X500Principal getValue() { + return this.value; + } + + /** + * Returns true if the input is an instance of this class and if its + * value equals the value contained in this class. This method + * deviates slightly from the XACML spec in the way that it handles + * RDNs with multiple attributeTypeAndValue pairs and some + * additional canonicalization steps. This method uses + * the procedure used by + * javax.security.auth.x500.X500Principal.equals(), while the + * XACML spec uses a slightly different procedure. In practice, it is + * expected that this difference will not be noticeable. For more + * details, refer to the javadoc for X500Principal.equals() + * and the XACML specification. + * + * @param o the object to compare + * + * @return true if this object and the input represent the same value + */ + public boolean equals(Object o) { + if (! (o instanceof X500NameAttribute)) { + return false; + } + X500NameAttribute other = (X500NameAttribute)o; + + return this.value.equals(other.value); + } + + /** + * Returns the hashcode value used to index and compare this object with + * others of the same type. Typically this is the hashcode of the backing + * data object. + * + * @return the object's hashcode value + */ + public int hashCode() { + return this.value.hashCode(); + } + + /** + * @return The String encoding this AttributeValue. + */ + public String encode() { + return this.value.getName(); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/YearMonthDurationAttribute.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/YearMonthDurationAttribute.java new file mode 100644 index 0000000..60890ce --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/YearMonthDurationAttribute.java @@ -0,0 +1,428 @@ + +/* + * @(#)YearMonthDurationAttribute.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.attr; + +import com.sun.xacml.Constants; +import com.sun.xacml.ParsingException; + +import java.math.BigInteger; + +import java.net.URI; + +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; +import java.util.regex.Matcher; + +import org.w3c.dom.Node; + + +/** + * Representation of an xf:yearMonthDuration value. This class supports parsing + * xd:yearMonthDuration values. All objects of this class are immutable and + * thread-safe. The Date objects returned are not, but + * these objects are cloned before being returned. + * + * @since 1.0 + * @author Steve Hanna + */ +public class YearMonthDurationAttribute extends AttributeValue +{ + /** + * Official name of this type + */ + public static final String identifier = + TypeIdentifierConstants.YEARMONTHDURATION; + + /** + * URI version of name for this type + *

+ * This field is initialized by a static initializer so that + * we can catch any exceptions thrown by URI(String) and + * transform them into a RuntimeException, since this should + * never happen but should be reported properly if it ever does. + */ + private static URI identifierURI; + + /** + * RuntimeException that wraps an Exception thrown during the + * creation of identifierURI, null if none. + */ + private static RuntimeException earlyException; + + /** + * Static initializer that initializes the identifierURI + * class field so that we can catch any exceptions thrown + * by URI(String) and transform them into a RuntimeException. + * Such exceptions should never happen but should be reported + * properly if they ever do. + */ + static { + try { + identifierURI = URI.create(identifier); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * Regular expression for yearMonthDuration (a la java.util.regex) + */ + private static final String patternString = + "(\\-)?P((\\d+)?Y)?((\\d+)?M)?"; + + /** + * The index of the capturing group for the negative sign. + */ + private static final int GROUP_SIGN = 1; + + /** + * The index of the capturing group for the number of years. + */ + private static final int GROUP_YEARS = 3; + + /** + * The index of the capturing group for the number of months. + */ + private static final int GROUP_MONTHS = 5; + + /** + * Static BigInteger values. We only use these if one of + * the components is bigger than Integer.MAX_LONG and we + * want to detect overflow. + */ + private static BigInteger big12 = BigInteger.valueOf(12); + private static BigInteger bigMaxLong = BigInteger.valueOf(Long.MAX_VALUE); + + /** + * A shared Pattern object, only initialized if needed + */ + private static Pattern pattern; + + /** + * Negative flag. true if duration is negative, false otherwise + */ + private boolean negative; + + /** + * Number of years + */ + private long years; + + /** + * Number of months + */ + private long months; + + /** + * Total number of months (used for equals) + */ + private long totalMonths; + + /** + * Cached encoded value (null if not cached yet). + */ + private String encodedValue = null; + + /** + * Creates a new YearMonthDurationAttribute that represents + * the duration supplied. + * + * @param negative true if the duration is negative, false otherwise + * @param years the number of years in the duration (must be positive) + * @param months the number of months in the duration (must be positive) + * @throws IllegalArgumentException if the total number of months + * exceeds Long.MAX_LONG or the number + * of months or years is negative + */ + public YearMonthDurationAttribute(boolean negative, long years, + long months) + throws IllegalArgumentException { + super(identifierURI); + + // Shouldn't happen, but just in case... + if (earlyException != null) { + throw earlyException; + } + + this.negative = negative; + this.years = years; + this.months = months; + + // Convert all the components except nanoseconds to milliseconds + + // If any of the components is big (too big to be an int), + // use the BigInteger class to do the math so we can detect + // overflow. + if ((years > Integer.MAX_VALUE) || (months > Integer.MAX_VALUE)) { + BigInteger bigMonths = BigInteger.valueOf(months); + BigInteger bigYears = BigInteger.valueOf(years); + + BigInteger bigTotal = bigYears.multiply(big12).add(bigMonths); + + // If the result is bigger than Long.MAX_VALUE, we have an + // overflow. Indicate an error (should be a processing error, + // since it can be argued that we should handle gigantic + // values for this). + if (bigTotal.compareTo(bigMaxLong) == 1) { + throw new IllegalArgumentException("total number of " + + "months " + + "exceeds Long.MAX_VALUE"); + } + // If no overflow, convert to a long. + this.totalMonths = bigTotal.longValue(); + if (negative) { + this.totalMonths = - this.totalMonths; + } + } else { + // The numbers are small, so do it the fast way. + this.totalMonths = ((years * 12) + months) * (negative ? -1 : 1); + } + } + + /** + * Returns a new YearMonthDurationAttribute that represents + * the xf:yearMonthDuration at a particular DOM node. + * + * @param root the Node that contains the desired value + * @return a new YearMonthDurationAttribute representing the + * appropriate value + * @throws ParsingException if any problems occurred while parsing + */ + public static YearMonthDurationAttribute getInstance(Node root) + throws ParsingException { + if (root.getFirstChild() != null) { + return getInstance(root.getFirstChild().getNodeValue()); + } + throw new ParsingException("Error while parsing a " + + "YearMonthDurationAttribute"); + } + + /** + * Returns the long value for the capturing group groupNumber. + * This method takes a Matcher that has been used to match a + * Pattern against a String, fetches the value for the specified + * capturing group, converts that value to an long, and returns + * the value. If that group did not match, 0 is returned. + * If the matched value is not a valid long, NumberFormatException + * is thrown. + * + * @param matcher the Matcher from which to fetch the group + * @param groupNumber the group number to fetch + * @return the long value for that groupNumber + * @throws NumberFormatException if the string value for that + * groupNumber is not a valid long + */ + private static long parseGroup(Matcher matcher, int groupNumber) + throws NumberFormatException { + long groupLong = 0; + + if (matcher.start(groupNumber) != -1) { + String groupString = matcher.group(groupNumber); + groupLong = Long.parseLong(groupString); + } + return groupLong; + } + + /** + * Returns a new YearMonthDurationAttribute that represents + * the xf:yearMonthDuration value indicated by the string provided. + * + * @param value a string representing the desired value + * + * @return a new YearMonthDurationAttribute representing the + * desired value + * + * @throws ParsingException if any problems occurred while parsing + */ + public static YearMonthDurationAttribute getInstance(String value) + throws ParsingException { + if (value == null) { + throw new ParsingException("Can't create a " + + "YearMonthDurationAttribute from empty input"); + } + boolean negative = false; + long years = 0; + long months = 0; + + // Compile the pattern, if not already done. + if (pattern == null) { + try { + pattern = Pattern.compile(patternString); + } catch (PatternSyntaxException e) { + // This should never happen + throw new ParsingException("unexpected pattern syntax error"); + } + } + + // See if the value matches the pattern. + Matcher matcher = pattern.matcher(value); + boolean matches = matcher.matches(); + + // If not, syntax error! + if (!matches) { + throw new ParsingException("Syntax error in yearMonthDuration"); + } + + // If the negative group matched, the value is negative. + if (matcher.start(GROUP_SIGN) != -1) { + negative = true; + } + + try { + // If the years group matched, parse that value. + years = parseGroup(matcher, GROUP_YEARS); + + // If the months group matched, parse that value. + months = parseGroup(matcher, GROUP_MONTHS); + } catch (NumberFormatException e) { + // If we run into a number that's too big to be a long + // that's an error. Really, it's a processing error, + // since one can argue that we should handle that. + throw new ParsingException("Unable to handle number size"); + } + + // If parsing went OK, create a new YearMonthDurationAttribute + // object and return it. + return new YearMonthDurationAttribute(negative, years, months); + } + + /** + * Returns true if the duration is negative. + * + * @return true if the duration is negative, false otherwise + */ + public boolean isNegative() { + return this.negative; + } + + /** + * Gets the number of years. + * + * @return the number of years + */ + public long getYears() { + return this.years; + } + + /** + * Gets the number of months. + * + * @return the number of months + */ + public long getMonths() { + return this.months; + } + + /** + * Returns true if the input is an instance of this class and if its + * value equals the value contained in this class. + * + * @param o the object to compare + * + * @return true if this object and the input represent the same value + */ + public boolean equals(Object o) { + if (! (o instanceof YearMonthDurationAttribute)) { + return false; + } + + YearMonthDurationAttribute other = (YearMonthDurationAttribute)o; + + return (this.totalMonths == other.totalMonths); + } + + /** + * Returns the hashcode value used to index and compare this object with + * others of the same type. Typically this is the hashcode of the backing + * data object. + * + * @return the object's hashcode value + */ + public int hashCode() { + return (int) this.totalMonths ^ (int) (this.totalMonths >> 32); + } + + /** + * Converts to a String representation. + * + * @return the String representation + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("YearMonthDurationAttribute: [" + Constants.nl); + sb.append(" Negative: " + this.negative); + sb.append(" Years: " + this.years); + sb.append(" Months: " + this.months); + sb.append("]"); + + return sb.toString(); + } + + /** + * Encodes the value in a form suitable for including in XML data like + * a request or an obligation. This must return a value that could in + * turn be used by the factory to create a new instance with the same + * value. + * + * @return a String form of the value + */ + public String encode() { + if (this.encodedValue != null) { + return this.encodedValue; + } + + // Length is variable + StringBuffer buf = new StringBuffer(10); + + if (this.negative) { + buf.append('-'); + } + buf.append('P'); + if ((this.years != 0) || (this.months == 0)) { + buf.append(Long.toString(this.years)); + buf.append('Y'); + } + if (this.months != 0) { + buf.append(Long.toString(this.months)); + buf.append('M'); + } + + this.encodedValue = buf.toString(); + + return this.encodedValue; + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/package.html b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/package.html new file mode 100644 index 0000000..80a1d3a --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/package.html @@ -0,0 +1,7 @@ + + Contains many of the classes related to attributes and attribute + retrieval. This package contains the base class for all attributes, as + well as implementations of all of the standard attribute types. The + AttributeDesignatorType and the AttributeSelectorType are also + represented here. + diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/AnyURIAttributeProxy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/AnyURIAttributeProxy.java new file mode 100644 index 0000000..4a71921 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/AnyURIAttributeProxy.java @@ -0,0 +1,70 @@ + +/* + * @(#)AnyURIAttributeProxy.java + * + * Copyright 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.attr.proxy; + +import com.sun.xacml.attr.AnyURIAttribute; +import com.sun.xacml.attr.AttributeProxy; +import com.sun.xacml.attr.AttributeValue; + +import org.w3c.dom.Node; + + +/** + * A proxy class that is provided mainly for the run-time configuration + * code to use. + * + * @since 1.2 + * @author Seth Proctor + */ +public class AnyURIAttributeProxy implements AttributeProxy +{ + + /** + * @see com.sun.xacml.attr.AttributeProxy#getInstance(org.w3c.dom.Node) + */ + public AttributeValue getInstance(Node root) throws Exception { + return AnyURIAttribute.getInstance(root); + } + + /** + * @see com.sun.xacml.attr.AttributeProxy#getInstance(java.lang.String) + */ + public AttributeValue getInstance(String value) throws Exception { + return AnyURIAttribute.getInstance(value); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/Base64BinaryAttributeProxy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/Base64BinaryAttributeProxy.java new file mode 100644 index 0000000..8268078 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/Base64BinaryAttributeProxy.java @@ -0,0 +1,64 @@ + +/* + * @(#)Base64BinaryAttributeProxy.java + * + * Copyright 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.attr.proxy; + +import com.sun.xacml.attr.AttributeProxy; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.Base64BinaryAttribute; + +import org.w3c.dom.Node; + + +/** + * A proxy class that is provided mainly for the run-time configuration + * code to use. + * + * @since 1.2 + * @author Seth Proctor + */ +public class Base64BinaryAttributeProxy implements AttributeProxy +{ + + public AttributeValue getInstance(Node root) throws Exception { + return Base64BinaryAttribute.getInstance(root); + } + + public AttributeValue getInstance(String value) throws Exception { + return Base64BinaryAttribute.getInstance(value); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/BooleanAttributeProxy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/BooleanAttributeProxy.java new file mode 100644 index 0000000..41c2e64 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/BooleanAttributeProxy.java @@ -0,0 +1,64 @@ + +/* + * @(#)BooleanAttributeProxy.java + * + * Copyright 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.attr.proxy; + +import com.sun.xacml.attr.AttributeProxy; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BooleanAttribute; + +import org.w3c.dom.Node; + + +/** + * A proxy class that is provided mainly for the run-time configuration + * code to use. + * + * @since 1.2 + * @author Seth Proctor + */ +public class BooleanAttributeProxy implements AttributeProxy +{ + + public AttributeValue getInstance(Node root) throws Exception { + return BooleanAttribute.getInstance(root); + } + + public AttributeValue getInstance(String value) throws Exception { + return BooleanAttribute.getInstance(value); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/DNSNameAttributeProxy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/DNSNameAttributeProxy.java new file mode 100644 index 0000000..e5c3677 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/DNSNameAttributeProxy.java @@ -0,0 +1,65 @@ + +/* + * @(#)DNSNameAttributeProxy.java + * + * Copyright 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.attr.proxy; + +import com.sun.xacml.ParsingException; +import com.sun.xacml.attr.AttributeProxy; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.DNSNameAttribute; + +import org.w3c.dom.Node; + + +/** + * A proxy class that is provided mainly for the run-time configuration + * code to use. + * + * @since 2.0 + * @author Seth Proctor + */ +public class DNSNameAttributeProxy implements AttributeProxy +{ + + public AttributeValue getInstance(Node root) throws Exception { + return DNSNameAttribute.getInstance(root); + } + + public AttributeValue getInstance(String value) throws ParsingException { + return DNSNameAttribute.getInstance(value); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/DateAttributeProxy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/DateAttributeProxy.java new file mode 100644 index 0000000..ab057c3 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/DateAttributeProxy.java @@ -0,0 +1,64 @@ + +/* + * @(#)DateAttributeProxy.java + * + * Copyright 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.attr.proxy; + +import com.sun.xacml.attr.AttributeProxy; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.DateAttribute; + +import org.w3c.dom.Node; + + +/** + * A proxy class that is provided mainly for the run-time configuration + * code to use. + * + * @since 1.2 + * @author Seth Proctor + */ +public class DateAttributeProxy implements AttributeProxy +{ + + public AttributeValue getInstance(Node root) throws Exception { + return DateAttribute.getInstance(root); + } + + public AttributeValue getInstance(String value) throws Exception { + return DateAttribute.getInstance(value); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/DateTimeAttributeProxy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/DateTimeAttributeProxy.java new file mode 100644 index 0000000..764acb4 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/DateTimeAttributeProxy.java @@ -0,0 +1,64 @@ + +/* + * @(#)DateTimeAttributeProxy.java + * + * Copyright 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.attr.proxy; + +import com.sun.xacml.attr.AttributeProxy; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.DateTimeAttribute; + +import org.w3c.dom.Node; + + +/** + * A proxy class that is provided mainly for the run-time configuration + * code to use. + * + * @since 1.2 + * @author Seth Proctor + */ +public class DateTimeAttributeProxy implements AttributeProxy +{ + + public AttributeValue getInstance(Node root) throws Exception { + return DateTimeAttribute.getInstance(root); + } + + public AttributeValue getInstance(String value) throws Exception { + return DateTimeAttribute.getInstance(value); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/DayTimeDurationAttributeProxy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/DayTimeDurationAttributeProxy.java new file mode 100644 index 0000000..1c4174f --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/DayTimeDurationAttributeProxy.java @@ -0,0 +1,64 @@ + +/* + * @(#)DayTimeDurationAttributeProxy.java + * + * Copyright 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.attr.proxy; + +import com.sun.xacml.attr.AttributeProxy; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.DayTimeDurationAttribute; + +import org.w3c.dom.Node; + + +/** + * A proxy class that is provided mainly for the run-time configuration + * code to use. + * + * @since 1.2 + * @author Seth Proctor + */ +public class DayTimeDurationAttributeProxy implements AttributeProxy +{ + + public AttributeValue getInstance(Node root) throws Exception { + return DayTimeDurationAttribute.getInstance(root); + } + + public AttributeValue getInstance(String value) throws Exception { + return DayTimeDurationAttribute.getInstance(value); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/DoubleAttributeProxy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/DoubleAttributeProxy.java new file mode 100644 index 0000000..9538fb8 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/DoubleAttributeProxy.java @@ -0,0 +1,64 @@ + +/* + * @(#)DoubleAttributeProxy.java + * + * Copyright 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.attr.proxy; + +import com.sun.xacml.attr.AttributeProxy; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.DoubleAttribute; + +import org.w3c.dom.Node; + + +/** + * A proxy class that is provided mainly for the run-time configuration + * code to use. + * + * @since 1.2 + * @author Seth Proctor + */ +public class DoubleAttributeProxy implements AttributeProxy +{ + + public AttributeValue getInstance(Node root) throws Exception { + return DoubleAttribute.getInstance(root); + } + + public AttributeValue getInstance(String value) throws Exception { + return DoubleAttribute.getInstance(value); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/HexBinaryAttributeProxy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/HexBinaryAttributeProxy.java new file mode 100644 index 0000000..06d0702 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/HexBinaryAttributeProxy.java @@ -0,0 +1,64 @@ + +/* + * @(#)HexBinaryAttributeProxy.java + * + * Copyright 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.attr.proxy; + +import com.sun.xacml.attr.AttributeProxy; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.HexBinaryAttribute; + +import org.w3c.dom.Node; + + +/** + * A proxy class that is provided mainly for the run-time configuration + * code to use. + * + * @since 1.2 + * @author Seth Proctor + */ +public class HexBinaryAttributeProxy implements AttributeProxy +{ + + public AttributeValue getInstance(Node root) throws Exception { + return HexBinaryAttribute.getInstance(root); + } + + public AttributeValue getInstance(String value) throws Exception { + return HexBinaryAttribute.getInstance(value); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/IPAddressAttributeProxy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/IPAddressAttributeProxy.java new file mode 100644 index 0000000..a2d8a57 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/IPAddressAttributeProxy.java @@ -0,0 +1,66 @@ + +/* + * @(#)IPAddressAttributeProxy.java + * + * Copyright 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.attr.proxy; + +import com.sun.xacml.ParsingException; + +import com.sun.xacml.attr.AttributeProxy; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.IPAddressAttribute; + +import org.w3c.dom.Node; + + +/** + * A proxy class that is provided mainly for the run-time configuration + * code to use. + * + * @since 2.0 + * @author Seth Proctor + */ +public class IPAddressAttributeProxy implements AttributeProxy +{ + + public AttributeValue getInstance(Node root) throws ParsingException { + return IPAddressAttribute.getInstance(root); + } + + public AttributeValue getInstance(String value) throws ParsingException { + return IPAddressAttribute.getInstance(value); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/IntegerAttributeProxy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/IntegerAttributeProxy.java new file mode 100644 index 0000000..2081239 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/IntegerAttributeProxy.java @@ -0,0 +1,64 @@ + +/* + * @(#)IntegerAttributeProxy.java + * + * Copyright 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.attr.proxy; + +import com.sun.xacml.attr.AttributeProxy; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.IntegerAttribute; + +import org.w3c.dom.Node; + + +/** + * A proxy class that is provided mainly for the run-time configuration + * code to use. + * + * @since 1.2 + * @author Seth Proctor + */ +public class IntegerAttributeProxy implements AttributeProxy +{ + + public AttributeValue getInstance(Node root) throws Exception { + return IntegerAttribute.getInstance(root); + } + + public AttributeValue getInstance(String value) throws Exception { + return IntegerAttribute.getInstance(value); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/RFC822NameAttributeProxy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/RFC822NameAttributeProxy.java new file mode 100644 index 0000000..d7adcb3 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/RFC822NameAttributeProxy.java @@ -0,0 +1,64 @@ + +/* + * @(#)RFC822NameAttributeProxy.java + * + * Copyright 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.attr.proxy; + +import com.sun.xacml.attr.AttributeProxy; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.RFC822NameAttribute; + +import org.w3c.dom.Node; + + +/** + * A proxy class that is provided mainly for the run-time configuration + * code to use. + * + * @since 1.2 + * @author Seth Proctor + */ +public class RFC822NameAttributeProxy implements AttributeProxy +{ + + public AttributeValue getInstance(Node root) throws Exception { + return RFC822NameAttribute.getInstance(root); + } + + public AttributeValue getInstance(String value) throws Exception { + return RFC822NameAttribute.getInstance(value); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/StringAttributeProxy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/StringAttributeProxy.java new file mode 100644 index 0000000..c04677a --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/StringAttributeProxy.java @@ -0,0 +1,65 @@ + +/* + * @(#)StringAttributeProxy.java + * + * Copyright 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.attr.proxy; + +import com.sun.xacml.ParsingException; +import com.sun.xacml.attr.AttributeProxy; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.StringAttribute; + +import org.w3c.dom.Node; + + +/** + * A proxy class that is provided mainly for the run-time configuration + * code to use. + * + * @since 1.2 + * @author Seth Proctor + */ +public class StringAttributeProxy implements AttributeProxy +{ + + public AttributeValue getInstance(Node root) throws ParsingException { + return StringAttribute.getInstance(root); + } + + public AttributeValue getInstance(String value) { + return StringAttribute.getInstance(value); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/TimeAttributeProxy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/TimeAttributeProxy.java new file mode 100644 index 0000000..9b877b4 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/TimeAttributeProxy.java @@ -0,0 +1,64 @@ + +/* + * @(#)TimeAttributeProxy.java + * + * Copyright 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.attr.proxy; + +import com.sun.xacml.attr.AttributeProxy; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.TimeAttribute; + +import org.w3c.dom.Node; + + +/** + * A proxy class that is provided mainly for the run-time configuration + * code to use. + * + * @since 1.2 + * @author Seth Proctor + */ +public class TimeAttributeProxy implements AttributeProxy +{ + + public AttributeValue getInstance(Node root) throws Exception { + return TimeAttribute.getInstance(root); + } + + public AttributeValue getInstance(String value) throws Exception { + return TimeAttribute.getInstance(value); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/X500NameAttributeProxy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/X500NameAttributeProxy.java new file mode 100644 index 0000000..257ecaa --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/X500NameAttributeProxy.java @@ -0,0 +1,64 @@ + +/* + * @(#)X500NameAttributeProxy.java + * + * Copyright 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.attr.proxy; + +import com.sun.xacml.attr.AttributeProxy; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.X500NameAttribute; + +import org.w3c.dom.Node; + + +/** + * A proxy class that is provided mainly for the run-time configuration + * code to use. + * + * @since 1.2 + * @author Seth Proctor + */ +public class X500NameAttributeProxy implements AttributeProxy +{ + + public AttributeValue getInstance(Node root) throws Exception { + return X500NameAttribute.getInstance(root); + } + + public AttributeValue getInstance(String value) throws Exception { + return X500NameAttribute.getInstance(value); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/YearMonthDurationAttributeProxy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/YearMonthDurationAttributeProxy.java new file mode 100644 index 0000000..874014f --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/YearMonthDurationAttributeProxy.java @@ -0,0 +1,64 @@ + +/* + * @(#)YearMonthDurationAttributeProxy.java + * + * Copyright 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.attr.proxy; + +import com.sun.xacml.attr.AttributeProxy; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.YearMonthDurationAttribute; + +import org.w3c.dom.Node; + + +/** + * A proxy class that is provided mainly for the run-time configuration + * code to use. + * + * @since 1.2 + * @author Seth Proctor + */ +public class YearMonthDurationAttributeProxy implements AttributeProxy +{ + + public AttributeValue getInstance(Node root) throws Exception { + return YearMonthDurationAttribute.getInstance(root); + } + + public AttributeValue getInstance(String value) throws Exception { + return YearMonthDurationAttribute.getInstance(value); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/package.html b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/package.html new file mode 100644 index 0000000..9da00b5 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/attr/proxy/package.html @@ -0,0 +1,8 @@ + + This package defines proxy classes for all of the standard + datatypes. This package was introduced in version 1.2 with the new + run-time configuration code, which needs concrete proxy classes to add + datatype support to a factory. Before 1.2, the + AttributeFactory used annonymous classes to cut down on + the total number of files in this project. + diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/BaseCombiningAlgFactory.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/BaseCombiningAlgFactory.java new file mode 100644 index 0000000..972c058 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/BaseCombiningAlgFactory.java @@ -0,0 +1,156 @@ + +/* + * @(#)BaseCombiningAlgFactory.java + * + * Copyright 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.combine; + +import com.sun.xacml.UnknownIdentifierException; + +import java.net.URI; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Set; + + +/** + * This is a basic implementation of CombiningAlgFactory. It + * implements the insertion and retrieval methods, but doesn't actually + * setup the factory with any algorithms. + *

+ * Note that while this class is thread-safe on all creation methods, it + * is not safe to add support for a new algorithm while creating an instance + * of an algorithm. This follows from the assumption that most people will + * initialize these factories up-front, and then start processing without + * ever modifying the factories. If you need these mutual operations to + * be thread-safe, then you should write a wrapper class that implements + * the right synchronization. + * + * @since 1.2 + * @author Seth Proctor + */ +public class BaseCombiningAlgFactory extends CombiningAlgFactory +{ + + // the map of available combining algorithms + private HashMap algMap; + + /** + * Default constructor. + */ + public BaseCombiningAlgFactory() { + this.algMap = new HashMap(); + } + + /** + * Constructor that configures this factory with an initial set of + * supported algorithms. + * + * @param algorithms a Set of + * CombiningAlgorithms + * + * @throws IllegalArgumentException if any elements of the set are not + * CombiningAlgorithms + */ + public BaseCombiningAlgFactory(Set algorithms) { + this.algMap = new HashMap(); + + Iterator it = algorithms.iterator(); + while (it.hasNext()) { + try { + CombiningAlgorithm alg = it.next(); + this.algMap.put(alg.getIdentifier().toString(), alg); + } catch (ClassCastException cce) { + throw new IllegalArgumentException("an element of the set " + + "was not an instance of " + + "CombiningAlgorithm"); + } + } + } + + /** + * Adds a combining algorithm to the factory. This single instance will + * be returned to anyone who asks the factory for an algorithm with the + * id given here. + * + * @param alg the combining algorithm to add + * + * @throws IllegalArgumentException if the algId is already registered + */ + public void addAlgorithm(CombiningAlgorithm alg) { + String algId = alg.getIdentifier().toString(); + + // check that the id doesn't already exist in the factory + if (this.algMap.containsKey(algId)) { + throw new IllegalArgumentException("algorithm already registered: " + + algId); + } + // add the algorithm + this.algMap.put(algId, alg); + } + + /** + * Returns the algorithm identifiers supported by this factory. + * + * @return a Set of Strings + */ + public Set getSupportedAlgorithms() { + return Collections.unmodifiableSet(this.algMap.keySet()); + } + + /** + * Tries to return the correct combinging algorithm based on the + * given algorithm ID. + * + * @param algId the identifier by which the algorithm is known + * + * @return a combining algorithm + * + * @throws UnknownIdentifierException algId is unknown + */ + public CombiningAlgorithm createAlgorithm(URI algId) + throws UnknownIdentifierException + { + String id = algId.toString(); + + if (this.algMap.containsKey(id)) { + return (CombiningAlgorithm)(this.algMap.get(algId.toString())); + } + throw new UnknownIdentifierException("unknown combining algId: " + + id); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/CombinerElement.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/CombinerElement.java new file mode 100644 index 0000000..6186d2b --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/CombinerElement.java @@ -0,0 +1,130 @@ + +/* + * @(#)CombinerElement.java + * + * Copyright 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.combine; + +import com.sun.xacml.Indenter; +import com.sun.xacml.PolicyTreeElement; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; + + +/** + * Represents one input (a Rule, Policy, PolicySet, or reference) to a + * combining algorithm and combiner parameters associated with that input. + * + * @since 2.0 + * @author Seth Proctor + */ +public abstract class CombinerElement +{ + + // the element to be combined + private PolicyTreeElement element; + + // the parameters used with this element + private List parameters; + + /** + * Constructor that only takes an element. No parameters are associated + * with this element when combining. + * + * @param element a PolicyTreeElement to use in combining + */ + public CombinerElement(PolicyTreeElement element) { + this(element, null); + } + + /** + * Constructor that takes both the element to combine and its associated + * combiner parameters. + * + * @param element a PolicyTreeElement to use in combining + * @param parameters a (possibly empty) non-null List of + * CombinerParameters provided for general + * use (for all pre-2.0 policies this must be empty) + */ + public CombinerElement(PolicyTreeElement element, List parameters) { + this.element = element; + + if (parameters == null) { + this.parameters = Collections.unmodifiableList(new ArrayList()); + } else { + this.parameters = Collections. + unmodifiableList(new ArrayList(parameters)); + } + } + + /** + * Returns the PolicyTreeElement in this element. + * + * @return the PolicyTreeElement + */ + public PolicyTreeElement getElement() { + return this.element; + } + + /** + * Returns the CombinerParameters associated with this + * element. + * + * @return a List of CombinerParameters + */ + public List getParameters() { + return this.parameters; + } + + /** + * Encodes the element and parameters in this CombinerElement + * into their XML representation and writes this encoding to the given + * OutputStream 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 abstract void encode(OutputStream output, String charsetName, + Indenter indenter) + throws UnsupportedEncodingException; + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/CombinerParameter.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/CombinerParameter.java new file mode 100644 index 0000000..e3d4c96 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/CombinerParameter.java @@ -0,0 +1,204 @@ + +/* + * @(#)CombinerParameter.java + * + * Copyright 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.combine; + +import com.sun.xacml.Indenter; +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; + +import com.sun.xacml.attr.AttributeFactory; +import com.sun.xacml.attr.AttributeValue; +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.util.Collections; +import java.util.List; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + + +/** + * Represents a single named parameter to a combining algorithm. Parameters + * are only used by XACML 2.0 and later policies. + * + * @since 2.0 + * @author Seth Proctor + */ +public class CombinerParameter implements Locatable +{ + + // the name of this parameter + private String name; + + // the value of this parameter + private AttributeValue value; + + public static final List EMPTY_LIST = Collections.emptyList(); + + private RuntimeInfo src; + + /** + * Creates a new CombinerParameter. + * + * @param name the parameter's name + * @param value the parameter's value + */ + public CombinerParameter(String name, AttributeValue value) { + this.name = name; + this.value = value; + } + + /** + * Returns a new instance of the CombinerParameter class + * based on a DOM node. The node must be the root of an XML + * CombinerParameterType. + * + * @param root the DOM root of a CombinerParameterType XML type + * + * @return The combiner parameter. + * + * @throws ParsingException if the CombinerParameterType is invalid + */ + public static CombinerParameter getInstance(Node root) + throws ParsingException { + RuntimeInfo src = RuntimeInfo.getRuntimeInfo(root, ELEMENT_TYPE.COMBINER_PARAMETER); + // check if this really is a CombinerParameter + if (root.getNodeType() != Node.ELEMENT_NODE + || !root.getLocalName().equals("CombinerParameter")) { + throw new ParsingException("Can't create a CombinerParameter " + + "from a " + root.getLocalName() + " element" + + ( src == null ? "" : src.getLocationMsgForError())); + } + // get the name, which is a required attribute + String name = null; + if (root.getAttributes().getNamedItem("ParameterName") != null) { + name = root.getAttributes().getNamedItem("ParameterName") + .getNodeValue(); + } else { + throw new ParsingException("Required XML attribute ParameterName" + + " not found while parsing a CombinerParameter" + + ( src == null ? "" : src.getLocationMsgForError())); + } + + // get the attribute value, the only child of this element + AttributeFactory attrFactory = AttributeFactory.getInstance(); + AttributeValue value = null; + + NodeList children = root.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + if ( child.getNodeType() == Node.ELEMENT_NODE ) { + try { + value = attrFactory.createValue(child); + break; + } catch (UnknownIdentifierException uie) { + throw new ParsingException("Unknown AttributeId" + + ( src == null ? "" : src.getLocationMsgForError()), uie); + } + } + } + if ( value == null ) { + throw new ParsingException("Missing AttributeValue for CombinerParameter" + + ( src == null ? "" : src.getLocationMsgForError())); + } + + CombinerParameter param = new CombinerParameter(name, value); + param.src = src; + return param; + } + + /** + * Returns the name of this parameter. + * + * @return the name of this parameter + */ + public String getName() { + return this.name; + } + + /** + * Returns the value provided by this parameter. + * + * @return the value provided by this parameter + */ + public AttributeValue getValue() { + return this.value; + } + + /** + * Encodes this parameter into its XML representation and writes this + * encoding to the given OutputStream 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 + ""); + indenter.in(); + + getValue().encode(output, charsetName, indenter); + + out.println(indent + ""); + indenter.out(); + } + + public RuntimeInfo getRuntimeInfo() { + return src; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/CombiningAlgFactory.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/CombiningAlgFactory.java new file mode 100644 index 0000000..bff1eb4 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/CombiningAlgFactory.java @@ -0,0 +1,273 @@ + +/* + * @(#)CombiningAlgFactory.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.combine; + +import com.sun.xacml.Constants; +import com.sun.xacml.UnknownIdentifierException; + +import java.net.URI; + +import java.util.HashMap; +import java.util.Set; + + +/** + * Provides a factory mechanism for installing and retrieving combining + * algorithms. + * + * @since 1.0 + * @author Seth Proctor + */ +public abstract class CombiningAlgFactory +{ + + // the proxy used to get the default factory + private static CombiningAlgFactoryProxy defaultFactoryProxy; + + // the map of registered factories + private static HashMap registeredFactories + = new HashMap(); + + // ignores the configuration, i.e., +// /** +// * static intialiazer that sets up the default factory proxy and +// * registers the standard namespaces +// */ +// static { +// CombiningAlgFactoryProxy proxy = new CombiningAlgFactoryProxy() { +// public CombiningAlgFactory getFactory() { +// return StandardCombiningAlgFactory.getFactory(); +// } +// }; +// +// registeredFactories = new HashMap(); +// registeredFactories.put(Constants.XACML_1_0_IDENTIFIER, proxy); +// registeredFactories.put(Constants.XACML_2_0_IDENTIFIER, proxy); +// registeredFactories.put(Constants.XACML_3_0_IDENTIFIER, proxy); +// +// defaultFactoryProxy = proxy; +// } + // + + /** + * Default constructor. Used only by subclasses. + */ + protected CombiningAlgFactory() { + //used only by subclasses + } + + /** + * Returns the default factory. Depending on the default factory's + * implementation, this may return a singleton instance or new instances + * with each invokation. + * + * @return the default CombiningAlgFactory + */ + public static final CombiningAlgFactory getInstance() { + return defaultFactoryProxy.getFactory(); + } + + /** + * Returns a factory based on the given identifier. You may register + * as many factories as you like, and then retrieve them through this + * interface, but a factory may only be registered once using a given + * identifier. By default, the standard XACML 1.0, 2.0 and 3.0 identifiers + * are regsietered to provide the standard factory. + * + * @param identifier the identifier for a factory + * + * @return a CombiningAlgFactory + * + * @throws UnknownIdentifierException if the given identifier isn't + * registered + */ + public static final CombiningAlgFactory getInstance(String identifier) + throws UnknownIdentifierException + { + CombiningAlgFactoryProxy proxy = + (CombiningAlgFactoryProxy)(registeredFactories.get(identifier)); + + if (proxy == null) { + throw new UnknownIdentifierException("Uknown CombiningAlgFactory " + + "identifier: " + + identifier); + } + return proxy.getFactory(); + } + + /** + * Sets the default factory. This does not register the factory proxy as + * an identifiable factory. + * + * @param proxy the CombiningAlgFactoryProxy to set as the + * new default factory proxy + */ + public static final void setDefaultFactory(CombiningAlgFactoryProxy proxy) + { + defaultFactoryProxy = proxy; + } + + public static final void setAllFactories(CombiningAlgFactory factory) { + + CombiningAlgFactoryProxyImpl proxy = new CombiningAlgFactoryProxyImpl(factory); + + registeredFactories.put(Constants.XACML_1_0_IDENTIFIER, proxy); + registeredFactories.put(Constants.XACML_2_0_IDENTIFIER, proxy); + registeredFactories.put(Constants.XACML_3_0_IDENTIFIER, proxy); + + defaultFactoryProxy = proxy; + } + + /** + * Registers the given factory proxy with the given identifier. If the + * identifier is already used, then this throws an exception. If the + * identifier is not already used, then it will always be bound to the + * given proxy. + * + * @param identifier the identifier for the proxy + * @param proxy the CombiningAlgFactoryProxy to register with + * the given identifier + * + * @throws IllegalArgumentException if the identifier is already used + */ + public static final void registerFactory(String identifier, + CombiningAlgFactoryProxy proxy) + throws IllegalArgumentException + { + synchronized (registeredFactories) { + if (registeredFactories.containsKey(identifier)) { + throw new IllegalArgumentException("Identifier is already " + + "registered as " + + "CombiningAlgFactory: " + + identifier); + } + + registeredFactories.put(identifier, proxy); + } + } + + + + /** + * Adds a combining algorithm to the factory. This single instance will + * be returned to anyone who asks the factory for an algorithm with the + * id given here. + * + * @param alg the combining algorithm to add + * + * @throws IllegalArgumentException if the algorithm is already registered + */ + public abstract void addAlgorithm(CombiningAlgorithm alg); + + /** + * Adds a combining algorithm to the factory. This single instance will + * be returned to anyone who asks the factory for an algorithm with the + * id given here. + * + * @deprecated As of version 1.2, replaced by + * {@link #addAlgorithm(CombiningAlgorithm)}. + * The new factory system requires you to get a factory + * instance and then call the non-static methods on that + * factory. The static versions of these methods have been + * left in for now, but are slower and will be removed in + * a future version. + * + * @param alg the combining algorithm to add + * + * @throws IllegalArgumentException if the algorithm is already registered + */ + public static void addCombiningAlg(CombiningAlgorithm alg) { + getInstance().addAlgorithm(alg); + } + + /** + * Returns the algorithm identifiers supported by this factory. + * + * @return a Set of Strings + */ + public abstract Set getSupportedAlgorithms(); + + /** + * Tries to return the correct combinging algorithm based on the + * given algorithm ID. + * + * @param algId the identifier by which the algorithm is known + * + * @return a combining algorithm + * + * @throws UnknownIdentifierException algId is unknown + */ + public abstract CombiningAlgorithm createAlgorithm(URI algId) + throws UnknownIdentifierException; + + /** + * Tries to return the correct combinging algorithm based on the + * given algorithm ID. + * + * @deprecated As of version 1.2, replaced by + * {@link #createAlgorithm(URI)}. + * The new factory system requires you to get a factory + * instance and then call the non-static methods on that + * factory. The static versions of these methods have been + * left in for now, but are slower and will be removed in + * a future version. + * + * @param algId the identifier by which the algorithm is known + * + * @return a combining algorithm + * + * @throws UnknownIdentifierException algId is unknown + */ + public static CombiningAlgorithm createCombiningAlg(URI algId) + throws UnknownIdentifierException + { + return getInstance().createAlgorithm(algId); + } + + private static class CombiningAlgFactoryProxyImpl implements CombiningAlgFactoryProxy { + + CombiningAlgFactory factory; + + CombiningAlgFactoryProxyImpl(CombiningAlgFactory factory) { + this.factory = factory; + } + + public CombiningAlgFactory getFactory() { + return factory; + } + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/CombiningAlgFactoryProxy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/CombiningAlgFactoryProxy.java new file mode 100644 index 0000000..48802a0 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/CombiningAlgFactoryProxy.java @@ -0,0 +1,58 @@ + +/* + * @(#)CombiningAlgFactoryProxy.java + * + * Copyright 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.combine; + + +/** + * A simple proxy interface used to install new + * CombiningAlgFactorys. + * + * @since 1.2 + * @author Seth Proctor + */ +public interface CombiningAlgFactoryProxy +{ + + /** + * Returns an instance of the CombiningAlgFactory for which + * this is a proxy. + * + * @return a CombiningAlgFactory instance + */ + public CombiningAlgFactory getFactory(); + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/CombiningAlgorithm.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/CombiningAlgorithm.java new file mode 100644 index 0000000..2607a39 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/CombiningAlgorithm.java @@ -0,0 +1,161 @@ + +/* + * @(#)CombiningAlgorithm.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.combine; + + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.ctx.Result; +import com.sun.xacml.debug.IndirectLocatable; +import com.sun.xacml.debug.RuntimeInfo; + +import java.net.URI; + +import java.util.List; +import java.util.Stack; + +import org.apache.log4j.Logger; + + +/** + * The base type for all combining algorithms. It provides one method that + * must be implemented. + * + * @since 1.0 + * @author Seth Proctor + */ +public abstract class CombiningAlgorithm implements IndirectLocatable +{ + + // the identifier for the algorithm + private URI identifier; + + //private RuntimeInfo src; + private Stack src; + + private static Logger logger = Logger.getLogger(CombiningAlgorithm.class); + + + + /** + * Constructor that takes the algorithm's identifier. + * + * @param identifier the algorithm's identifier + */ + public CombiningAlgorithm(URI identifier) { + this.identifier = identifier; + } + + /** + * Combines the results of the inputs based on the context to produce + * some unified result. This is the one function of a combining algorithm. + * + * @param context the representation of the request + * @param parameters a (possibly empty) non-null List of + * CombinerParameters provided for general + * use (for all pre-2.0 policies this must be empty) + * @param inputs a List of CombinerElementss to + * evaluate and combine + * + * @return a single unified result based on the combining logic + */ + public abstract Result combine(EvaluationCtx context, List parameters, + List inputs); + + /** + * Returns the identifier for this algorithm. + * + * @return the algorithm's identifier + */ + public URI getIdentifier() { + return this.identifier; + } + + public RuntimeInfo getRuntimeInfo() { + if ( this.src != null && this.src.size() > 0 ) { + return this.src.get(this.src.size()-1); + } else { + return null; + } + + //return this.src; + } + + /** + * Implements the IndirectLocatable interface + */ + public void setRuntimeInfo(RuntimeInfo src) { + if ( this.src == null ) { + this.src = new Stack(); + } + this.src.push(src); +// if ( this.src != null ) { +// logger.warn("Overwriting SourceLocator! This indicates that " + +// "serveral threads are used to query the enginge which " + +// "should NOT be the case when the source locator feature " + +// "is enabled (overwrite" + +// ( this.src == null ? "null" : this.src.getLocationMsgForError()) + " with " + +// ( src == null ? "null" : src.getLocationMsgForError())); +// try { +// throw new Exception(); +// } catch(Exception e) { +// e.printStackTrace(); +// } +// } +// this.src = src; + } + + /** + * Implements the IndirectLocatable interface + */ + public void unsetRuntimeInfo(RuntimeInfo src) { + if ( this.src != null ) { + RuntimeInfo src_pop = this.src.pop(); + if ( src_pop != src ) { + logger.warn("Unset Source Locator Object which did not match the current " + + "element on the stack"); + this.src.removeAllElements(); + } + } +// if ( src != this.src ) { +// logger.warn("Unset Source Locator Object which is currently unvalid! (from " + +// ( this.src == null ? "null" : this.src.getLocationMsgForError()) + " with " + +// ( src == null ? "null" : src.getLocationMsgForError())); +// } +// this.src = null; + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/DenyOverridesPolicyAlg.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/DenyOverridesPolicyAlg.java new file mode 100644 index 0000000..85e46f1 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/DenyOverridesPolicyAlg.java @@ -0,0 +1,179 @@ + +/* + * @(#)DenyOverridesPolicyAlg.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.combine; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.MatchResult; +import com.sun.xacml.Obligation; + +import com.sun.xacml.ctx.Result; + +import java.net.URI; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + + +/** + * This is the standard Deny Overrides policy combining algorithm. It + * allows a single evaluation of Deny to take precedence over any number + * of permit, not applicable or indeterminate results. Note that since + * this implementation does an ordered evaluation, this class also + * supports the Ordered Deny Overrides algorithm. + * + * @since 1.0 + * @author Seth Proctor + */ +public class DenyOverridesPolicyAlg extends PolicyCombiningAlgorithm +{ + + /** + * The standard URN used to identify this algorithm + */ + public static final String algId = + "urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:" + + "deny-overrides"; + + // a URI form of the identifier + private static URI identifierURI; + // exception if the URI was invalid, which should never be a problem + private static RuntimeException earlyException; + + static { + try { + identifierURI = URI.create(algId); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * Standard constructor. + */ + public DenyOverridesPolicyAlg() { + super(identifierURI); + + if (earlyException != null) { + throw earlyException; + } + } + + /** + * Protected constructor used by the ordered version of this algorithm. + * + * @param identifier the algorithm's identifier + */ + protected DenyOverridesPolicyAlg(URI identifier) { + super(identifier); + } + + /** + * Applies the combining rule to the set of policies based on the + * evaluation context. + * + * @param context the context from the request + * @param parameters a (possibly empty) non-null List of + * CombinerParameters + * @param policyElements the policies to combine + * + * @return the result of running the combining algorithm + */ + public Result combine(EvaluationCtx context, List parameters, + List policyElements) { + boolean atLeastOnePermit = false; + Set permitObligations = new HashSet(); + Iterator it = policyElements.iterator(); + + while (it.hasNext()) { + AbstractPolicy policy = ((PolicyCombinerElement) it.next()).getPolicy(); + + // make sure that the policy matches the context + context.newEvent(policy); + MatchResult match = policy.match(context); + + if (match.getResult() == MatchResult.INDETERMINATE) { + Result result = new Result(Result.DECISION_DENY, context); + context.closeCurrentEvent(result); + return result; + } + + if (match.getResult() == MatchResult.NO_MATCH) { + context.closeCurrentEvent( + new Result(Result.DECISION_NOT_APPLICABLE)); + } + + if (match.getResult() == MatchResult.MATCH) { + // evaluate the policy + Result result = policy.evaluate(context); + context.closeCurrentEvent(result); + // do not treat the discarded values + if (result != null) { + int effect = result.getDecision(); + + // unlike in the RuleCombining version of this alg, we + // always return DENY if any Policy returns DENY or + // INDETERMINATE + if ((effect == Result.DECISION_DENY) || + (effect == Result.DECISION_INDETERMINATE)) { + return new Result(Result.DECISION_DENY, + context, + result.getObligations()); + } + + // remember if at least one Policy said PERMIT + if (effect == Result.DECISION_PERMIT) { + atLeastOnePermit = true; + permitObligations.addAll(result.getObligations()); + } + } + } + } + + // if we got a PERMIT, return it, otherwise it's NOT_APPLICABLE + if (atLeastOnePermit) { + return new Result(Result.DECISION_PERMIT, + context, + permitObligations); + } + return new Result(Result.DECISION_NOT_APPLICABLE, + context); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/DenyOverridesRuleAlg.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/DenyOverridesRuleAlg.java new file mode 100644 index 0000000..4d08803 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/DenyOverridesRuleAlg.java @@ -0,0 +1,184 @@ + +/* + * @(#)DenyOverridesRuleAlg.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.combine; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.Rule; + +import com.sun.xacml.ctx.Result; + +import java.net.URI; + +import java.util.Iterator; +import java.util.List; + + +/** + * This is the standard Deny Overrides rule combining algorithm. It + * allows a single evaluation of Deny to take precedence over any number + * of permit, not applicable or indeterminate results. Note that since + * this implementation does an ordered evaluation, this class also + * supports the Ordered Deny Overrides algorithm. + * + * @since 1.0 + * @author Seth Proctor + */ +public class DenyOverridesRuleAlg extends RuleCombiningAlgorithm +{ + + /** + * The standard URN used to identify this algorithm + */ + public static final String algId = + "urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:" + + "deny-overrides"; + + // a URI form of the identifier + private static URI identifierURI; + // exception if the URI was invalid, which should never be a problem + private static RuntimeException earlyException; + + static { + try { + identifierURI = URI.create(algId); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * Standard constructor. + */ + public DenyOverridesRuleAlg() { + super(identifierURI); + + if (earlyException != null) { + throw earlyException; + } + } + + /** + * Protected constructor used by the ordered version of this algorithm. + * + * @param identifier the algorithm's identifier + */ + protected DenyOverridesRuleAlg(URI identifier) { + super(identifier); + } + + /** + * Applies the combining rule to the set of rules based on the + * evaluation context. + * + * @param context the context from the request + * @param parameters a (possibly empty) non-null List of + * CombinerParameters + * @param ruleElements the rules to combine + * + * @return the result of running the combining algorithm + */ + public Result combine(EvaluationCtx context, List parameters, + List ruleElements) { + boolean atLeastOneError = false; + boolean potentialDeny = false; + boolean atLeastOnePermit = false; + Result firstIndeterminateResult = null; + Iterator it = ruleElements.iterator(); + + while (it.hasNext()) { + Rule rule = ((RuleCombinerElement)(it.next())).getRule(); + Result result = rule.evaluate(context); + int value = result.getDecision(); + + // if there was a value of DENY, then regardless of what else + // we've seen, we always return DENY + if (value == Result.DECISION_DENY) { + return result; + } + + // if it was INDETERMINATE, then we couldn't figure something + // out, so we keep track of these cases... + if (value == Result.DECISION_INDETERMINATE) { + atLeastOneError = true; + + // there are no rules about what to do if multiple cases + // cause errors, so we'll just return the first one + if (firstIndeterminateResult == null) { + firstIndeterminateResult = result; + } + + // if the Rule's effect is DENY, then we can't let this + // alg return PERMIT, since this Rule might have denied + // if it could do its stuff + if (rule.getEffect() == Result.DECISION_DENY) { + potentialDeny = true; + } + } else { + // keep track of whether we had at least one rule that + // actually pertained to the request + if (value == Result.DECISION_PERMIT) { + atLeastOnePermit = true; + } + } + } + + // we didn't explicitly DENY, but we might have had some Rule + // been evaluated, so we have to return INDETERMINATE + if (potentialDeny) { + return firstIndeterminateResult; + } + + // some Rule said PERMIT, so since nothing could have denied, + // we return PERMIT + if (atLeastOnePermit) { + return new Result(Result.DECISION_PERMIT, + context); + } + + // we didn't find anything that said PERMIT, but if we had a + // problem with one of the Rules, then we're INDETERMINATE + if (atLeastOneError) { + return firstIndeterminateResult; + } + + // if we hit this point, then none of the rules actually applied + // to us, so we return NOT_APPLICABLE + return new Result(Result.DECISION_NOT_APPLICABLE, + context); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/FirstApplicablePolicyAlg.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/FirstApplicablePolicyAlg.java new file mode 100644 index 0000000..72bd17d --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/FirstApplicablePolicyAlg.java @@ -0,0 +1,152 @@ + +/* + * @(#)FirstApplicablePolicyAlg.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.combine; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.MatchResult; + +import com.sun.xacml.ctx.Result; + +import java.net.URI; + +import java.util.Iterator; +import java.util.List; + + +/** + * This is the standard First Applicable policy combining algorithm. It looks + * through the set of policies, finds the first one that applies, and returns + * that evaluation result. + * + * @since 1.0 + * @author Seth Proctor + */ +public class FirstApplicablePolicyAlg extends PolicyCombiningAlgorithm +{ + + /** + * The standard URN used to identify this algorithm + */ + public static final String algId = + "urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:" + + "first-applicable"; + + // a URI form of the identifier + private static URI identifierURI; + // exception if the URI was invalid, which should never be a problem + private static RuntimeException earlyException; + + static { + try { + identifierURI = URI.create(algId); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * Standard constructor. + */ + public FirstApplicablePolicyAlg() { + super(identifierURI); + + if (earlyException != null) { + throw earlyException; + } + } + + /** + * Applies the combining rule to the set of policies based on the + * evaluation context. + * + * @param context the context from the request + * @param parameters a (possibly empty) non-null List of + * CombinerParameters + * @param policyElements the policies to combine + * + * @return the result of running the combining algorithm + */ + public Result combine(EvaluationCtx context, List parameters, + List policyElements) { + Iterator it = policyElements.iterator(); + + while (it.hasNext()) { + AbstractPolicy policy = + ((PolicyCombinerElement)(it.next())).getPolicy(); + + // make sure that the policy matches the context + context.newEvent(policy); + MatchResult match = policy.match(context); + + if (match.getResult() == MatchResult.INDETERMINATE) { + Result result = new Result(Result.DECISION_INDETERMINATE, + match.getStatus(), + context); + context.closeCurrentEvent(result); + return result; + } + + if (match.getResult() == MatchResult.NO_MATCH) { + context.closeCurrentEvent( + new Result(Result.DECISION_NOT_APPLICABLE)); + } + + if (match.getResult() == MatchResult.MATCH) { + // evaluate the policy + Result result = policy.evaluate(context); + context.closeCurrentEvent(result); + // do not treat the discarded values + if (result != null) { + int effect = result.getDecision(); + + // in the case of PERMIT, DENY, or INDETERMINATE, we always + // just return that result, so only on a rule that doesn't + // apply do we keep going... + if (effect != Result.DECISION_NOT_APPLICABLE) { + return result; + } + } + } + } + + // if we got here, then none of the rules applied + return new Result(Result.DECISION_NOT_APPLICABLE, + context); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/FirstApplicableRuleAlg.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/FirstApplicableRuleAlg.java new file mode 100644 index 0000000..4adddb4 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/FirstApplicableRuleAlg.java @@ -0,0 +1,128 @@ + +/* + * @(#)FirstApplicableRuleAlg.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.combine; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.Rule; + +import com.sun.xacml.ctx.Result; + +import java.net.URI; + +import java.util.Iterator; +import java.util.List; + + +/** + * This is the standard First Applicable rule combining algorithm. It looks + * through the set of rules, finds the first one that applies, and returns + * that evaluation result. + * + * @since 1.0 + * @author Seth Proctor + */ +public class FirstApplicableRuleAlg extends RuleCombiningAlgorithm +{ + + /** + * The standard URN used to identify this algorithm + */ + public static final String algId = + "urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:" + + "first-applicable"; + + // a URI form of the identifier + private static URI identifierURI; + // exception if the URI was invalid, which should never be a problem + private static RuntimeException earlyException; + + static { + try { + identifierURI = URI.create(algId); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * Standard constructor. + */ + public FirstApplicableRuleAlg() { + super(identifierURI); + + if (earlyException != null) { + throw earlyException; + } + } + + + + /** + * Applies the combining rule to the set of rules based on the + * evaluation context. + * + * @param context the context from the request + * @param parameters a (possibly empty) non-null List of + * CombinerParameters + * @param ruleElements the rules to combine + * + * @return the result of running the combining algorithm + */ + public Result combine(EvaluationCtx context, List parameters, + List ruleElements) { + + Iterator it = ruleElements.iterator(); + + while (it.hasNext()) { + Rule rule = ((RuleCombinerElement)(it.next())).getRule(); + Result result = rule.evaluate(context); + int value = result.getDecision(); + + // in the case of PERMIT, DENY, or INDETERMINATE, we always + // just return that result, so only on a rule that doesn't + // apply do we keep going... + if (value != Result.DECISION_NOT_APPLICABLE) { + return result; + } + } + + // if we got here, then none of the rules applied + return new Result(Result.DECISION_NOT_APPLICABLE, + context); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/OnlyOneApplicablePolicyAlg.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/OnlyOneApplicablePolicyAlg.java new file mode 100644 index 0000000..5ad2861 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/OnlyOneApplicablePolicyAlg.java @@ -0,0 +1,175 @@ + +/* + * @(#)OnlyOneApplicablePolicyAlg.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.combine; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.MatchResult; + +import com.sun.xacml.ctx.Result; +import com.sun.xacml.ctx.Status; + +import java.net.URI; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + + +/** + * This is the standard Only One Applicable Policy combining algorithm. This + * is a special algorithm used at the root of a policy/pdp to make sure that + * pdp only selects one policy per request. + * + * @since 1.0 + * @author Seth Proctor + */ +public class OnlyOneApplicablePolicyAlg extends PolicyCombiningAlgorithm +{ + + /** + * The standard URN used to identify this algorithm + */ + public static final String algId = + "urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:" + + "only-one-applicable"; + + // a URI form of the identifier + private static URI identifierURI; + // exception if the URI was invalid, which should never be a problem + private static RuntimeException earlyException; + + static { + try { + identifierURI = URI.create(algId); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * Standard constructor. + */ + public OnlyOneApplicablePolicyAlg() { + super(identifierURI); + + if (earlyException != null) { + throw earlyException; + } + } + + + + /** + * Applies the combining rule to the set of policies based on the + * evaluation context. + * + * @param context the context from the request + * @param parameters a (possibly empty) non-null List of + * CombinerParameters + * @param policyElements the policies to combine + * + * @return the result of running the combining algorithm + */ + public Result combine(EvaluationCtx context, List parameters, + List policyElements) { + boolean atLeastOne = false; + AbstractPolicy selectedPolicy = null; + Iterator it = policyElements.iterator(); + + while (it.hasNext()) { + AbstractPolicy policy = + ((PolicyCombinerElement)(it.next())).getPolicy(); + + // see if the policy matches the context + context.newEvent(policy); + MatchResult match = policy.match(context); + + // if there is an error in trying to match any of the targets, + // we always return INDETERMINATE immediately + if (match.getResult() == MatchResult.INDETERMINATE) { + Result result = new Result(Result.DECISION_INDETERMINATE, + match.getStatus(), + context); + context.closeCurrentEvent(result); + return result; + } + + if (match.getResult() == MatchResult.NO_MATCH) { + context.closeCurrentEvent( + new Result(Result.DECISION_NOT_APPLICABLE)); + } + + if (match.getResult() == MatchResult.MATCH) { + // if this isn't the first match, then this is an error + if (atLeastOne) { + List code = new ArrayList(); + code.add(Status.STATUS_PROCESSING_ERROR); + String message = "Too many applicable policies"; + Result result = new Result(Result.DECISION_INDETERMINATE, + new Status(code, message), + context); + context.closeCurrentEvent(result); + return result; + } + + // if this was the first applicable policy in the set, then + // remember it for later + atLeastOne = true; + selectedPolicy = policy; + context.closeCurrentEvent("Evaluated later"); + } + } + + // if we got through the loop and found exactly one match, then + // we return the evaluation result of that policy + if (atLeastOne) { + context.newEvent(selectedPolicy); + Result result = selectedPolicy.evaluate(context); + context.closeCurrentEvent(result); + // do not treat the discarded values + if (result != null) { + return result; + } + } + + // if we didn't find a matching policy, then we don't apply + return new Result(Result.DECISION_NOT_APPLICABLE, + context); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/OrderedDenyOverridesPolicyAlg.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/OrderedDenyOverridesPolicyAlg.java new file mode 100644 index 0000000..5e03fcb --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/OrderedDenyOverridesPolicyAlg.java @@ -0,0 +1,85 @@ + +/* + * OrderedDenyOverridesPolicyAlg.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.combine; + +import java.net.URI; + + +/** + * This is the standard Ordered Deny Overrides policy combining algorithm. It + * allows a single evaluation of Deny to take precedence over any number + * of permit, not applicable or indeterminate results. Note that this uses + * the regular Deny Overrides implementation since it is also orderd. + * + * @since 1.1 + * @author seth proctor + */ +public class OrderedDenyOverridesPolicyAlg extends DenyOverridesPolicyAlg +{ + + /** + * The standard URN used to identify this algorithm + */ + public static final String algId = + "urn:oasis:names:tc:xacml:1.1:policy-combining-algorithm:" + + "ordered-deny-overrides"; + + // a URI form of the identifier + private static URI identifierURI; + // exception if the URI was invalid, which should never be a problem + private static RuntimeException earlyException; + + static { + try { + identifierURI = URI.create(algId); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * Standard constructor. + */ + public OrderedDenyOverridesPolicyAlg() { + super(identifierURI); + + if (earlyException != null) { + throw earlyException; + } + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/OrderedDenyOverridesRuleAlg.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/OrderedDenyOverridesRuleAlg.java new file mode 100644 index 0000000..9969dcf --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/OrderedDenyOverridesRuleAlg.java @@ -0,0 +1,85 @@ + +/* + * @(#)OrderedDenyOverridesRuleAlg.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.combine; + +import java.net.URI; + + +/** + * This is the standard Ordered Deny Overrides rule combining algorithm. It + * allows a single evaluation of Deny to take precedence over any number + * of permit, not applicable or indeterminate results. Note that this uses + * the regular Deny Overrides implementation since it is also orderd. + * + * @since 1.1 + * @author seth proctor + */ +public class OrderedDenyOverridesRuleAlg extends DenyOverridesRuleAlg +{ + + /** + * The standard URN used to identify this algorithm + */ + public static final String algId = + "urn:oasis:names:tc:xacml:1.1:rule-combining-algorithm:" + + "ordered-deny-overrides"; + + // a URI form of the identifier + private static URI identifierURI; + // exception if the URI was invalid, which should never be a problem + private static RuntimeException earlyException; + + static { + try { + identifierURI = URI.create(algId); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * Standard constructor. + */ + public OrderedDenyOverridesRuleAlg() { + super(identifierURI); + + if (earlyException != null) { + throw earlyException; + } + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/OrderedPermitOverridesPolicyAlg.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/OrderedPermitOverridesPolicyAlg.java new file mode 100644 index 0000000..0f63ede --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/OrderedPermitOverridesPolicyAlg.java @@ -0,0 +1,85 @@ + +/* + * @(#)OrderedPermitOverridesPolicyAlg.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.combine; + +import java.net.URI; + + +/** + * This is the standard Ordered Permit Overrides policy combining algorithm. + * It allows a single evaluation of Permit to take precedence over any number + * of deny, not applicable or indeterminate results. Note that this uses + * the regular Permit Overrides implementation since it is also orderd. + * + * @since 1.1 + * @author seth proctor + */ +public class OrderedPermitOverridesPolicyAlg extends PermitOverridesPolicyAlg +{ + + /** + * The standard URN used to identify this algorithm + */ + public static final String algId = + "urn:oasis:names:tc:xacml:1.1:policy-combining-algorithm:" + + "ordered-permit-overrides"; + + // a URI form of the identifier + private static URI identifierURI; + // exception if the URI was invalid, which should never be a problem + private static RuntimeException earlyException; + + static { + try { + identifierURI = URI.create(algId); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * Standard constructor. + */ + public OrderedPermitOverridesPolicyAlg() { + super(identifierURI); + + if (earlyException != null) { + throw earlyException; + } + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/OrderedPermitOverridesRuleAlg.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/OrderedPermitOverridesRuleAlg.java new file mode 100644 index 0000000..2859dd0 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/OrderedPermitOverridesRuleAlg.java @@ -0,0 +1,85 @@ + +/* + * @(#)OrderedPermitOverridesRuleAlg.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.combine; + +import java.net.URI; + + +/** + * This is the standard Ordered Permit Overrides rule combining algorithm. It + * allows a single evaluation of Permit to take precedence over any number + * of deny, not applicable or indeterminate results. Note that this uses + * the regular Permit Overrides implementation since it is also orderd. + * + * @since 1.1 + * @author seth proctor + */ +public class OrderedPermitOverridesRuleAlg extends PermitOverridesRuleAlg +{ + + /** + * The standard URN used to identify this algorithm + */ + public static final String algId = + "urn:oasis:names:tc:xacml:1.1:rule-combining-algorithm:" + + "ordered-permit-overrides"; + + // a URI form of the identifier + private static URI identifierURI; + // exception if the URI was invalid, which should never be a problem + private static RuntimeException earlyException; + + static { + try { + identifierURI = URI.create(algId); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * Standard constructor. + */ + public OrderedPermitOverridesRuleAlg() { + super(identifierURI); + + if (earlyException != null) { + throw earlyException; + } + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/PermitOverridesPolicyAlg.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/PermitOverridesPolicyAlg.java new file mode 100644 index 0000000..b988858 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/PermitOverridesPolicyAlg.java @@ -0,0 +1,195 @@ + +/* + * @(#)PermitOverridesPolicyAlg.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.combine; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.MatchResult; +import com.sun.xacml.Obligation; + +import com.sun.xacml.ctx.Result; +import com.sun.xacml.ctx.Status; + +import java.net.URI; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + + +/** + * This is the standard Permit Overrides policy combining algorithm. It + * allows a single evaluation of Permit to take precedence over any number + * of deny, not applicable or indeterminate results. Note that since + * this implementation does an ordered evaluation, this class also + * supports the Ordered Permit Overrides algorithm. + * + * @since 1.0 + * @author Seth Proctor + */ +public class PermitOverridesPolicyAlg extends PolicyCombiningAlgorithm +{ + + /** + * The standard URN used to identify this algorithm + */ + public static final String algId = + "urn:oasis:names:tc:xacml:1.0:policy-combining-algorithm:" + + "permit-overrides"; + + // a URI form of the identifier + private static URI identifierURI; + // exception if the URI was invalid, which should never be a problem + private static RuntimeException earlyException; + + static { + try { + identifierURI = URI.create(algId); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * Standard constructor. + */ + public PermitOverridesPolicyAlg() { + super(identifierURI); + + if (earlyException != null) { + throw earlyException; + } + } + + /** + * Protected constructor used by the ordered version of this algorithm. + * + * @param identifier the algorithm's identifier + */ + protected PermitOverridesPolicyAlg(URI identifier) { + super(identifier); + } + + /** + * Applies the combining rule to the set of policies based on the + * evaluation context. + * + * @param context the context from the request + * @param parameters a (possibly empty) non-null List of + * CombinerParameters + * @param policyElements the policies to combine + * + * @return the result of running the combining algorithm + */ + public Result combine(EvaluationCtx context, List parameters, + List policyElements) { + boolean atLeastOneError = false; + boolean atLeastOneDeny = false; + Set denyObligations = new HashSet(); + Status firstIndeterminateStatus = null; + Iterator it = policyElements.iterator(); + + while (it.hasNext()) { + AbstractPolicy policy = + ((PolicyCombinerElement)(it.next())).getPolicy(); + + // make sure that the policy matches the context + context.newEvent(policy); + MatchResult match = policy.match(context); + + if (match.getResult() == MatchResult.INDETERMINATE) { + context.closeCurrentEvent( + new Result(Result.DECISION_INDETERMINATE, context)); + atLeastOneError = true; + + // keep track of the first error, regardless of cause + if (firstIndeterminateStatus == null) { + firstIndeterminateStatus = match.getStatus(); + } + } else if (match.getResult() == MatchResult.NO_MATCH) { + context.closeCurrentEvent( + new Result(Result.DECISION_NOT_APPLICABLE)); + } else if (match.getResult() == MatchResult.MATCH) { + // now we evaluate the policy + Result result = policy.evaluate(context); + context.closeCurrentEvent(result); + + // do not treat the discarded values + if (result != null) { + int effect = result.getDecision(); + + // this is a little different from DenyOverrides... + if (effect == Result.DECISION_PERMIT) { + return result; + } + + if (effect == Result.DECISION_DENY) { + atLeastOneDeny = true; + denyObligations.addAll(result.getObligations()); + } else if (effect == Result.DECISION_INDETERMINATE) { + atLeastOneError = true; + + // keep track of the first error, regardless of cause + if (firstIndeterminateStatus == null) { + firstIndeterminateStatus = result.getStatus(); + } + } + } + } + } + + // if we got a DENY, return it + if (atLeastOneDeny) { + return new Result(Result.DECISION_DENY, + context, + denyObligations); + } + + // if we got an INDETERMINATE, return it + if (atLeastOneError) { + return new Result(Result.DECISION_INDETERMINATE, + firstIndeterminateStatus, + context); + } + + // if we got here, then nothing applied to us + return new Result(Result.DECISION_NOT_APPLICABLE, + context); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/PermitOverridesRuleAlg.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/PermitOverridesRuleAlg.java new file mode 100644 index 0000000..ab92f13 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/PermitOverridesRuleAlg.java @@ -0,0 +1,184 @@ + +/* + * @(#)PermitOverridesRuleAlg.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.combine; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.Rule; + +import com.sun.xacml.ctx.Result; + +import java.net.URI; + +import java.util.Iterator; +import java.util.List; + + +/** + * This is the standard Permit Overrides rule combining algorithm. It + * allows a single evaluation of Permit to take precedence over any number + * of deny, not applicable or indeterminate results. Note that since + * this implementation does an ordered evaluation, this class also + * supports the Ordered Permit Overrides algorithm. + * + * @since 1.0 + * @author Seth Proctor + */ +public class PermitOverridesRuleAlg extends RuleCombiningAlgorithm +{ + + /** + * The standard URN used to identify this algorithm + */ + public static final String algId = + "urn:oasis:names:tc:xacml:1.0:rule-combining-algorithm:" + + "permit-overrides"; + + // a URI form of the identifier + private static URI identifierURI; + // exception if the URI was invalid, which should never be a problem + private static RuntimeException earlyException; + + static { + try { + identifierURI = URI.create(algId); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * Standard constructor. + */ + public PermitOverridesRuleAlg() { + super(identifierURI); + + if (earlyException != null) { + throw earlyException; + } + } + + /** + * Protected constructor used by the ordered version of this algorithm. + * + * @param identifier the algorithm's identifier + */ + protected PermitOverridesRuleAlg(URI identifier) { + super(identifier); + } + + /** + * Applies the combining rule to the set of rules based on the + * evaluation context. + * + * @param context the context from the request + * @param parameters a (possibly empty) non-null List of + * CombinerParameters + * @param ruleElements the rules to combine + * + * @return the result of running the combining algorithm + */ + public Result combine(EvaluationCtx context, List parameters, + List ruleElements) { + boolean atLeastOneError = false; + boolean potentialPermit = false; + boolean atLeastOneDeny = false; + Result firstIndeterminateResult = null; + Iterator it = ruleElements.iterator(); + + while (it.hasNext()) { + Rule rule = ((RuleCombinerElement)(it.next())).getRule(); + Result result = rule.evaluate(context); + int value = result.getDecision(); + + // if there was a value of PERMIT, then regardless of what + // else we've seen, we always return PERMIT + if (value == Result.DECISION_PERMIT) { + return result; + } + + // if it was INDETERMINATE, then we couldn't figure something + // out, so we keep track of these cases... + if (value == Result.DECISION_INDETERMINATE) { + atLeastOneError = true; + + // there are no rules about what to do if multiple cases + // cause errors, so we'll just return the first one + if (firstIndeterminateResult == null) { + firstIndeterminateResult = result; + } + + // if the Rule's effect is PERMIT, then we can't let this + // alg return DENY, since this Rule might have permitted + // if it could do its stuff + if (rule.getEffect() == Result.DECISION_PERMIT) { + potentialPermit = true; + } + } else { + // keep track of whether we had at least one rule that + // actually pertained to the request + if (value == Result.DECISION_DENY) { + atLeastOneDeny = true; + } + } + } + + // we didn't explicitly PERMIT, but we might have had some Rule + // been evaluated, so we have to return INDETERMINATE + if (potentialPermit) { + return firstIndeterminateResult; + } + + // some Rule said DENY, so since nothing could have permitted, + // we return DENY + if (atLeastOneDeny) { + return new Result(Result.DECISION_DENY, + context); + } + + // we didn't find anything that said DENY, but if we had a + // problem with one of the Rules, then we're INDETERMINATE + if (atLeastOneError) { + return firstIndeterminateResult; + } + + // if we hit this point, then none of the rules actually applied + // to us, so we return NOT_APPLICABLE + return new Result(Result.DECISION_NOT_APPLICABLE, + context); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/PolicyCombinerElement.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/PolicyCombinerElement.java new file mode 100644 index 0000000..e89bdbe --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/PolicyCombinerElement.java @@ -0,0 +1,167 @@ + +/* + * @(#)PolicyCombinerElement.java + * + * Copyright 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.combine; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.Indenter; +import com.sun.xacml.Policy; +import com.sun.xacml.PolicyReference; +import com.sun.xacml.PolicySet; + +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; + +import java.util.Iterator; +import java.util.List; + + +/** + * Specific version of CombinerElement used for policy combining. + * + * @since 2.0 + * @author Seth Proctor + */ +public class PolicyCombinerElement extends CombinerElement +{ + + /** + * Constructor that only takes an AbstractPolicyAbstractPolicy when combining. + * + * @param policy an AbstractPolicy to use in combining + */ + public PolicyCombinerElement(AbstractPolicy policy) { + super(policy); + } + + /** + * Constructor that takes both the AbstractPolicy to combine + * and its associated combiner parameters. + * + * @param policy an AbstractPolicy to use in combining + * @param parameters a (possibly empty) non-null List of + * CombinerParameters provided for general + * use (for all pre-2.0 policies this must be empty) + */ + public PolicyCombinerElement(AbstractPolicy policy, List parameters) { + super(policy, parameters); + } + + /** + * Returns the AbstractPolicy in this element. + * + * @return the element's AbstractPolicy + */ + public AbstractPolicy getPolicy() { + return (AbstractPolicy)(getElement()); + } + + /** + * Encodes this element's AbstractPolicy and parameters into + * their XML representation and writes this encoding to the given + * OutputStream 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 { + if (! getParameters().isEmpty()) { + AbstractPolicy policy = getPolicy(); + + // XXX: This is ugly and happens in several places...maybe this + // should get folded into the AbstractPolicy API? + if (policy instanceof Policy) { + encodeParamaters(output, charsetName, indenter, "Policy", + policy.getId().toString()); + } else if (policy instanceof PolicySet) { + encodeParamaters(output, charsetName, indenter, "PolicySet", + policy.getId().toString()); + } else { + PolicyReference ref = (PolicyReference)policy; + if (ref.getReferenceType() + == PolicyReference.POLICY_REFERENCE) { + encodeParamaters(output, charsetName, indenter, "Policy", + ref.getReference().toString()); + } else { + encodeParamaters(output, charsetName, indenter, + "PolicySet", ref.getReference().toString()); + } + } + } + + getPolicy().encode(output, charsetName, indenter); + } + + /** + * Private helper that encodes the parameters based on the type + * + * @throws UnsupportedEncodingException + */ + private void encodeParamaters(OutputStream output, String charsetName, + Indenter indenter, String prefix, String id) + throws UnsupportedEncodingException { + PrintStream out; + if(charsetName == null) { + out = new PrintStream(output); + } else { + out = new PrintStream(output, false, charsetName); + } + String indent = indenter.makeString(); + Iterator it = getParameters().iterator(); + + out.println(indent + "<" + prefix + "CombinerParameters " + + prefix + "IdRef=\"" + id + "\">"); + indenter.in(); + + while (it.hasNext()) { + CombinerParameter param = it.next(); + param.encode(output, charsetName, indenter); + } + + out.println(indent + ""); + indenter.out(); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/PolicyCombiningAlgorithm.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/PolicyCombiningAlgorithm.java new file mode 100644 index 0000000..3b4700f --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/PolicyCombiningAlgorithm.java @@ -0,0 +1,93 @@ + +/* + * @(#)PolicyCombiningAlgorithm.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.combine; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.ctx.Result; + +import java.net.URI; + +import java.util.List; + + +/** + * The base type for all Policy combining algorithms. Unlike in Rule + * Combining Algorithms, each policy must be matched before they're evaluated + * to make sure they apply. Also, in combining policies, obligations must be + * handled correctly. Specifically, no obligation may be included in the + * Result that doesn't match the effect being returned. So, if + * INDETERMINATE or NOT_APPLICABLE is the returned effect, no obligations + * may be included in the result. If the effect of the combining algorithm + * is PERMIT or DENY, then obligations with a matching fulfillOn effect + * are also included in the result. + * + * @since 1.0 + * @author Seth Proctor + * @author Marco Barreno + */ +public abstract class PolicyCombiningAlgorithm extends CombiningAlgorithm +{ + /** + * Constructor that takes the algorithm's identifier. + * + * @param identifier the algorithm's identifier + */ + public PolicyCombiningAlgorithm(URI identifier) { + super(identifier); + } + + /** + * Combines the policies based on the context to produce some unified + * result. This is the one function of a combining algorithm. + *

+ * Note that unlike in the RuleCombiningAlgorithms, here you must + * explicitly match the sub-policies to make sure that you should + * consider them, and you must handle Obligations. + * + * @param context the representation of the request + * @param parameters a (possibly empty) non-null List of + * CombinerParameters + * @param policyElements a List of + * CombinerElements + * + * @return a single unified result based on the combining logic + */ + public abstract Result combine(EvaluationCtx context, List parameters, + List policyElements); + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/RuleCombinerElement.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/RuleCombinerElement.java new file mode 100644 index 0000000..2e00c55 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/RuleCombinerElement.java @@ -0,0 +1,134 @@ + +/* + * @(#)RuleCombinerElement.java + * + * Copyright 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.combine; + +import com.sun.xacml.Indenter; +import com.sun.xacml.Rule; + +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; + +import java.util.Iterator; +import java.util.List; + + +/** + * Specific version of CombinerElement used for rule combining. + * + * @since 2.0 + * @author Seth Proctor + */ +public class RuleCombinerElement extends CombinerElement +{ + + /** + * Constructor that only takes a RuleRule when combining. + * + * @param rule a Rule to use in combining + */ + public RuleCombinerElement(Rule rule) { + super(rule); + } + + /** + * Constructor that takes both the Rule to combine and its + * associated combiner parameters. + * + * @param rule a Rule to use in combining + * @param parameters a (possibly empty) non-null List of + * CombinerParameters provided for general + * use (for all pre-2.0 policies this must be empty) + */ + public RuleCombinerElement(Rule rule, List parameters) { + super(rule, parameters); + } + + /** + * Returns the Rule in this element. + * + * @return the element's Rule + */ + public Rule getRule() { + return (Rule)(getElement()); + } + + /** + * Encodes this element's Rule and parameters into their + * XML representation and writes this encoding to the given + * OutputStream 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 { + Iterator it = getParameters().iterator(); + + if (it.hasNext()) { + PrintStream out; + if(charsetName == null) { + out = new PrintStream(output); + } else { + out = new PrintStream(output, false, charsetName); + } + String indent = indenter.makeString(); + + out.println(indent + ""); + indenter.in(); + + while (it.hasNext()) { + CombinerParameter param = (CombinerParameter)(it.next()); + param.encode(output, charsetName, indenter); + } + + out.println(indent + ""); + indenter.out(); + } + + getRule().encode(output, charsetName, indenter); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/RuleCombiningAlgorithm.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/RuleCombiningAlgorithm.java new file mode 100644 index 0000000..918e054 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/RuleCombiningAlgorithm.java @@ -0,0 +1,81 @@ + +/* + * @(#)RuleCombiningAlgorithm.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.combine; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.ctx.Result; + +import java.net.URI; + +import java.util.List; + + +/** + * The base type for all Rule combining algorithms. + * + * @since 1.0 + * @author Seth Proctor + * @author Marco Barreno + */ +public abstract class RuleCombiningAlgorithm extends CombiningAlgorithm +{ + + /** + * Constructor that takes the algorithm's identifier. + * + * @param identifier the algorithm's identifier + */ + public RuleCombiningAlgorithm(URI identifier) { + super(identifier); + } + + /** + * Combines the rules based on the context to produce some unified + * result. This is the one function of a combining algorithm. + * + * @param context the representation of the request + * @param parameters a (possibly empty) non-null List of + * CombinerParameters + * @param ruleElements a List of CombinerElements + * + * @return a single unified result based on the combining logic + */ + public abstract Result combine(EvaluationCtx context, List parameters, + List ruleElements); + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/StandardCombiningAlgFactory.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/StandardCombiningAlgFactory.java new file mode 100644 index 0000000..0b9d3e2 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/StandardCombiningAlgFactory.java @@ -0,0 +1,209 @@ + +/* + * @(#)StandardCombiningAlgFactory.java + * + * Copyright 2004-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.combine; + +import com.sun.xacml.Constants; +import com.sun.xacml.UnknownIdentifierException; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.apache.log4j.Logger; + + +/** + * This factory supports the standard set of algorithms specified in XACML + * 1.x and 2.0. It is the default factory used by the system, and imposes + * a singleton pattern insuring that there is only ever one instance of + * this class. + *

+ * Note that because this supports only the standard algorithms, this + * factory does not allow the addition of any other algorithms. If you call + * addAlgorithm on an instance of this class, an exception + * will be thrown. If you need a standard factory that is modifiable, you + * should create a new BaseCombiningAlgFactory (or some other + * CombiningAlgFactory) and configure it with the standard + * algorithms using getStandardAlgorithms (or, in the case of + * BaseAttributeFactory, by providing the datatypes in the + * constructor). + * + * @since 1.2 + * @author Seth Proctor + */ +public class StandardCombiningAlgFactory extends BaseCombiningAlgFactory +{ + + // the single factory instance + private static StandardCombiningAlgFactory factoryInstance = null; + + // the algorithms supported by this factory + private static Set supportedAlgorithms = null; + + // identifiers for the supported algorithms + private static Set supportedAlgIds; + + // the logger we'll use for all messages + private static final Logger logger = + Logger.getLogger(StandardCombiningAlgFactory.class.getName()); + + /** + * Default constructor. + */ + private StandardCombiningAlgFactory() { + super(supportedAlgorithms); + } + + /** + * Private initializer for the supported algorithms. This isn't called + * until something needs these values, and is only called once. + */ + private static void initAlgorithms() { + logger.debug("Initializing standard combining algorithms"); + + supportedAlgorithms = new HashSet(); + supportedAlgIds = new HashSet(); + + supportedAlgorithms.add(new DenyOverridesRuleAlg()); + supportedAlgIds.add(DenyOverridesRuleAlg.algId); + supportedAlgorithms.add(new DenyOverridesPolicyAlg()); + supportedAlgIds.add(DenyOverridesPolicyAlg.algId); + + supportedAlgorithms.add(new OrderedDenyOverridesRuleAlg()); + supportedAlgIds.add(OrderedDenyOverridesRuleAlg.algId); + supportedAlgorithms.add(new OrderedDenyOverridesPolicyAlg()); + supportedAlgIds.add(OrderedDenyOverridesPolicyAlg.algId); + + supportedAlgorithms.add(new PermitOverridesRuleAlg()); + supportedAlgIds.add(PermitOverridesRuleAlg.algId); + supportedAlgorithms.add(new PermitOverridesPolicyAlg()); + supportedAlgIds.add(PermitOverridesPolicyAlg.algId); + + supportedAlgorithms.add(new OrderedPermitOverridesRuleAlg()); + supportedAlgIds.add(OrderedPermitOverridesRuleAlg.algId); + supportedAlgorithms.add(new OrderedPermitOverridesPolicyAlg()); + supportedAlgIds.add(OrderedPermitOverridesPolicyAlg.algId); + + supportedAlgorithms.add(new FirstApplicableRuleAlg()); + supportedAlgIds.add(FirstApplicableRuleAlg.algId); + supportedAlgorithms.add(new FirstApplicablePolicyAlg()); + supportedAlgIds.add(FirstApplicablePolicyAlg.algId); + + supportedAlgorithms.add(new OnlyOneApplicablePolicyAlg()); + supportedAlgIds.add(OnlyOneApplicablePolicyAlg.algId); + + supportedAlgIds = Collections.unmodifiableSet(supportedAlgIds); + } + + /** + * Returns an instance of this factory. This method enforces a singleton + * model, meaning that this always returns the same instance, creating + * the factory if it hasn't been requested before. This is the default + * model used by the CombiningAlgFactory, ensuring quick + * access to this factory. + * + * @return the factory instance + */ + public static synchronized StandardCombiningAlgFactory getFactory() { + if (factoryInstance == null) { + initAlgorithms(); + factoryInstance = new StandardCombiningAlgFactory(); + } + + return factoryInstance; + } + + /** + * A convenience method that returns a new instance of a + * CombiningAlgFactory that supports all of the standard + * algorithms. The new factory allows adding support for new algorithms. + * This method should only be used when you need a new, mutable instance + * (eg, when you want to create a new factory that extends the set of + * supported algorithms). In general, you should use + * getFactory which is more efficient and enforces a + * singleton pattern. + * + * @return a new factory supporting the standard algorithms + */ + public static CombiningAlgFactory getNewFactory() { + // first we make sure everything's been initialized... + getFactory(); + + // ...then we create the new instance + return new BaseCombiningAlgFactory(supportedAlgorithms); + } + + /** + * Returns the identifiers supported for the given version of XACML. + * Because this factory supports identifiers from all versions of the + * XACML specifications, this method is useful for getting a list of + * which specific identifiers are supported by a given version of XACML. + * + * @param xacmlVersion a standard XACML identifier string, as provided + * in PolicyMetaData + * + * @return a Set of identifiers + * + * @throws UnknownIdentifierException if the version string is unknown + */ + public static Set getStandardAlgorithms(String xacmlVersion) + throws UnknownIdentifierException + { + if ((xacmlVersion.equals(Constants.XACML_1_0_IDENTIFIER)) || + (xacmlVersion.equals(Constants.XACML_2_0_IDENTIFIER)) || + (xacmlVersion.equals(Constants.XACML_3_0_IDENTIFIER))) { + return supportedAlgIds; + } + + throw new UnknownIdentifierException("Unknown XACML version: " + + xacmlVersion); + } + + /** + * Throws an UnsupportedOperationException since you are not + * allowed to modify what a standard factory supports. + * + * @param alg the combining algorithm to add + * + * @throws UnsupportedOperationException always + */ + public void addAlgorithm(CombiningAlgorithm alg) { + throw new UnsupportedOperationException("a standard factory cannot " + + "support new algorithms"); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/package.html b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/package.html new file mode 100644 index 0000000..53f45ba --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/combine/package.html @@ -0,0 +1,7 @@ + + All of the combining algorithm support is in this package. There are + base classes that all combining algorithms need to extend, and a + factory for getting algorithms and adding new algorithms to the + system. There are also implementations of all of the standard + combining algorithms. + diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/AbsFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/AbsFunction.java new file mode 100644 index 0000000..ea532ef --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/AbsFunction.java @@ -0,0 +1,168 @@ + +/* + * @(#)AbsFunction.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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.DoubleAttribute; +import com.sun.xacml.attr.IntegerAttribute; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +/** + * A class that implements all the *-abs functions. It takes one + * operand of the appropriate type and returns the absolute value of the + * operand. If the operand is indeterminate, an indeterminate result + * is returned. + * + * @since 1.0 + * @author Steve Hanna + * @author Seth Proctor + */ +public class AbsFunction extends FunctionBase +{ + + /** + * Standard identifier for the integer-abs function. + */ + public static final String NAME_INTEGER_ABS = + FUNCTION_NS + "integer-abs"; + + /** + * Standard identifier for the double-abs function. + */ + public static final String NAME_DOUBLE_ABS = + FUNCTION_NS + "double-abs"; + + // inernal identifiers for each of the supported functions + private static final int ID_INTEGER_ABS = 0; + private static final int ID_DOUBLE_ABS = 1; + + /** + * Creates a new AbsFunction object. + * + * @param functionName the standard XACML name of the function to be + * handled by this object, including the full namespace + * + * @throws IllegalArgumentException if the function is known + */ + public AbsFunction(String functionName) { + super(functionName, getId(functionName), getArgumentType(functionName), + false, 1, getArgumentType(functionName), false); + } + + /** + * Private helper that returns the internal identifier used for the + * given standard function. + */ + private static int getId(String functionName) { + if (functionName.equals(NAME_INTEGER_ABS)) { + return ID_INTEGER_ABS; + } else if (functionName.equals(NAME_DOUBLE_ABS)) { + return ID_DOUBLE_ABS; + } else { + throw new IllegalArgumentException("unknown abs function " + + functionName); + } + } + + /** + * Private helper that returns the type used for the given standard + * function. Note that this doesn't check on the return value since the + * method always is called after getId, so we assume that the function + * is present. + */ + private static String getArgumentType(String functionName) { + if (functionName.equals(NAME_INTEGER_ABS)) { + return IntegerAttribute.identifier; + } + return DoubleAttribute.identifier; + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + Set set = new HashSet(); + + set.add(NAME_INTEGER_ABS); + set.add(NAME_DOUBLE_ABS); + + return set; + } + + /** + * Evaluate the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + + // evaluate the inputs, returning any error that may occur + AttributeValue [] argValues = new AttributeValue[inputs.size()]; + EvaluationResult result = evalArgs(inputs, context, argValues); + if (result != null) { + return result; + } + + // Now that we have real values, perform the abs operation + // in the manner appropriate for the type of the arguments. + if (getFunctionId() == ID_INTEGER_ABS) { + long arg = ((IntegerAttribute) argValues[0]).getValue(); + long absValue = Math.abs(arg); + result = new EvaluationResult(new IntegerAttribute(absValue)); + } else if (getFunctionId() == ID_DOUBLE_ABS) { + double arg = ((DoubleAttribute) argValues[0]).getValue(); + double absValue = Math.abs(arg); + result = new EvaluationResult(new DoubleAttribute(absValue)); + } + + return result; + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/AddFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/AddFunction.java new file mode 100644 index 0000000..ca0a593 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/AddFunction.java @@ -0,0 +1,187 @@ + +/* + * @(#)AddFunction.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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.DoubleAttribute; +import com.sun.xacml.attr.IntegerAttribute; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +/** + * A class that implements all the *-add functions. It takes two or more + * operands of the appropriate type and returns the sum of the operands. + * If any of the operands is indeterminate, an indeterminate result is + * returned. + * + * @since 1.0 + * @author Steve Hanna + * @author Seth Proctor + */ +public class AddFunction extends FunctionBase +{ + + /** + * Standard identifier for the integer-add function. + */ + public static final String NAME_INTEGER_ADD = + FUNCTION_NS + "integer-add"; + + /** + * Standard identifier for the double-add function. + */ + public static final String NAME_DOUBLE_ADD = + FUNCTION_NS + "double-add"; + + // inernal identifiers for each of the supported functions + private static final int ID_INTEGER_ADD = 0; + private static final int ID_DOUBLE_ADD = 1; + + /** + * Creates a new AddFunction object. + * + * @param functionName the standard XACML name of the function to be + * handled by this object, including the full namespace + * + * @throws IllegalArgumentException if the function is unknown + */ + public AddFunction(String functionName) { + super(functionName, getId(functionName), getArgumentType(functionName), + false, -1, 2, getArgumentType(functionName), false); + } + + /** + * Private helper that returns the internal identifier used for the + * given standard function. + */ + private static int getId(String functionName) { + if (functionName.equals(NAME_INTEGER_ADD)) { + return ID_INTEGER_ADD; + } else if (functionName.equals(NAME_DOUBLE_ADD)) { + return ID_DOUBLE_ADD; + } else { + throw new IllegalArgumentException("unknown add function " + + functionName); + } + } + + /** + * Private helper that returns the type used for the given standard + * function. Note that this doesn't check on the return value since the + * method always is called after getId, so we assume that the function + * is present. + */ + private static String getArgumentType(String functionName) { + if (functionName.equals(NAME_INTEGER_ADD)) { + return IntegerAttribute.identifier; + } + return DoubleAttribute.identifier; + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + Set set = new HashSet(); + + set.add(NAME_INTEGER_ADD); + set.add(NAME_DOUBLE_ADD); + + return set; + } + + /** + * Evaluate the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + + // Evaluate the arguments + AttributeValue [] argValues = new AttributeValue[inputs.size()]; + EvaluationResult result = evalArgs(inputs, context, argValues); + if (result != null) { + return result; + } + + // Now that we have real values, perform the add operation + if (getFunctionId() == ID_INTEGER_ADD) { + long sum = 0; + for (int index = 0; index < argValues.length; index++) { + long arg = ((IntegerAttribute) argValues[index]).getValue(); + sum += arg; + } + result = new EvaluationResult(new IntegerAttribute(sum)); + } else if (getFunctionId() == ID_DOUBLE_ADD) { + double sum = 0; + for (int index = 0; index < argValues.length; index++) { + double arg = + ((DoubleAttribute) argValues[index]).getValue(); + sum = sum + arg; + } + // Make it round half even, not round nearest + double lower = Math.floor(sum); + double higher = lower + 1; + //Equality test for floating point numbers that is + //resilient against errors. + if (Math.abs((sum - lower) - (higher - sum)) < .0000001) { + if ((lower % 2) == 0) { + sum = lower; + } else { + sum = higher; + } + } + result = new EvaluationResult(new DoubleAttribute(sum)); + } + + return result; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/Apply.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/Apply.java new file mode 100644 index 0000000..9434cbe --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/Apply.java @@ -0,0 +1,459 @@ + +/* + * @(#)Apply.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.cond; + +import com.sun.xacml.Constants; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.Indenter; +import com.sun.xacml.ParsingException; +import com.sun.xacml.PolicyMetaData; +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.Iterator; +import java.util.List; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + + +/** + * Represents the XACML ApplyType and ConditionType XML types. + *

+ * Note well: as of 2.0, there is no longer a notion of a separate higher- + * order bag function. Instead, if needed, it is supplied as one of the + * Expressions in the parameter list. As such, when this + * Apply is evaluated, it no longer pre-evaluates all the + * parameters if a bag function is used. It is now up to the implementor + * of a higher-order function to do this. + *

+ * Also, as of 2.0, the Apply is no longer used to represent + * a Condition, since the XACML 2.0 specification changed how Condition + * works. Instead, there is now a Condition class that + * represents both 1.x and 2.0 style Conditions. + * + * @since 1.0 + * @author Seth Proctor + */ +public class Apply implements Evaluatable +{ + + // the function used to evaluate the contents of the apply + private Function function; + + // the paramaters to the function...ie, the contents of the apply + private List xprs; + + private RuntimeInfo src; + + //private Logger logger = Logger.getLogger(Apply.class); + + /** + * Constructs an Apply instance. + * + * @param function the Function to use in evaluating the + * elements in the apply + * @param xprs the contents of the apply which will be the parameters + * to the function, each of which is an + * Expression + * + * @throws IllegalArgumentException if the input expressions don't + * match the signature of the function + */ + public Apply(Function function, List xprs) + throws IllegalArgumentException { + this(function, xprs, null); + } + + /** + * Constructs an Apply instance. + * + * @param function the Function to use in evaluating the + * elements in the apply + * @param xprs the contents of the apply which will be the parameters + * to the function, each of which is an + * Expression + * + * @throws IllegalArgumentException if the input expressions don't + * match the signature of the function + */ + public Apply(Function function, List xprs, RuntimeInfo src) + throws IllegalArgumentException { + // check that the given inputs work for the function + function.checkInputs(xprs, src); + + // if everything checks out, then store the inputs + this.function = function; + this.xprs = Collections.unmodifiableList(new ArrayList(xprs)); + this.src = src; + } + + /** + * Constructs an Apply instance. + * + * @deprecated As of 2.0 Apply is no longer used for + * Conditions, so the isCondition parameter + * is no longer needed. You should now use the 2 parameter + * constructor. This constructor will be removed in a + * future release. + * + * @param function the Function to use in evaluating the + * elements in the apply + * @param xprs the contents of the apply which will be the parameters + * to the function, each of which is an + * Expression + * @param isCondition as of 2.0, this must always be false + * + * @throws IllegalArgumentException if the input expressions don't + * match the signature of the function or + * if isCondition is true + */ + public Apply(Function function, List xprs, boolean isCondition) + throws IllegalArgumentException { + // make sure that no is using this constructor to create a Condition + if (isCondition) { + throw new IllegalArgumentException("As of version 2.0 an Apply" + + " may not represent a" + + " Condition"); + } + // check that the given inputs work for the function + function.checkInputs(xprs); + + // if everything checks out, then store the inputs + this.function = function; + this.xprs = Collections.unmodifiableList(new ArrayList(xprs)); + } + + /** + * Returns an instance of an Apply based on the given DOM + * root node. This will actually return a special kind of + * Apply, namely an XML ConditionType, which is the root + * of the condition logic in a RuleType. A ConditionType is the same + * as an ApplyType except that it must use a FunctionId that returns + * a boolean value. + *

+ * Note that as of 2.0 there is a separate Condition class + * used to support the different kinds of Conditions in XACML 1.x and + * 2.0. As such, the system no longer treats a ConditionType as a + * special kind of ApplyType. You may still use this method to get a + * 1.x style ConditionType, but you will need to convert it into a + * Condition to use it in evaluation. The preferred way + * to create a Condition is now through the getInstance + * method on Condition. + * + * @param root the DOM root of a ConditionType 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) + * @param manager VariableManager used to connect references + * and definitions while parsing + * + * @return The condition instance of this Apply. + * + * @throws ParsingException if this is not a valid ConditionType + */ + public static Apply getConditionInstance(Node root, String xpathVersion, + VariableManager manager) throws ParsingException { + return getInstance(root, FunctionFactory.getConditionInstance(), + new PolicyMetaData( + Constants.XACML_1_0_IDENTIFIER, + xpathVersion), + manager); + } + + /** + * Returns an instance of an Apply based on the given DOM + * root node. This will actually return a special kind of + * Apply, namely an XML ConditionType, which is the root + * of the condition logic in a RuleType. A ConditionType is the same + * as an ApplyType except that it must use a FunctionId that returns + * a boolean value. + * + * @deprecated As of 2.0 you should avoid using this method, since it + * does not provide a Condition instance and + * does not handle XACML 2.0 policies correctly. If you need + * a similar method you can use the new version that + * accepts a VariableManager. This will return + * an Apply instance for XACML 1.x policies. + * + * @param root the DOM root of a ConditionType 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 condition instance of this Apply. + * + * @throws ParsingException if this is not a valid ConditionType + */ + public static Apply getConditionInstance(Node root, String xpathVersion) + throws ParsingException { + return getInstance(root, FunctionFactory.getConditionInstance(), + new PolicyMetaData( + Constants.XACML_1_0_IDENTIFIER, + xpathVersion), + null); + } + + /** + * Returns an instance of Apply based on the given DOM root. + * + * @param root the DOM root of an ApplyType XML type + * @param metaData the meta-data associated with the containing policy + * @param manager VariableManager used to connect references + * and definitions while parsing + * + * @return An instance of this Apply. + * + * @throws ParsingException if this is not a valid ApplyType + */ + public static Apply getInstance(Node root, PolicyMetaData metaData, + VariableManager manager) throws ParsingException { + return getInstance(root, FunctionFactory.getGeneralInstance(), + metaData, manager); + } + + /** + * This is a helper method that is called by the two getInstance + * methods. It takes a factory so we know that we're getting the right + * kind of function. + */ + private static Apply getInstance(Node root, FunctionFactory factory, + PolicyMetaData metaData, VariableManager manager) + throws ParsingException { + RuntimeInfo src = RuntimeInfo.getRuntimeInfo(root, ELEMENT_TYPE.APPLY); + // check if this really is an Apply + if (root.getNodeType() != Node.ELEMENT_NODE + || (!root.getLocalName().equals("Apply") + && !root.getLocalName().equals("Condition"))) { + throw new ParsingException("Can't create an Apply from a " + + root.getLocalName() + " element" + + (src != null ? src.getLocationMsgForError() : "")); + } + Function function = + ExpressionHandler.getFunction(root, metaData, factory); + List xprs = new ArrayList(); + + NodeList nodes = root.getChildNodes(); + for (int i = 0; i < nodes.getLength(); i++) { + Expression xpr = ExpressionHandler. + parseExpression(nodes.item(i), metaData, manager); + + if (xpr != null) { + xprs.add(xpr); + } + } + + Apply apply = new Apply(function, xprs, src); + if ( src != null ) { + apply.src = src; + src.setXACMLObject(apply); + } + return apply; + } + + /** + * Returns the Function used by this Apply. + * + * @return the Function + */ + public Function getFunction() { + return this.function; + } + + /** + * Returns the List of children for this Apply. + * The List contains Expressions. The list is + * unmodifiable, and may be empty. + * + * @return a List of Expressions + */ + public List getChildren() { + return this.xprs; + } + + /** + * Returns whether or not this ApplyType is actually a ConditionType. As + * of 2.0 this always returns false; + * + * @deprecated As of 2.0 this method should not be used, since an + * Apply is never a Condition. + * + * @return false + */ + public boolean isCondition() { + return false; + } + + /** + * Evaluates the apply object using the given function. This will in + * turn call evaluate on all the given parameters, some of which may be + * other Apply objects. + * + * @param context the representation of the request + * + * @return the result of trying to evaluate this apply object + */ + public EvaluationResult evaluate(EvaluationCtx context) { + // Note that prior to the 2.0 codebase, this method was much more + // complex, pre-evaluating the higher-order functions. Because this + // was never really the right behavior (there's no reason that a + // function can only be at the start of an Apply), we no longer make + // assumptions at this point, so the higher order functions are + // left to evaluate their own parameters. + context.newEvent(this); + + //set (context dependent) source locator for function + RuntimeInfo funcSrc = null; + if ( src != null ) { + funcSrc = src.getIndirectRuntimeInfo(function, ELEMENT_TYPE.FUNCTION); + this.function.setRuntimeInfo(funcSrc); + } + + EvaluationResult result = this.function.evaluate(this.xprs, context); + //unset source locator + if ( funcSrc != null ) { + this.function.unsetRuntimeInfo(funcSrc) ; + } + context.closeCurrentEvent(result); + return result; + } + + /** + * Returns the type of attribute that this object will return on a call + * to evaluate. In practice, this will always be the same as + * the result of calling getReturnType on the function used + * by this object. + * + * @return the type returned by evaluate + */ + public URI getType() { + return this.function.getReturnType(); + } + + + public RuntimeInfo getRuntimeInfo() { + return this.src; + } + + /** + * Returns whether or not the Function will return a bag + * of values on evaluation. + * + * @return true if evaluation will return a bag of values, false otherwise + */ + public boolean returnsBag() { + return this.function.returnsBag(); + } + + /** + * Returns whether or not the Function will return a bag + * of values on evaluation. + * + * + * @deprecated As of 2.0, you should use the returnsBag + * method from the super-interface Expression. + * + * @return true if evaluation will return a bag of values, false otherwise + */ + public boolean evaluatesToBag() { + return this.function.returnsBag(); + } + + + /** + * Encodes this Apply into its XML representation and + * writes this encoding to the given OutputStream 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 Apply into its XML representation and + * writes this encoding to the given OutputStream 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 + ""); + indenter.in(); + + Iterator it = this.xprs.iterator(); + while (it.hasNext()) { + Expression xpr = (Expression)(it.next()); + xpr.encode(output, charsetName, indenter); + } + + indenter.out(); + out.println(indent + ""); + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/BagFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/BagFunction.java new file mode 100644 index 0000000..b80070d --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/BagFunction.java @@ -0,0 +1,289 @@ + +/* + * @(#)BagFunction.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.cond; + +import com.sun.xacml.attr.AnyURIAttribute; +import com.sun.xacml.attr.Base64BinaryAttribute; +import com.sun.xacml.attr.BooleanAttribute; +import com.sun.xacml.attr.DateAttribute; +import com.sun.xacml.attr.DateTimeAttribute; +import com.sun.xacml.attr.DayTimeDurationAttribute; +import com.sun.xacml.attr.DNSNameAttribute; +import com.sun.xacml.attr.DoubleAttribute; +import com.sun.xacml.attr.HexBinaryAttribute; +import com.sun.xacml.attr.IntegerAttribute; +import com.sun.xacml.attr.IPAddressAttribute; +import com.sun.xacml.attr.RFC822NameAttribute; +import com.sun.xacml.attr.StringAttribute; +import com.sun.xacml.attr.TimeAttribute; +import com.sun.xacml.attr.X500NameAttribute; +import com.sun.xacml.attr.YearMonthDurationAttribute; + +import java.util.HashSet; +import java.util.Set; + + +/** + * Represents all of the Bag functions, though the actual implementations + * are in two sub-classes specific to the condition and general bag + * functions. + * + * @since 1.0 + * @author Seth Proctor + */ +public abstract class BagFunction extends FunctionBase +{ + + /** + * Base name for the type-one-and-only funtions. To get the standard + * identifier for a given type, use FunctionBase.FUNCTION_NS + * + the datatype's base name (e.g., string) + + * NAME_BASE_ONE_AND_ONLY. + */ + public static final String NAME_BASE_ONE_AND_ONLY = + "-one-and-only"; + + /** + * Base name for the type-bag-size funtions. To get the standard + * identifier for a given type, use FunctionBase.FUNCTION_NS + * + the datatype's base name (e.g., string) + + * NAME_BASE_BAG_SIZE. + */ + public static final String NAME_BASE_BAG_SIZE = + "-bag-size"; + + /** + * Base name for the type-is-in. To get the standard + * identifier for a given type, use FunctionBase.FUNCTION_NS + * + the datatype's base name (e.g., string) + + * NAME_BASE_IS_IN. + */ + public static final String NAME_BASE_IS_IN = + "-is-in"; + + /** + * Base name for the type-bag funtions. To get the standard + * identifier for a given type, use FunctionBase.FUNCTION_NS + * + the datatype's base name (e.g., string) + + * NAME_BASE_BAG. + */ + public static final String NAME_BASE_BAG = + "-bag"; + + // bag parameter info for the functions that accept multiple args + private static final boolean bagParams [] = { false, true }; + + /** + * A complete list of all the XACML 1.x datatypes supported by the Bag + * functions + */ + protected final static String baseTypes [] = { + StringAttribute.identifier, + BooleanAttribute.identifier, + IntegerAttribute.identifier, + DoubleAttribute.identifier, + DateAttribute.identifier, + DateTimeAttribute.identifier, + TimeAttribute.identifier, + AnyURIAttribute.identifier, + HexBinaryAttribute.identifier, + Base64BinaryAttribute.identifier, + DayTimeDurationAttribute.identifier, + YearMonthDurationAttribute.identifier, + X500NameAttribute.identifier, + RFC822NameAttribute.identifier + }; + + /** + * A complete list of all the XACML 2.0 datatypes newly supported by the + * Bag functions + */ + protected static final String baseTypes2 [] = { + IPAddressAttribute.identifier, + DNSNameAttribute.identifier + }; + + /** + * A complete list of all the 1.x XACML datatypes supported by the + * Bag functions, using the "simple" form of the names (eg, string + * instead of http://www.w3.org/2001/XMLSchema#string) + */ + protected static final String simpleTypes [] = { + "string", "boolean", "integer", "double", "date", "dateTime", + "time", "anyURI", "hexBinary", "base64Binary", "dayTimeDuration", + "yearMonthDuration", "x500Name", "rfc822Name" + }; + + /** + * A complete list of all the 2.0 XACML datatypes newly supported by the + * Bag functions, using the "simple" form of the names (eg, string + * instead of http://www.w3.org/2001/XMLSchema#string) + */ + protected static final String simpleTypes2 [] = { + "ipAddress", "dnsName" + }; + + /** + * Returns a new BagFunction that provides the + * type-one-and-only functionality over the given attribute type. + * This should be used to create new function instances for any new + * attribute types, and the resulting object should be put into + * the FunctionFactory (instances already exist in the + * factory for the standard attribute types). + * + * @param functionName the name to use for the function + * @param argumentType the type to operate on + * + * @return a new BagFunction + */ + public static BagFunction getOneAndOnlyInstance(String functionName, + String argumentType) { + return new GeneralBagFunction(functionName, argumentType, + NAME_BASE_ONE_AND_ONLY); + } + + /** + * Returns a new BagFunction that provides the + * type-bag-size functionality over the given attribute type. This + * should be used to create new function instances for any new + * attribute types, and the resulting object should be put into + * the FunctionFactory (instances already exist in the + * factory for the standard attribute types). + * + * @param functionName the name to use for the function + * @param argumentType the type to operate on + * + * @return a new BagFunction + */ + public static BagFunction getBagSizeInstance(String functionName, + String argumentType) { + return new GeneralBagFunction(functionName, argumentType, + NAME_BASE_BAG_SIZE); + } + + /** + * Returns a new BagFunction that provides the + * type-is-in functionality over the given attribute type. This + * should be used to create new function instances for any new + * attribute types, and the resulting object should be put into + * the FunctionFactory (instances already exist in the + * factory for the standard attribute types). + * + * @param functionName the name to use for the function + * @param argumentType the type to operate on + * + * @return a new BagFunction + */ + public static BagFunction getIsInInstance(String functionName, + String argumentType) { + return new ConditionBagFunction(functionName, argumentType); + } + + /** + * Returns a new BagFunction that provides the + * type-bag functionality over the given attribute type. This + * should be used to create new function instances for any new + * attribute types, and the resulting object should be put into + * the FunctionFactory (instances already exist in the + * factory for the standard attribute types). + * + * @param functionName the name to use for the function + * @param argumentType the type to operate on + * + * @return a new BagFunction + */ + public static BagFunction getBagInstance(String functionName, + String argumentType) { + return new GeneralBagFunction(functionName, argumentType, + NAME_BASE_BAG); + } + + /** + * Protected constuctor used by the general and condition subclasses + * to create a non-boolean function with parameters of the same datatype. + * If you need to create a new BagFunction instance you + * should either use one of the getInstance methods or + * construct one of the sub-classes directly. + * + * @param functionName the identitifer for the function + * @param functionId an optional, internal numeric identifier + * @param paramType the datatype this function accepts + * @param paramIsBag whether the parameters are bags + * @param numParams number of parameters allowed or -1 for any number + * @param returnType the datatype this function returns + * @param returnsBag whether this function returns bags + */ + protected BagFunction(String functionName, int functionId, + String paramType, boolean paramIsBag, int numParams, + String returnType, boolean returnsBag) { + super(functionName, functionId, paramType, paramIsBag, numParams, + returnType, returnsBag); + } + + /** + * Protected constuctor used by the general and condition subclasses + * to create a boolean function with parameters of different datatypes. + * If you need to create a new BagFunction instance you + * should either use one of the getInstance methods or + * construct one of the sub-classes directly. + * + * @param functionName the identitifer for the function + * @param functionId an optional, internal numeric identifier + * @param paramTypes the datatype of each parameter + */ + protected BagFunction(String functionName, int functionId, + String [] paramTypes) { + super(functionName, functionId, paramTypes, bagParams, + BooleanAttribute.identifier, false); + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + Set set = new HashSet(); + + set.addAll(ConditionBagFunction.getSupportedIdentifiers()); + set.addAll(GeneralBagFunction.getSupportedIdentifiers()); + + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/BaseFunctionFactory.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/BaseFunctionFactory.java new file mode 100644 index 0000000..e5146d2 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/BaseFunctionFactory.java @@ -0,0 +1,418 @@ + +/* + * @(#)BaseCombiningAlgFactory.java + * + * Copyright 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.cond; + +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; + +import java.net.URI; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.w3c.dom.Node; + + +/** + * This is a basic implementation of FunctionFactory. It + * implements the insertion and retrieval methods, but it doesn't actually + * setup the factory with any functions. It also assumes a certain model + * with regard to the different kinds of functions (Target, Condition, and + * General). For this reason, you may want to re-use this class, or you + * may want to extend FunctionFactory directly, if you're writing a new + * factory implementation. + *

+ * Note that while this class is thread-safe on all creation methods, it + * is not safe to add support for a new function while creating an instance + * of a function. This follows from the assumption that most people will + * initialize these factories up-front, and then start processing without + * ever modifying the factories. If you need these mutual operations to + * be thread-safe, then you should write a wrapper class that implements + * the right synchronization. + * + * @since 1.2 + * @author Seth Proctor + */ +public class BaseFunctionFactory extends FunctionFactory +{ + + // the backing maps for the Function objects or FunctionProxy objects + private HashMap functionMap = null; + + // the superset factory chained to this factory + private FunctionFactory superset = null; + + /** + * Default constructor. No superset factory is used. + */ + public BaseFunctionFactory() { + this(null); + } + + /** + * Constructor that sets a "superset factory". This is useful since + * the different function factories (Target, Condition, and General) + * have a superset relationship (Condition functions are a superset + * of Target functions, etc.). Adding a function to this factory will + * automatically add the same function to the superset factory. + * + * @param superset the superset factory or null + */ + public BaseFunctionFactory(FunctionFactory superset) { + this.functionMap = new HashMap(); + + this.superset = superset; + } + + /** + * Constructor that defines the initial functions supported by this + * factory but doesn't use a superset factory. + * + * @param supportedFunctions a Set of Functions + * @param supportedAbstractFunctions a mapping from URI to + * FunctionProxy + */ + public BaseFunctionFactory(Set supportedFunctions, + Map supportedAbstractFunctions) { + this(null, supportedFunctions, supportedAbstractFunctions); + } + + /** + * Constructor that defines the initial functions supported by this + * factory and uses a superset factory. Note that the functions + * supplied here are not propagated up to the superset factory, so + * you must either make sure the superst factory is correctly + * initialized or use BaseFunctionFactory(FunctionFactory) + * and then manually add each function. + * + * @param superset the superset factory or null + * @param supportedFunctions a Set of Functions + * @param supportedAbstractFunctions a mapping from URI to + * FunctionProxy + */ + public BaseFunctionFactory(FunctionFactory superset, + Set supportedFunctions, + Map supportedAbstractFunctions) { + this(superset); + + Iterator it = supportedFunctions.iterator(); + while (it.hasNext()) { + Function function = it.next(); + this.functionMap.put(function.getIdentifier().toString(), + function); + } + + Iterator> it2 = supportedAbstractFunctions.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry entry = it2.next(); + URI id = (URI)(entry.getKey()); + FunctionProxy proxy = + (FunctionProxy)(entry.getValue()); + this.functionMap.put(id.toString(), proxy); + } + } + + /** + * Adds the function to the factory. Most functions have no state, so + * the singleton model used here is typically desireable. The factory will + * not enforce the requirement that a Target or Condition matching function + * must be boolean. If a function is already contained in the factory, an + * error will be thrown. + * + * @param function the Function to add to the factory + * + * @throws IllegalArgumentException if the function's identifier is already + * used or if the function is non-boolean + * (when this is a Target or Condition + * factory) + */ + public void addFunction(Function function) + throws IllegalArgumentException + { + addFunction(function, false); + } + + /** + * Adds the function to the factory. Most functions have no state, so + * the singleton model used here is typically desireable. The factory will + * not enforce the requirement that a Target or Condition matching function + * must be boolean. + * + * Allows to define if an already existing function should be overwritten + * or not. + * + * * @param function the Function to add to the factory + * + * @throws IllegalArgumentException if the function's identifier is already + * used or if the function is non-boolean + * (when this is a Target or Condition + * factory) + */ + @Override + public void addFunction(Function function, boolean overwrite) + throws IllegalArgumentException { + + String id = function.getIdentifier().toString(); + + // make sure this doesn't already exist + if (! overwrite && this.functionMap.containsKey(id)) { + throw new IllegalArgumentException("function already exists"); + } + + // add to the superset factory + if (this.superset != null) { + this.superset.addFunction(function); + } + + // finally, add to this factory + this.functionMap.put(id, function); + + } + + /** + * Adds the abstract function proxy to the factory. This is used for + * those functions which have state, or change behavior (for instance + * the standard map function, which changes its return type based on + * how it is used). + * + * @param proxy the FunctionProxy to add to the factory + * @param identity the function's identifier + * + * @throws IllegalArgumentException if the function's identifier is already + * used + */ + public void addAbstractFunction(FunctionProxy proxy, + URI identity) + throws IllegalArgumentException + { + String id = identity.toString(); + + // make sure this doesn't already exist + if (this.functionMap.containsKey(id)) { + throw new IllegalArgumentException("function already exists"); + } + // add to the superset factory + if (this.superset != null) { + this.superset.addAbstractFunction(proxy, identity); + } + // finally, add to this factory + this.functionMap.put(id, proxy); + } + + /** + * Returns the function identifiers supported by this factory. + * + * @return a Set of Strings + */ + public Set getSupportedFunctions() { + Set set = new HashSet(this.functionMap.keySet()); + + if (this.superset != null) { + set.addAll(this.superset.getSupportedFunctions()); + } + return set; + } + + /** + * Tries to get an instance of the specified function. + * + * @param identity the name of the function + * + * @return The function. + * + * @throws UnknownIdentifierException if the name isn't known + * @throws FunctionTypeException if the name is known to map to an + * abstract function, and should therefore + * be created through createAbstractFunction + */ + public Function createFunction(URI identity) + throws UnknownIdentifierException, FunctionTypeException + { + return createFunction(identity.toString()); + } + + /** + * Tries to get an instance of the specified function. + * + * @param identity the name of the function + * + * @throws UnknownIdentifierException if the name isn't known + * @throws FunctionTypeException if the name is known to map to an + * abstract function, and should therefore + * be created through createAbstractFunction + * + * @return The function. + */ + public Function createFunction(String identity) + throws UnknownIdentifierException, FunctionTypeException + { + Object entry = this.functionMap.get(identity); + + if (entry != null) { + if (entry instanceof Function) { + return (Function)entry; + } + // this is actually a proxy, which means the other create + // method should have been called + throw new FunctionTypeException("function is abstract"); + } + // we couldn't find a match + throw new UnknownIdentifierException("functions of type " + + identity + " are not supported by this factory"); + } + + /** + * Tries to get an instance of the specified abstract function. + * + * @param identity the name of the function + * @param root the DOM root containing info used to create the function + * + * @throws UnknownIdentifierException if the name isn't known + * @throws FunctionTypeException if the name is known to map to a + * concrete function, and should therefore + * be created through createFunction + * + * @return The function. + * + * @throws ParsingException if the function can't be created with the + * given inputs + */ + public Function createAbstractFunction(URI identity, Node root) + throws UnknownIdentifierException, ParsingException, + FunctionTypeException + { + return createAbstractFunction(identity.toString(), root, null); + } + + /** + * Tries to get an instance of the specified abstract function. + * + * @param identity the name of the function + * @param root the DOM root containing info used to create the function + * @param xpathVersion the version specified in the contianing policy, or + * null if no version was specified + * + * @throws UnknownIdentifierException if the name isn't known + * @throws FunctionTypeException if the name is known to map to a + * concrete function, and should therefore + * be created through createFunction + * + * @return The function. + * + * @throws ParsingException if the function can't be created with the + * given inputs + */ + public Function createAbstractFunction(URI identity, Node root, + String xpathVersion) + throws UnknownIdentifierException, ParsingException, + FunctionTypeException + { + return createAbstractFunction(identity.toString(), root, xpathVersion); + } + + /** + * Tries to get an instance of the specified abstract function. + * + * @param identity the name of the function + * @param root the DOM root containing info used to create the function + * + * @throws UnknownIdentifierException if the name isn't known + * @throws FunctionTypeException if the name is known to map to a + * concrete function, and should therefore + * be created through createFunction + * + * @return The function. + * + * @throws ParsingException if the function can't be created with the + * given inputs + */ + public Function createAbstractFunction(String identity, Node root) + throws UnknownIdentifierException, ParsingException, + FunctionTypeException + { + return createAbstractFunction(identity, root, null); + } + + /** + * Tries to get an instance of the specified abstract function. + * + * @param identity the name of the function + * @param root the DOM root containing info used to create the function + * @param xpathVersion the version specified in the contianing policy, or + * null if no version was specified + * + * @return The function. + * + * @throws UnknownIdentifierException if the name isn't known + * @throws FunctionTypeException if the name is known to map to a + * concrete function, and should therefore + * be created through createFunction + * @throws ParsingException if the function can't be created with the + * given inputs + */ + public Function createAbstractFunction(String identity, Node root, + String xpathVersion) + throws UnknownIdentifierException, ParsingException, + FunctionTypeException { + Object entry = this.functionMap.get(identity); + + if (entry != null) { + if (entry instanceof FunctionProxy) { + try { + return ((FunctionProxy)entry).getInstance(root, + xpathVersion); + } catch (Exception e) { + throw new ParsingException("couldn't create abstract" + + " function " + identity, e); + } + } + // this is actually a concrete function, which means that + // the other create method should have been called + throw new FunctionTypeException("function is concrete"); + } + // we couldn't find a match + throw new UnknownIdentifierException("abstract functions of " + + "type " + identity + + " are not supported by " + + "this factory"); + } + + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/BasicFunctionFactoryProxy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/BasicFunctionFactoryProxy.java new file mode 100644 index 0000000..17a64fb --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/BasicFunctionFactoryProxy.java @@ -0,0 +1,81 @@ + +/* + * @(#)BasicFunctionFactoryProxy.java + * + * Copyright 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.cond; + + +/** + * A simple utility class that manages triples of function factories. + * + * @since 1.2 + * @author Seth Proctor + */ +public class BasicFunctionFactoryProxy implements FunctionFactoryProxy +{ + + // the triple of factories + private FunctionFactory targetFactory; + private FunctionFactory conditionFactory; + private FunctionFactory generalFactory; + + /** + * Creates a new proxy. + * + * @param targetFactory the target factory provided by this proxy + * @param conditionFactory the target condition provided by this proxy + * @param generalFactory the general factory provided by this proxy + */ + public BasicFunctionFactoryProxy(FunctionFactory targetFactory, + FunctionFactory conditionFactory, + FunctionFactory generalFactory) { + this.targetFactory = targetFactory; + this.conditionFactory = conditionFactory; + this.generalFactory = generalFactory; + } + + public FunctionFactory getTargetFactory() { + return this.targetFactory; + } + + public FunctionFactory getConditionFactory() { + return this.conditionFactory; + } + + public FunctionFactory getGeneralFactory() { + return this.generalFactory; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/ComparisonFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/ComparisonFunction.java new file mode 100644 index 0000000..feba8cb --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/ComparisonFunction.java @@ -0,0 +1,711 @@ + +/* + * @(#)ComparisonFunction.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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BooleanAttribute; +import com.sun.xacml.attr.DateAttribute; +import com.sun.xacml.attr.DateTimeAttribute; +import com.sun.xacml.attr.DoubleAttribute; +import com.sun.xacml.attr.IntegerAttribute; +import com.sun.xacml.attr.StringAttribute; +import com.sun.xacml.attr.TimeAttribute; + +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Set; + + +/** + * A class that implements all of the standard comparison functions. + * + * @since 1.0 + * @author Steve Hanna + * @author Seth Proctor + */ +public class ComparisonFunction extends FunctionBase +{ + + /** + * Standard identifier for the integer-greater-than function. + */ + public static final String NAME_INTEGER_GREATER_THAN = + FUNCTION_NS + "integer-greater-than"; + + /** + * Standard identifier for the integer-greater-than-or-equal function. + */ + public static final String NAME_INTEGER_GREATER_THAN_OR_EQUAL = + FUNCTION_NS + "integer-greater-than-or-equal"; + + /** + * Standard identifier for the integer-less-than function. + */ + public static final String NAME_INTEGER_LESS_THAN = + FUNCTION_NS + "integer-less-than"; + + /** + * Standard identifier for the integer-less-than-or-equal function. + */ + public static final String NAME_INTEGER_LESS_THAN_OR_EQUAL = + FUNCTION_NS + "integer-less-than-or-equal"; + + + /** + * Standard identifier for the double-greater-than function. + */ + public static final String NAME_DOUBLE_GREATER_THAN = + FUNCTION_NS + "double-greater-than"; + + /** + * Standard identifier for the double-greater-than-or-equal function. + */ + public static final String NAME_DOUBLE_GREATER_THAN_OR_EQUAL = + FUNCTION_NS + "double-greater-than-or-equal"; + + /** + * Standard identifier for the double-less-than function. + */ + public static final String NAME_DOUBLE_LESS_THAN = + FUNCTION_NS + "double-less-than"; + + /** + * Standard identifier for the double-less-than-or-equal function. + */ + public static final String NAME_DOUBLE_LESS_THAN_OR_EQUAL = + FUNCTION_NS + "double-less-than-or-equal"; + + + /** + * Standard identifier for the string-greater-than function. + */ + public static final String NAME_STRING_GREATER_THAN = + FUNCTION_NS + "string-greater-than"; + + /** + * Standard identifier for the string-greater-than-or-equal function. + */ + public static final String NAME_STRING_GREATER_THAN_OR_EQUAL = + FUNCTION_NS + "string-greater-than-or-equal"; + + /** + * Standard identifier for the string-less-than function. + */ + public static final String NAME_STRING_LESS_THAN = + FUNCTION_NS + "string-less-than"; + + /** + * Standard identifier for the string-less-than-or-equal function. + */ + public static final String NAME_STRING_LESS_THAN_OR_EQUAL = + FUNCTION_NS + "string-less-than-or-equal"; + + + /** + * Standard identifier for the time-greater-than function. + */ + public static final String NAME_TIME_GREATER_THAN = + FUNCTION_NS + "time-greater-than"; + + /** + * Standard identifier for the time-greater-than-or-equal function. + */ + public static final String NAME_TIME_GREATER_THAN_OR_EQUAL = + FUNCTION_NS + "time-greater-than-or-equal"; + + /** + * Standard identifier for the time-less-than function. + */ + public static final String NAME_TIME_LESS_THAN = + FUNCTION_NS + "time-less-than"; + + /** + * Standard identifier for the time-less-than-or-equal function. + */ + public static final String NAME_TIME_LESS_THAN_OR_EQUAL = + FUNCTION_NS + "time-less-than-or-equal"; + + + /** + * Standard identifier for the dateTime-greater-than function. + */ + public static final String NAME_DATETIME_GREATER_THAN = + FUNCTION_NS + "dateTime-greater-than"; + + /** + * Standard identifier for the dateTime-greater-than-or-equal function. + */ + public static final String NAME_DATETIME_GREATER_THAN_OR_EQUAL = + FUNCTION_NS + "dateTime-greater-than-or-equal"; + + /** + * Standard identifier for the dateTime-less-than function. + */ + public static final String NAME_DATETIME_LESS_THAN = + FUNCTION_NS + "dateTime-less-than"; + + /** + * Standard identifier for the dateTime-less-than-or-equal function. + */ + public static final String NAME_DATETIME_LESS_THAN_OR_EQUAL = + FUNCTION_NS + "dateTime-less-than-or-equal"; + + + /** + * Standard identifier for the date-greater-than function. + */ + public static final String NAME_DATE_GREATER_THAN = + FUNCTION_NS + "date-greater-than"; + + /** + * Standard identifier for the date-greater-than-or-equal function. + */ + public static final String NAME_DATE_GREATER_THAN_OR_EQUAL = + FUNCTION_NS + "date-greater-than-or-equal"; + + /** + * Standard identifier for the date-less-than function. + */ + public static final String NAME_DATE_LESS_THAN = + FUNCTION_NS + "date-less-than"; + + /** + * Standard identifier for the date-less-than-or-equal function. + */ + public static final String NAME_DATE_LESS_THAN_OR_EQUAL = + FUNCTION_NS + "date-less-than-or-equal"; + + // private identifiers for the supported functions + private static final int ID_INTEGER_GREATER_THAN = 0; + private static final int ID_INTEGER_GREATER_THAN_OR_EQUAL = 1; + private static final int ID_INTEGER_LESS_THAN = 2; + private static final int ID_INTEGER_LESS_THAN_OR_EQUAL = 3; + private static final int ID_DOUBLE_GREATER_THAN = 4; + private static final int ID_DOUBLE_GREATER_THAN_OR_EQUAL = 5; + private static final int ID_DOUBLE_LESS_THAN = 6; + private static final int ID_DOUBLE_LESS_THAN_OR_EQUAL = 7; + private static final int ID_STRING_GREATER_THAN = 8; + private static final int ID_STRING_GREATER_THAN_OR_EQUAL = 9; + private static final int ID_STRING_LESS_THAN = 10; + private static final int ID_STRING_LESS_THAN_OR_EQUAL = 11; + private static final int ID_TIME_GREATER_THAN = 12; + private static final int ID_TIME_GREATER_THAN_OR_EQUAL = 13; + private static final int ID_TIME_LESS_THAN = 14; + private static final int ID_TIME_LESS_THAN_OR_EQUAL = 15; + private static final int ID_DATE_GREATER_THAN = 16; + private static final int ID_DATE_GREATER_THAN_OR_EQUAL = 17; + private static final int ID_DATE_LESS_THAN = 18; + private static final int ID_DATE_LESS_THAN_OR_EQUAL = 19; + private static final int ID_DATETIME_GREATER_THAN = 20; + private static final int ID_DATETIME_GREATER_THAN_OR_EQUAL = 21; + private static final int ID_DATETIME_LESS_THAN = 22; + private static final int ID_DATETIME_LESS_THAN_OR_EQUAL = 23; + + // mappings from name to private identifier and argument datatype + private static HashMap idMap; + private static HashMap typeMap; + + /** + * Static initializer to setup the two maps. + */ + static { + idMap = new HashMap(); + + idMap.put(NAME_INTEGER_GREATER_THAN, + Integer.valueOf(ID_INTEGER_GREATER_THAN)); + idMap.put(NAME_INTEGER_GREATER_THAN_OR_EQUAL, + Integer.valueOf(ID_INTEGER_GREATER_THAN_OR_EQUAL)); + idMap.put(NAME_INTEGER_LESS_THAN, + Integer.valueOf(ID_INTEGER_LESS_THAN)); + idMap.put(NAME_INTEGER_LESS_THAN_OR_EQUAL, + Integer.valueOf(ID_INTEGER_LESS_THAN_OR_EQUAL)); + idMap.put(NAME_DOUBLE_GREATER_THAN, + Integer.valueOf(ID_DOUBLE_GREATER_THAN)); + idMap.put(NAME_DOUBLE_GREATER_THAN_OR_EQUAL, + Integer.valueOf(ID_DOUBLE_GREATER_THAN_OR_EQUAL)); + idMap.put(NAME_DOUBLE_LESS_THAN, + Integer.valueOf(ID_DOUBLE_LESS_THAN)); + idMap.put(NAME_DOUBLE_LESS_THAN_OR_EQUAL, + Integer.valueOf(ID_DOUBLE_LESS_THAN_OR_EQUAL)); + idMap.put(NAME_STRING_GREATER_THAN, + Integer.valueOf(ID_STRING_GREATER_THAN)); + idMap.put(NAME_STRING_GREATER_THAN_OR_EQUAL, + Integer.valueOf(ID_STRING_GREATER_THAN_OR_EQUAL)); + idMap.put(NAME_STRING_LESS_THAN, + Integer.valueOf(ID_STRING_LESS_THAN)); + idMap.put(NAME_STRING_LESS_THAN_OR_EQUAL, + Integer.valueOf(ID_STRING_LESS_THAN_OR_EQUAL)); + idMap.put(NAME_TIME_GREATER_THAN, + Integer.valueOf(ID_TIME_GREATER_THAN)); + idMap.put(NAME_TIME_GREATER_THAN_OR_EQUAL, + Integer.valueOf(ID_TIME_GREATER_THAN_OR_EQUAL)); + idMap.put(NAME_TIME_LESS_THAN, + Integer.valueOf(ID_TIME_LESS_THAN)); + idMap.put(NAME_TIME_LESS_THAN_OR_EQUAL, + Integer.valueOf(ID_TIME_LESS_THAN_OR_EQUAL)); + idMap.put(NAME_DATE_GREATER_THAN, + Integer.valueOf(ID_DATE_GREATER_THAN)); + idMap.put(NAME_DATE_GREATER_THAN_OR_EQUAL, + Integer.valueOf(ID_DATE_GREATER_THAN_OR_EQUAL)); + idMap.put(NAME_DATE_LESS_THAN, + Integer.valueOf(ID_DATE_LESS_THAN)); + idMap.put(NAME_DATE_LESS_THAN_OR_EQUAL, + Integer.valueOf(ID_DATE_LESS_THAN_OR_EQUAL)); + idMap.put(NAME_DATETIME_GREATER_THAN, + Integer.valueOf(ID_DATETIME_GREATER_THAN)); + idMap.put(NAME_DATETIME_GREATER_THAN_OR_EQUAL, + Integer.valueOf(ID_DATETIME_GREATER_THAN_OR_EQUAL)); + idMap.put(NAME_DATETIME_LESS_THAN, + Integer.valueOf(ID_DATETIME_LESS_THAN)); + idMap.put(NAME_DATETIME_LESS_THAN_OR_EQUAL, + Integer.valueOf(ID_DATETIME_LESS_THAN_OR_EQUAL)); + + typeMap = new HashMap(); + + typeMap.put(NAME_INTEGER_GREATER_THAN, IntegerAttribute.identifier); + typeMap.put(NAME_INTEGER_GREATER_THAN_OR_EQUAL, + IntegerAttribute.identifier); + typeMap.put(NAME_INTEGER_LESS_THAN, IntegerAttribute.identifier); + typeMap.put(NAME_INTEGER_LESS_THAN_OR_EQUAL, + IntegerAttribute.identifier); + typeMap.put(NAME_DOUBLE_GREATER_THAN, DoubleAttribute.identifier); + typeMap.put(NAME_DOUBLE_GREATER_THAN_OR_EQUAL, + DoubleAttribute.identifier); + typeMap.put(NAME_DOUBLE_LESS_THAN, DoubleAttribute.identifier); + typeMap.put(NAME_DOUBLE_LESS_THAN_OR_EQUAL, + DoubleAttribute.identifier); + typeMap.put(NAME_STRING_GREATER_THAN, StringAttribute.identifier); + typeMap.put(NAME_STRING_GREATER_THAN_OR_EQUAL, + StringAttribute.identifier); + typeMap.put(NAME_STRING_LESS_THAN, StringAttribute.identifier); + typeMap.put(NAME_STRING_LESS_THAN_OR_EQUAL, + StringAttribute.identifier); + typeMap.put(NAME_TIME_GREATER_THAN, TimeAttribute.identifier); + typeMap.put(NAME_TIME_GREATER_THAN_OR_EQUAL, TimeAttribute.identifier); + typeMap.put(NAME_TIME_LESS_THAN, TimeAttribute.identifier); + typeMap.put(NAME_TIME_LESS_THAN_OR_EQUAL, TimeAttribute.identifier); + typeMap.put(NAME_DATETIME_GREATER_THAN, DateTimeAttribute.identifier); + typeMap.put(NAME_DATETIME_GREATER_THAN_OR_EQUAL, + DateTimeAttribute.identifier); + typeMap.put(NAME_DATETIME_LESS_THAN, DateTimeAttribute.identifier); + typeMap.put(NAME_DATETIME_LESS_THAN_OR_EQUAL, + DateTimeAttribute.identifier); + typeMap.put(NAME_DATE_GREATER_THAN, DateAttribute.identifier); + typeMap.put(NAME_DATE_GREATER_THAN_OR_EQUAL, DateAttribute.identifier); + typeMap.put(NAME_DATE_LESS_THAN, DateAttribute.identifier); + typeMap.put(NAME_DATE_LESS_THAN_OR_EQUAL, DateAttribute.identifier); + } + + /** + * Creates a new ComparisonFunction object. + * + * @param functionName the standard XACML name of the function to be + * handled by this object, including the full namespace + * + * @throws IllegalArgumentException if the function isn't known + */ + public ComparisonFunction(String functionName) { + super(functionName, getId(functionName), getArgumentType(functionName), + false, 2, BooleanAttribute.identifier, false); + } + + /** + * Private helper that returns the internal identifier used for the + * given standard function. + */ + private static int getId(String functionName) { + Integer i = (Integer)(idMap.get(functionName)); + + if (i == null) { + throw new IllegalArgumentException("unknown comparison function " + + functionName); + } + return i.intValue(); + } + + /** + * Private helper that returns the type used for the given standard + * function. Note that this doesn't check on the return value since the + * method always is called after getId, so we assume that the function + * is present. + */ + private static String getArgumentType(String functionName) { + return (String)(typeMap.get(functionName)); + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + return Collections.unmodifiableSet(idMap.keySet()); + } + + /** + * Evaluate the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + // Evaluate the arguments + AttributeValue [] argValues = new AttributeValue [inputs.size()]; + EvaluationResult result = evalArgs(inputs, context, argValues); + if (result != null) { + return result; + } + // Now that we have real values, perform the comparison operation + + boolean boolResult = false; + + switch (getFunctionId()) { + + case ID_INTEGER_GREATER_THAN: { + long arg0 = ((IntegerAttribute)(argValues[0])).getValue(); + long arg1 = ((IntegerAttribute)(argValues[1])).getValue(); + + boolResult = (arg0 > arg1); + + break; + } + + case ID_INTEGER_GREATER_THAN_OR_EQUAL: { + long arg0 = ((IntegerAttribute)(argValues[0])).getValue(); + long arg1 = ((IntegerAttribute)(argValues[1])).getValue(); + + boolResult = (arg0 >= arg1); + + break; + } + + case ID_INTEGER_LESS_THAN: { + long arg0 = ((IntegerAttribute)(argValues[0])).getValue(); + long arg1 = ((IntegerAttribute)(argValues[1])).getValue(); + + boolResult = (arg0 < arg1); + + break; + } + + case ID_INTEGER_LESS_THAN_OR_EQUAL: { + long arg0 = ((IntegerAttribute)(argValues[0])).getValue(); + long arg1 = ((IntegerAttribute)(argValues[1])).getValue(); + + boolResult = (arg0 <= arg1); + + break; + } + + case ID_DOUBLE_GREATER_THAN: { + double arg0 = ((DoubleAttribute)(argValues[0])).getValue(); + double arg1 = ((DoubleAttribute)(argValues[1])).getValue(); + + boolResult = (doubleCompare(arg0, arg1) > 0); + + break; + } + + case ID_DOUBLE_GREATER_THAN_OR_EQUAL: { + double arg0 = ((DoubleAttribute)(argValues[0])).getValue(); + double arg1 = ((DoubleAttribute)(argValues[1])).getValue(); + + boolResult = (doubleCompare(arg0, arg1) >= 0); + + break; + } + + case ID_DOUBLE_LESS_THAN: { + double arg0 = ((DoubleAttribute)(argValues[0])).getValue(); + double arg1 = ((DoubleAttribute)(argValues[1])).getValue(); + + boolResult = (doubleCompare(arg0, arg1) < 0); + + break; + } + + case ID_DOUBLE_LESS_THAN_OR_EQUAL: { + double arg0 = ((DoubleAttribute)(argValues[0])).getValue(); + double arg1 = ((DoubleAttribute)(argValues[1])).getValue(); + + boolResult = (doubleCompare(arg0, arg1) <= 0); + + break; + } + + case ID_STRING_GREATER_THAN: { + String arg0 = ((StringAttribute)(argValues[0])).getValue(); + String arg1 = ((StringAttribute)(argValues[1])).getValue(); + + boolResult = (arg0.compareTo(arg1) > 0); + + break; + } + + case ID_STRING_GREATER_THAN_OR_EQUAL: { + String arg0 = ((StringAttribute)(argValues[0])).getValue(); + String arg1 = ((StringAttribute)(argValues[1])).getValue(); + + boolResult = (arg0.compareTo(arg1) >= 0); + + break; + } + + case ID_STRING_LESS_THAN: { + String arg0 = ((StringAttribute)(argValues[0])).getValue(); + String arg1 = ((StringAttribute)(argValues[1])).getValue(); + + boolResult = (arg0.compareTo(arg1) < 0); + + break; + } + + case ID_STRING_LESS_THAN_OR_EQUAL: { + String arg0 = ((StringAttribute)(argValues[0])).getValue(); + String arg1 = ((StringAttribute)(argValues[1])).getValue(); + + boolResult = (arg0.compareTo(arg1) <= 0); + + break; + } + + case ID_TIME_GREATER_THAN: { + TimeAttribute arg0 = (TimeAttribute)(argValues[0]); + TimeAttribute arg1 = (TimeAttribute)(argValues[1]); + + boolResult = + (dateCompare(arg0.getValue(), arg0.getNanoseconds(), + arg1.getValue(), arg1.getNanoseconds()) > 0); + + break; + } + + case ID_TIME_GREATER_THAN_OR_EQUAL: { + TimeAttribute arg0 = (TimeAttribute)(argValues[0]); + TimeAttribute arg1 = (TimeAttribute)(argValues[1]); + + boolResult = + (dateCompare(arg0.getValue(), arg0.getNanoseconds(), + arg1.getValue(), arg1.getNanoseconds()) >= 0); + + break; + } + + case ID_TIME_LESS_THAN: { + TimeAttribute arg0 = (TimeAttribute)(argValues[0]); + TimeAttribute arg1 = (TimeAttribute)(argValues[1]); + + boolResult = + (dateCompare(arg0.getValue(), arg0.getNanoseconds(), + arg1.getValue(), arg1.getNanoseconds()) < 0); + + break; + } + + case ID_TIME_LESS_THAN_OR_EQUAL: { + TimeAttribute arg0 = (TimeAttribute)(argValues[0]); + TimeAttribute arg1 = (TimeAttribute)(argValues[1]); + + boolResult = + (dateCompare(arg0.getValue(), arg0.getNanoseconds(), + arg1.getValue(), arg1.getNanoseconds()) <= 0); + + break; + } + + case ID_DATETIME_GREATER_THAN: { + DateTimeAttribute arg0 = (DateTimeAttribute)(argValues[0]); + DateTimeAttribute arg1 = (DateTimeAttribute)(argValues[1]); + + boolResult = + (dateCompare(arg0.getValue(), arg0.getNanoseconds(), + arg1.getValue(), arg1.getNanoseconds()) > 0); + + break; + } + + case ID_DATETIME_GREATER_THAN_OR_EQUAL: { + DateTimeAttribute arg0 = (DateTimeAttribute)(argValues[0]); + DateTimeAttribute arg1 = (DateTimeAttribute)(argValues[1]); + + boolResult = + (dateCompare(arg0.getValue(), arg0.getNanoseconds(), + arg1.getValue(), arg1.getNanoseconds()) >= 0); + + break; + } + + case ID_DATETIME_LESS_THAN: { + DateTimeAttribute arg0 = (DateTimeAttribute)(argValues[0]); + DateTimeAttribute arg1 = (DateTimeAttribute)(argValues[1]); + + boolResult = + (dateCompare(arg0.getValue(), arg0.getNanoseconds(), + arg1.getValue(), arg1.getNanoseconds()) < 0); + + break; + } + + case ID_DATETIME_LESS_THAN_OR_EQUAL: { + DateTimeAttribute arg0 = (DateTimeAttribute)(argValues[0]); + DateTimeAttribute arg1 = (DateTimeAttribute)(argValues[1]); + + boolResult = + (dateCompare(arg0.getValue(), arg0.getNanoseconds(), + arg1.getValue(), arg1.getNanoseconds()) <= 0); + + break; + } + + case ID_DATE_GREATER_THAN: { + Date arg0 = ((DateAttribute)(argValues[0])).getValue(); + Date arg1 = ((DateAttribute)(argValues[1])).getValue(); + + boolResult = (arg0.compareTo(arg1) > 0); + + break; + } + + case ID_DATE_GREATER_THAN_OR_EQUAL: { + Date arg0 = ((DateAttribute)(argValues[0])).getValue(); + Date arg1 = ((DateAttribute)(argValues[1])).getValue(); + + boolResult = (arg0.compareTo(arg1) >= 0); + + break; + } + + case ID_DATE_LESS_THAN: { + Date arg0 = ((DateAttribute)(argValues[0])).getValue(); + Date arg1 = ((DateAttribute)(argValues[1])).getValue(); + + boolResult = (arg0.compareTo(arg1) < 0); + + break; + } + + case ID_DATE_LESS_THAN_OR_EQUAL: { + Date arg0 = ((DateAttribute)(argValues[0])).getValue(); + Date arg1 = ((DateAttribute)(argValues[1])).getValue(); + + boolResult = (arg0.compareTo(arg1) <= 0); + + break; + } + + } + + // Return the result as a BooleanAttribute. + return EvaluationResult.getInstance(boolResult); + } + + /** + * Helper function that does a comparison of the two doubles using the + * rules of XMLSchema. Like all compare methods, this returns 0 if they're + * equal, a positive value if d1 > d2, and a negative value if d1 < d2. + */ + private int doubleCompare(double d1, double d2) { + // see if the numbers equal each other + if (d1 == d2) { + // these are not NaNs, and therefore we just need to check that + // that they're not zeros, which may have different signs + if (d1 != 0) { + return 0; + } + + // they're both zeros, so we compare strings to figure out + // the significance of any signs + return Double.toString(d1).compareTo(Double.toString(d2)); + } + + // see if d1 is NaN + if (Double.isNaN(d1)) { + // d1 is NaN, so see if d2 is as well + if (Double.isNaN(d2)) { + // they're both NaNs, so they're equal + return 0; + } + // d1 is always bigger than d2 since it's a NaN + return 1; + } + + // see if d2 is NaN + if (Double.isNaN(d2)) { + // d2 is a NaN, though d1 isn't, so d2 is always bigger + return -1; + } + + // if we got here then neither is a NaN, and the numbers aren't + // equal...given those facts, basic comparison works the same in + // java as it's defined in XMLSchema, so now we can do the simple + // comparison and return whatever we find + return ((d1 > d2) ? 1 : -1); + } + + /** + * Helper function to compare two Date objects and their associated + * nanosecond values. Like all compare methods, this returns 0 if they're + * equal, a positive value if d1 > d2, and a negative value if d1 < d2. + */ + private int dateCompare(Date d1, int n1, Date d2, int n2) { + int compareResult = d1.compareTo(d2); + + // we only worry about the nanosecond values if the Dates are equal + if (compareResult != 0) { + return compareResult; + } + + // see if there's any difference + if (n1 == n2) { + return 0; + } + + // there is some difference in the nanoseconds, and that's how + // we'll determine the comparison + return ((n1 > n2) ? 1 : -1); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/Condition.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/Condition.java new file mode 100644 index 0000000..f644700 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/Condition.java @@ -0,0 +1,409 @@ + +/* + * @(#)Condition.java + * + * Copyright 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.cond; + +import com.sun.xacml.Constants; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.Indenter; +import com.sun.xacml.ParsingException; +import com.sun.xacml.PolicyMetaData; + +import com.sun.xacml.attr.BooleanAttribute; +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.Iterator; +import java.util.List; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + + +/** + * Represents the XACML ConditionType type. It contains exactly one child + * expression that is boolean and returns a single value. This class was + * added in XACML 2.0 + * + * @since 2.0 + * @author Seth Proctor + */ +public class Condition implements Evaluatable +{ + + // a local Boolean URI that is used as the return type + private static URI booleanIdentifier; + + // regardless of version, this contains the Condition's children + private List children; + + // regardless of version, this is an expression that can be evaluated + // directly + private Expression expression; + + // the condition function, which is only used if this is a 1.x condition + private Function function; + + // flags whether this is XACML 1.x or 2.0 + private boolean isVersionOne; + + private RuntimeInfo src; + + // initialize the boolean identifier + static { + try { + booleanIdentifier = new URI(BooleanAttribute.identifier); + } catch (Exception e) { + // we ignore this, since it cannot happen, but it should be + // flagged in case something changes to trip this case + booleanIdentifier = null; + } + } + + /** + * Constructs a Condition as used in XACML 1.x. + * + * @param function the Function to use in evaluating the + * elements in the Condition + * @param expressions the contents of the Condition which will be the + * parameters to the function, each of which is an + * Expression + * + * @throws IllegalArgumentException if the input expressions don't + * match the signature of the function or + * if the function is invalid for use + * in a Condition + */ + public Condition(Function function, List expressions) + throws IllegalArgumentException { + this(function, expressions, null); + } + + /** + * Constructs a Condition as used in XACML 1.x. + * + * @param function the Function to use in evaluating the + * elements in the Condition + * @param expressions the contents of the Condition which will be the + * parameters to the function, each of which is an + * Expression + * + * @throws IllegalArgumentException if the input expressions don't + * match the signature of the function or + * if the function is invalid for use + * in a Condition + */ + public Condition(Function function, List expressions, + RuntimeInfo src) + throws IllegalArgumentException + { + this.src = src; + this.isVersionOne = true; + + // check that the function is valid for a Condition + checkExpression(function); + + + // turn the parameters into an Apply for simplicity + if ( src == null ) { + this.expression = new Apply(function, expressions, null); + } else { + Apply apply = null; + apply = new Apply(function, expressions, src.getSourceLocator(apply, ELEMENT_TYPE.APPLY)); + apply.getRuntimeInfo().setXACMLObject(apply); + this.expression = apply; + } + + // keep track of the function and the children + this.function = function; + this.children = ((Apply)this.expression).getChildren(); + } + + + /** + * Constructs a Condition as used in XACML 2.0. + * + * @param expression the child Expression + * + * @throws IllegalArgumentException if the expression is not boolean or + * returns a bag + */ + public Condition(Expression expression) + throws IllegalArgumentException + { + this.isVersionOne = false; + + // check that the function is valid for a Condition + checkExpression(expression); + + // store the expression + this.expression = expression; + + // there is no function in a 2.0 Condition + this.function = null; + + // store the expression as the child + List list = new ArrayList(); + list.add(this.expression); + this.children = Collections.unmodifiableList(list); + } + + /** + * Private helper for the constructors that checks if a given expression + * is valid for the root of a Condition + */ + private void checkExpression(Expression xpr) { + // make sure it's a boolean expression... + if (! xpr.getType().equals(booleanIdentifier)) { + throw new IllegalArgumentException("A Condition must return a " + + "boolean... cannot create a condition with return typ " + + xpr.getType() + (src != null ? src.getLocationMsgForError() : "")); + } + // ...and that it never returns a bag + if (xpr.returnsBag()) { + throw new IllegalArgumentException("A Condition must not return " + + "a Bag" + (src != null ? src.getLocationMsgForError() : "")); + } + } + + /** + * Returns an instance of Condition based on the given + * DOM root. + * + * @param root the DOM root of a ConditionType XML type + * @param metaData the meta-data associated with the containing policy + * @param manager VariableManager used to connect references + * and definitions while parsing + * + * @return The instance of the condition. + * + * @throws ParsingException if this is not a valid ConditionType + */ + public static Condition getInstance(Node root, PolicyMetaData metaData, + VariableManager manager) + throws ParsingException { + RuntimeInfo src = RuntimeInfo.getRuntimeInfo(root, ELEMENT_TYPE.CONDITION); + // check if this really is a Condition + if (root.getNodeType() != Node.ELEMENT_NODE + || !root.getLocalName().equals("Condition")) { + throw new ParsingException("Can't create a Condition from a" + + root.getLocalName() + " element" + + (src != null ? src.getLocationMsgForError() : "")); + } + if (metaData.getXACMLVersion() < Constants.XACML_VERSION_2_0) { + Apply apply = + Apply.getConditionInstance(root, metaData.getXPathIdentifier(), + manager); + + Condition cond = new Condition(apply.getFunction(), apply.getChildren(), src); + if ( src != null ) { + src.setXACMLObject(cond); + } + return cond; + } + Expression xpr = null; + NodeList nodes = root.getChildNodes(); + + for (int i = 0; i < nodes.getLength(); i++) { + if (nodes.item(i).getNodeType() == Node.ELEMENT_NODE) { + xpr = ExpressionHandler. + parseExpression(nodes.item(i), metaData, manager); + break; + } + } + + Condition cond = new Condition(xpr); + if ( src != null ) { + cond.src = src; + src.setXACMLObject(cond); + } + return cond; + } + + /** + * Returns the Function used by this Condition + * if this is a 1.x condition, or null if this is a 2.0 condition. + * + * @return a Function or null + */ + public Function getFunction() { + return this.function; + } + + /** + * Returns the List of children for this + * Condition. The List contains + * Expressions. The list is unmodifiable. + * + * @return a List of Expressions + */ + public List getChildren() { + return this.children; + } + + public Expression getExpression() { + return this.expression; + } + + /** + * Returns the type of attribute that this object will return on a call + * to evaluate. This is always a boolean, since that's + * all that a Condition is allowed to return. + * + * @return the boolean type + */ + public URI getType() { + return booleanIdentifier; + } + + public RuntimeInfo getRuntimeInfo() { + return this.src; + } + + /** + * Returns whether or not this Condition will return a bag + * of values on evaluation. This always returns false, since a Condition + * isn't allowed to return a bag. + * + * @return false + */ + public boolean returnsBag() { + return false; + } + + /** + * Returns whether or not this Condition will return a bag + * of values on evaluation. This always returns false, since a Condition + * isn't allowed to return a bag. + * + * @deprecated As of 2.0, you should use the returnsBag + * method from the super-interface Expression. + * + * @return false + */ + public boolean evaluatesToBag() { + return false; + } + + /** + * Evaluates the Condition by evaluating its child + * Expression. + * + * @param context the representation of the request + * + * @return the result of trying to evaluate this condition object + */ + public EvaluationResult evaluate(EvaluationCtx context) { + context.newEvent(this); + + EvaluationResult result + = ((Evaluatable)this.expression).evaluate(context); + + context.closeCurrentEvent(result); + return result; + } + + /** + * Encodes this Condition into its XML representation and + * writes this encoding to the given OutputStream 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 Condition into its XML representation and + * writes this encoding to the given OutputStream 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(); + + if (this.isVersionOne) { + out.println(indent + ""); + indenter.in(); + + Iterator it = this.children.iterator(); + while (it.hasNext()) { + Expression xpr = it.next(); + xpr.encode(output, charsetName, indenter); + } + } else { + out.println(indent + ""); + indenter.in(); + + this.expression.encode(output, charsetName, indenter); + } + + indenter.out(); + out.println(indent + ""); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/ConditionBagFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/ConditionBagFunction.java new file mode 100644 index 0000000..fe1b3f7 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/ConditionBagFunction.java @@ -0,0 +1,167 @@ + +/* + * @(#)ConditionBagFunction.java + * + * Copyright 2004-206 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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BagAttribute; +import com.sun.xacml.attr.BooleanAttribute; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Set; + + +/** + * Specific BagFunction class that supports the single + * condition bag function: type-is-in. + * + * @since 1.2 + * @author Seth Proctor + */ +public class ConditionBagFunction extends BagFunction +{ + + // mapping of function name to its associated argument type + private static HashMap argMap; + + /** + * Static initializer that sets up the argument info for all the + * supported functions. + */ + static { + argMap = new HashMap(); + + for (int i = 0; i < baseTypes.length; i++) { + String [] args = { baseTypes[i], baseTypes[i] }; + + argMap.put(FUNCTION_NS + simpleTypes[i] + NAME_BASE_IS_IN, + args); + } + + + + for (int i = 0; i < baseTypes2.length; i++) { + String [] args = { baseTypes2[i], baseTypes2[i] }; + + argMap.put(FUNCTION_NS_2 + simpleTypes2[i] + NAME_BASE_IS_IN, + args); + } + } + + /** + * Constructor that is used to create one of the condition standard bag + * functions. The name supplied must be one of the standard XACML + * functions supported by this class, including the full namespace, + * otherwise an exception is thrown. Look in BagFunction + * for details about the supported names. + * + * @param functionName the name of the function to create + * + * @throws IllegalArgumentException if the function is unknown + */ + public ConditionBagFunction(String functionName) { + super(functionName, 0, getArguments(functionName)); + } + + /** + * Constructor that is used to create instances of condition bag + * functions for new (non-standard) datatypes. This is equivalent to + * using the getInstance methods in BagFunction + * and is generally only used by the run-time configuration code. + * + * @param functionName the name of the new function + * @param datatype the full identifier for the supported datatype + */ + public ConditionBagFunction(String functionName, String datatype) { + super(functionName, 0, new String [] {datatype, datatype}); + } + + /** + * Private helper that returns the argument types for the given standard + * function. + */ + private static String [] getArguments(String functionName) { + String [] args = (String [])(argMap.get(functionName)); + + if (args == null) { + throw new IllegalArgumentException("unknown bag function: " + + functionName); + } + return args; + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + return Collections.unmodifiableSet(argMap.keySet()); + } + + /** + * Evaluate the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + + // Evaluate the arguments + AttributeValue [] argValues = new AttributeValue[inputs.size()]; + EvaluationResult result = evalArgs(inputs, context, argValues); + if (result != null) { + return result; + } + // *-is-in takes a bag and an element of baseType and + // returns a single boolean value + AttributeValue item = argValues[0]; + BagAttribute bag = (BagAttribute)(argValues[1]); + + return new EvaluationResult(BooleanAttribute. + getInstance(bag.contains(item))); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/ConditionSetFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/ConditionSetFunction.java new file mode 100644 index 0000000..fc3c3fd --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/ConditionSetFunction.java @@ -0,0 +1,269 @@ + +/* + * @(#)ConditionSetFunction.java + * + * Copyright 2004-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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BagAttribute; +import com.sun.xacml.attr.BooleanAttribute; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + + +/** + * Specific SetFunction class that supports all of the + * condition set functions: type-at-least-one-member-of, type-subset, and + * type-set-equals. + * + * @since 1.2 + * @author Seth Proctor + */ +public class ConditionSetFunction extends SetFunction +{ + + // private identifiers for the supported functions + private static final int ID_BASE_AT_LEAST_ONE_MEMBER_OF = 0; + private static final int ID_BASE_SUBSET = 1; + private static final int ID_BASE_SET_EQUALS = 2; + + // mapping of function name to its associated id and parameter type + private static HashMap idMap; + private static HashMap typeMap; + + // the actual supported ids + private static Set supportedIds; + + /** + * Static initializer that sets up the paramater info for all the + * supported functions. + */ + static { + idMap = new HashMap(); + typeMap = new HashMap(); + + for (int i = 0; i < baseTypes.length; i++) { + String baseName = FUNCTION_NS + simpleTypes[i]; + String baseType = baseTypes[i]; + + idMap.put(baseName + NAME_BASE_AT_LEAST_ONE_MEMBER_OF, + Integer.valueOf(ID_BASE_AT_LEAST_ONE_MEMBER_OF)); + idMap.put(baseName + NAME_BASE_SUBSET, + Integer.valueOf(ID_BASE_SUBSET)); + idMap.put(baseName + NAME_BASE_SET_EQUALS, + Integer.valueOf(ID_BASE_SET_EQUALS)); + + typeMap.put(baseName + NAME_BASE_AT_LEAST_ONE_MEMBER_OF, baseType); + typeMap.put(baseName + NAME_BASE_SUBSET, baseType); + typeMap.put(baseName + NAME_BASE_SET_EQUALS, baseType); + } + + for (int i = 0; i < baseTypes2.length; i++) { + String baseName = FUNCTION_NS_2 + simpleTypes2[i]; + String baseType = baseTypes2[i]; + + idMap.put(baseName + NAME_BASE_AT_LEAST_ONE_MEMBER_OF, + Integer.valueOf(ID_BASE_AT_LEAST_ONE_MEMBER_OF)); + idMap.put(baseName + NAME_BASE_SUBSET, + Integer.valueOf(ID_BASE_SUBSET)); + idMap.put(baseName + NAME_BASE_SET_EQUALS, + Integer.valueOf(ID_BASE_SET_EQUALS)); + + typeMap.put(baseName + NAME_BASE_AT_LEAST_ONE_MEMBER_OF, baseType); + typeMap.put(baseName + NAME_BASE_SUBSET, baseType); + typeMap.put(baseName + NAME_BASE_SET_EQUALS, baseType); + } + + supportedIds = Collections. + unmodifiableSet(new HashSet(idMap.keySet())); + + idMap.put(NAME_BASE_AT_LEAST_ONE_MEMBER_OF, + Integer.valueOf(ID_BASE_AT_LEAST_ONE_MEMBER_OF)); + idMap.put(NAME_BASE_SUBSET, Integer.valueOf(ID_BASE_SUBSET)); + idMap.put(NAME_BASE_SET_EQUALS, Integer.valueOf(ID_BASE_SET_EQUALS)); + } + + /** + * Constructor that is used to create one of the condition standard + * set functions. The name supplied must be one of the standard XACML + * functions supported by this class, including the full namespace, + * otherwise an exception is thrown. Look in SetFunction + * for details about the supported names. + * + * @param functionName the name of the function to create + * + * @throws IllegalArgumentException if the function is unknown + */ + public ConditionSetFunction(String functionName) { + super(functionName, getId(functionName), getArgumentType(functionName), + BooleanAttribute.identifier, false); + } + + /** + * Constructor that is used to create instances of condition set + * functions for new (non-standard) datatypes. This is equivalent to + * using the getInstance methods in SetFunction + * and is generally only used by the run-time configuration code. + * + * @param functionName the name of the new function + * @param datatype the full identifier for the supported datatype + * @param functionType which kind of Set function, based on the + * NAME_BASE_* fields + */ + public ConditionSetFunction(String functionName, String datatype, + String functionType) { + super(functionName, getId(functionName), datatype, + BooleanAttribute.identifier, false); + } + + /** + * Private helper that returns the internal identifier used for the + * given standard function. + */ + private static int getId(String functionName) { + Integer id = (Integer)(idMap.get(functionName)); + + if (id == null) { + throw new IllegalArgumentException("unknown set function " + + functionName); + } + return id.intValue(); + } + + /** + * Private helper that returns the argument type for the given standard + * function. Note that this doesn't check on the return value since the + * method always is called after getId, so we assume that the function + * is present. + */ + private static String getArgumentType(String functionName) { + return (String)(typeMap.get(functionName)); + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + return supportedIds; + } + + /** + * Evaluates the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + + // Evaluate the arguments + AttributeValue [] argValues = new AttributeValue[inputs.size()]; + EvaluationResult evalResult = evalArgs(inputs, context, argValues); + if (evalResult != null) { + return evalResult; + } + // setup the two bags we'll be using + BagAttribute [] bags = new BagAttribute[2]; + bags[0] = (BagAttribute)(argValues[0]); + bags[1] = (BagAttribute)(argValues[1]); + + AttributeValue result = null; + + switch(getFunctionId()) { + // *-at-least-one-member-of takes two bags of the same type and + // returns a boolean + case ID_BASE_AT_LEAST_ONE_MEMBER_OF: + // true if at least one element in the first argument is in the + // second argument (using the *-is-in semantics) + + result = BooleanAttribute.getFalseInstance(); + Iterator it = bags[0].iterator(); + + while (it.hasNext()) { + if (bags[1].contains((AttributeValue)(it.next()))) { + result = BooleanAttribute.getTrueInstance(); + break; + } + } + + break; + + // *-set-equals takes two bags of the same type and returns + // a boolean + case ID_BASE_SUBSET: + // returns true if the first argument is a subset of the second + // argument (ie, all the elements in the first bag appear in + // the second bag) ... ignore all duplicate values in both + // input bags + + boolean subset = bags[1].containsAll(bags[0]); + result = BooleanAttribute.getInstance(subset); + + break; + + // *-set-equals takes two bags of the same type and returns + // a boolean + case ID_BASE_SET_EQUALS: + + // returns true if the two inputs contain the same elements + // discounting any duplicates in either input ... this is the same + // as applying the and function on the subset function with + // the two inputs, and then the two inputs reversed (ie, are the + // two inputs subsets of each other) + + boolean equals = (bags[1].containsAll(bags[0]) && + bags[0].containsAll(bags[1])); + result = BooleanAttribute.getInstance(equals); + + break; + } + + return new EvaluationResult(result); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/DateMathFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/DateMathFunction.java new file mode 100644 index 0000000..99efd63 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/DateMathFunction.java @@ -0,0 +1,373 @@ + +/* + * @(#)DateMathFunction.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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.DateAttribute; +import com.sun.xacml.attr.DateTimeAttribute; +import com.sun.xacml.attr.DayTimeDurationAttribute; +import com.sun.xacml.attr.YearMonthDurationAttribute; + +import java.util.Calendar; +import java.util.Collections; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.HashMap; +import java.util.List; +import java.util.Set; + + +/** + * A class that implements several of the date math functions. They + * all take two arguments. The first is a DateTimeAttribute or a + * DateAttribute (as the case may be) and the second is a + * DayTimeDurationAttribute or a YearMonthDurationAttribute (as + * the case may be). The function adds or subtracts the second + * argument to/from the first and returns a value of the same + * type as the first argument. If either of the arguments evaluates + * to indeterminate, an indeterminate result is returned. + * + * @since 1.0 + * @author Steve Hanna + * @author Seth Proctor + */ +public class DateMathFunction extends FunctionBase +{ + + /** + * Standard identifier for the dateTime-add-dayTimeDuration function. + */ + public static final String NAME_DATETIME_ADD_DAYTIMEDURATION = + FUNCTION_NS + "dateTime-add-dayTimeDuration"; + + /** + * Standard identifier for the dateTime-subtract-dayTimeDuration function. + */ + public static final String NAME_DATETIME_SUBTRACT_DAYTIMEDURATION = + FUNCTION_NS + "dateTime-subtract-dayTimeDuration"; + + /** + * Standard identifier for the dateTime-add-yearMonthDuration function. + */ + public static final String NAME_DATETIME_ADD_YEARMONTHDURATION = + FUNCTION_NS + "dateTime-add-yearMonthDuration"; + + /** + * Standard identifier for the dateTime-subtract-yearMonthDuration + * function. + */ + public static final String NAME_DATETIME_SUBTRACT_YEARMONTHDURATION = + FUNCTION_NS + "dateTime-subtract-yearMonthDuration"; + + /** + * Standard identifier for the date-add-yearMonthDuration function. + */ + public static final String NAME_DATE_ADD_YEARMONTHDURATION = + FUNCTION_NS + "date-add-yearMonthDuration"; + + /** + * Standard identifier for the date-subtract-yearMonthDuration function. + */ + public static final String NAME_DATE_SUBTRACT_YEARMONTHDURATION = + FUNCTION_NS + "date-subtract-yearMonthDuration"; + + // private identifiers for the supported functions + private static final int ID_DATETIME_ADD_DAYTIMEDURATION = 0; + private static final int ID_DATETIME_SUBTRACT_DAYTIMEDURATION = 1; + private static final int ID_DATETIME_ADD_YEARMONTHDURATION = 2; + private static final int ID_DATETIME_SUBTRACT_YEARMONTHDURATION = 3; + private static final int ID_DATE_ADD_YEARMONTHDURATION = 4; + private static final int ID_DATE_SUBTRACT_YEARMONTHDURATION = 5; + + // Argument types + private static final String dateTimeDayTimeDurationArgTypes [] = + { DateTimeAttribute.identifier, + DayTimeDurationAttribute.identifier }; + private static final String dateTimeYearMonthDurationArgTypes [] = + { DateTimeAttribute.identifier, + YearMonthDurationAttribute.identifier }; + private static final String dateYearMonthDurationArgTypes [] = + { DateAttribute.identifier, + YearMonthDurationAttribute.identifier }; + + // nothing here uses a bag + private static final boolean bagParams [] = { false, false }; + + // mapping from name to provide identifiers and argument types + private static HashMap idMap; + private static HashMap typeMap; + + /** + * Static initializer to setup the id and type maps + */ + static { + idMap = new HashMap(); + + idMap.put(NAME_DATETIME_ADD_DAYTIMEDURATION, + Integer.valueOf(ID_DATETIME_ADD_DAYTIMEDURATION)); + idMap.put(NAME_DATETIME_SUBTRACT_DAYTIMEDURATION, + Integer.valueOf(ID_DATETIME_SUBTRACT_DAYTIMEDURATION)); + idMap.put(NAME_DATETIME_ADD_YEARMONTHDURATION, + Integer.valueOf(ID_DATETIME_ADD_YEARMONTHDURATION)); + idMap.put(NAME_DATETIME_SUBTRACT_YEARMONTHDURATION, + Integer.valueOf(ID_DATETIME_SUBTRACT_YEARMONTHDURATION)); + idMap.put(NAME_DATE_ADD_YEARMONTHDURATION, + Integer.valueOf(ID_DATE_ADD_YEARMONTHDURATION)); + idMap.put(NAME_DATE_SUBTRACT_YEARMONTHDURATION, + Integer.valueOf(ID_DATE_SUBTRACT_YEARMONTHDURATION)); + + typeMap = new HashMap(); + + typeMap.put(NAME_DATETIME_ADD_DAYTIMEDURATION, + dateTimeDayTimeDurationArgTypes); + typeMap.put(NAME_DATETIME_SUBTRACT_DAYTIMEDURATION, + dateTimeDayTimeDurationArgTypes); + typeMap.put(NAME_DATETIME_ADD_YEARMONTHDURATION, + dateTimeYearMonthDurationArgTypes); + typeMap.put(NAME_DATETIME_SUBTRACT_YEARMONTHDURATION, + dateTimeYearMonthDurationArgTypes); + typeMap.put(NAME_DATE_ADD_YEARMONTHDURATION, + dateYearMonthDurationArgTypes); + typeMap.put(NAME_DATE_SUBTRACT_YEARMONTHDURATION, + dateYearMonthDurationArgTypes); + } + + /** + * Creates a new DateMathFunction object. + * + * @param functionName the standard XACML name of the function to be + * handled by this object, including the full namespace + * + * @throws IllegalArgumentException if the function is unknown + */ + public DateMathFunction(String functionName) { + super(functionName, getId(functionName), + getArgumentTypes(functionName), bagParams, + getReturnType(functionName), false); + } + + /** + * Private helper that returns the internal identifier used for the + * given standard function. + */ + private static int getId(String functionName) { + Integer i = (Integer)(idMap.get(functionName)); + + if (i == null) { + throw new IllegalArgumentException("unknown datemath function " + + functionName); + } + + return i.intValue(); + } + + /** + * Private helper that returns the types used for the given standard + * function. Note that this doesn't check on the return value since the + * method always is called after getId, so we assume that the function + * is present. + */ + private static String [] getArgumentTypes(String functionName) { + return (String [])(typeMap.get(functionName)); + } + + /** + * Private helper that returns the return type for the given standard + * function. Note that this doesn't check on the return value since the + * method always is called after getId, so we assume that the function + * is present. + */ + private static String getReturnType(String functionName) { + if (functionName.equals(NAME_DATE_ADD_YEARMONTHDURATION) || + functionName.equals(NAME_DATE_SUBTRACT_YEARMONTHDURATION)) { + return DateAttribute.identifier; + } + return DateTimeAttribute.identifier; + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + return Collections.unmodifiableSet(idMap.keySet()); + } + + /** + * Evaluate the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + + // Evaluate the arguments + AttributeValue [] argValues = new AttributeValue[inputs.size()]; + EvaluationResult result = evalArgs(inputs, context, argValues); + if (result != null) { + return result; + } + + // Now that we have real values, perform the date math operation. + AttributeValue attrResult = null; + + switch (getFunctionId()) { + // These two functions are basically the same except for sign. + // And they both need to deal with sign anyway, so they share + // their code. + case ID_DATETIME_ADD_DAYTIMEDURATION: + case ID_DATETIME_SUBTRACT_DAYTIMEDURATION: { + DateTimeAttribute dateTime = (DateTimeAttribute) argValues[0]; + DayTimeDurationAttribute duration = + (DayTimeDurationAttribute) argValues[1]; + + // Decide what sign goes with duration + int sign = 1; + if (getFunctionId() == ID_DATETIME_SUBTRACT_DAYTIMEDURATION) { + sign = -sign; + } + if (duration.isNegative()) { + sign = -sign; + } + long millis = sign * duration.getTotalSeconds(); + long nanoseconds = dateTime.getNanoseconds(); + nanoseconds = nanoseconds + (sign * duration.getNanoseconds()); + if (nanoseconds >= 1000000000) { + nanoseconds -= 1000000000; + millis += 1000; + } + if (nanoseconds < 0) { + nanoseconds += 1000000000; + millis -= 1000; + } + millis = millis + dateTime.getValue().getTime(); + + attrResult = new DateTimeAttribute(new Date(millis), + (int) nanoseconds, + dateTime.getTimeZone(), + dateTime. + getDefaultedTimeZone()); + + break; + } + case ID_DATETIME_ADD_YEARMONTHDURATION: + case ID_DATETIME_SUBTRACT_YEARMONTHDURATION: { + DateTimeAttribute dateTime = (DateTimeAttribute) argValues[0]; + YearMonthDurationAttribute duration = + (YearMonthDurationAttribute) argValues[1]; + + // Decide what sign goes with duration + int sign = 1; + if (getFunctionId() == ID_DATETIME_SUBTRACT_YEARMONTHDURATION) { + sign = -sign; + } + if (duration.isNegative()) { + sign = -sign; + } + + // Add (or subtract) the years and months. + Calendar cal = new GregorianCalendar(); + cal.setTime(dateTime.getValue()); + long years = sign * duration.getYears(); + long months = sign * duration.getMonths(); + if ((years > Integer.MAX_VALUE) || (years < Integer.MIN_VALUE)) { + return makeProcessingError("years too large"); + } + if ((months > Integer.MAX_VALUE) || (months < Integer.MIN_VALUE)) { + return makeProcessingError("months too large"); + } + + cal.add(Calendar.YEAR, (int) years); + cal.add(Calendar.MONTH, (int) months); + + attrResult = new DateTimeAttribute(cal.getTime(), + dateTime.getNanoseconds(), + dateTime.getTimeZone(), + dateTime. + getDefaultedTimeZone()); + + break; + } + case ID_DATE_ADD_YEARMONTHDURATION: + case ID_DATE_SUBTRACT_YEARMONTHDURATION: { + DateAttribute date = (DateAttribute) argValues[0]; + YearMonthDurationAttribute duration = + (YearMonthDurationAttribute) argValues[1]; + + // Decide what sign goes with duration + int sign = 1; + if (getFunctionId() == ID_DATE_SUBTRACT_YEARMONTHDURATION) { + sign = -sign; + } + if (duration.isNegative()) { + sign = -sign; + } + + // Add (or subtract) the years and months. + Calendar cal = new GregorianCalendar(); + cal.setTime(date.getValue()); + long years = sign * duration.getYears(); + long months = sign * duration.getMonths(); + if ((years > Integer.MAX_VALUE) || (years < Integer.MIN_VALUE)) { + return makeProcessingError("years too large"); + } + if ((months > Integer.MAX_VALUE) || (months < Integer.MIN_VALUE)) { + return makeProcessingError("months too large"); + } + + cal.add(Calendar.YEAR, (int) years); + cal.add(Calendar.MONTH, (int) months); + + attrResult = new DateAttribute(cal.getTime(), + date.getTimeZone(), + date.getDefaultedTimeZone()); + + break; + } + } + + return new EvaluationResult(attrResult); + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/DivideFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/DivideFunction.java new file mode 100644 index 0000000..6f0665a --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/DivideFunction.java @@ -0,0 +1,179 @@ + +/* + * @(#)DivideFunction.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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.DoubleAttribute; +import com.sun.xacml.attr.IntegerAttribute; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +/** + * A class that implements all the *-divide functions. It takes two + * operands of the appropriate type and returns the quotient of the + * operands. If either of the operands is indeterminate, an indeterminate + * result is returned. + * + * @since 1.0 + * @author Steve Hanna + * @author Seth Proctor + */ +public class DivideFunction extends FunctionBase +{ + + /** + * Standard identifier for the integer-divide function. + */ + public static final String NAME_INTEGER_DIVIDE = + FUNCTION_NS + "integer-divide"; + + /** + * Standard identifier for the double-divide function. + */ + public static final String NAME_DOUBLE_DIVIDE = + FUNCTION_NS + "double-divide"; + + // inernal identifiers for each of the supported functions + private static final int ID_INTEGER_DIVIDE = 0; + private static final int ID_DOUBLE_DIVIDE = 1; + + /** + * Creates a new DivideFunction object. + * + * @param functionName the standard XACML name of the function to be + * handled by this object, including the full namespace + * + * @throws IllegalArgumentException if the function is unknown + */ + public DivideFunction(String functionName) { + super(functionName, getId(functionName), getArgumentType(functionName), + false, 2, getArgumentType(functionName), false); + } + + /** + * Private helper that returns the internal identifier used for the + * given standard function. + */ + private static int getId(String functionName) { + if (functionName.equals(NAME_INTEGER_DIVIDE)) { + return ID_INTEGER_DIVIDE; + } else if (functionName.equals(NAME_DOUBLE_DIVIDE)) { + return ID_DOUBLE_DIVIDE; + } else { + throw new IllegalArgumentException("unknown divide function " + + functionName); + } + + } + + /** + * Private helper that returns the type used for the given standard + * function. Note that this doesn't check on the return value since the + * method always is called after getId, so we assume that the function + * is present. + */ + private static String getArgumentType(String functionName) { + if (functionName.equals(NAME_INTEGER_DIVIDE)) { + return IntegerAttribute.identifier; + } + return DoubleAttribute.identifier; + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + Set set = new HashSet(); + + set.add(NAME_INTEGER_DIVIDE); + set.add(NAME_DOUBLE_DIVIDE); + + return set; + } + + /** + * Evaluate the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + + // Evaluate the arguments + AttributeValue [] argValues = new AttributeValue[inputs.size()]; + EvaluationResult result = evalArgs(inputs, context, argValues); + if (result != null) { + return result; + } + + // Now that we have real values, perform the divide operation + // in the manner appropriate for the type of the arguments. + if (getFunctionId() == ID_INTEGER_DIVIDE) { + long dividend = ((IntegerAttribute) argValues[0]).getValue(); + long divisor = ((IntegerAttribute) argValues[1]).getValue(); + if (divisor == 0) { + result = makeProcessingError("divide by zero"); + } else { + long quotient = dividend / divisor; + result = new EvaluationResult(new IntegerAttribute(quotient)); + } + } else if (getFunctionId() == ID_DOUBLE_DIVIDE) { + double dividend = ((DoubleAttribute) argValues[0]).getValue(); + double divisor = ((DoubleAttribute) argValues[1]).getValue(); + if (divisor == 0) { + result = makeProcessingError("divide by zero"); + } else { + double quotient = dividend / divisor; + result = new EvaluationResult(new DoubleAttribute(quotient)); + } + } + + return result; + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/EqualFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/EqualFunction.java new file mode 100644 index 0000000..d253fb5 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/EqualFunction.java @@ -0,0 +1,299 @@ + +/* + * @(#)EqualFunction.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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AnyURIAttribute; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.Base64BinaryAttribute; +import com.sun.xacml.attr.BooleanAttribute; +import com.sun.xacml.attr.DateAttribute; +import com.sun.xacml.attr.DateTimeAttribute; +import com.sun.xacml.attr.DayTimeDurationAttribute; +import com.sun.xacml.attr.DNSNameAttribute; +import com.sun.xacml.attr.DoubleAttribute; +import com.sun.xacml.attr.HexBinaryAttribute; +import com.sun.xacml.attr.IntegerAttribute; +import com.sun.xacml.attr.IPAddressAttribute; +import com.sun.xacml.attr.RFC822NameAttribute; +import com.sun.xacml.attr.StringAttribute; +import com.sun.xacml.attr.TimeAttribute; +import com.sun.xacml.attr.YearMonthDurationAttribute; +import com.sun.xacml.attr.X500NameAttribute; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Set; + + +/** + * A class that implements all the *-equal functions. It takes two operands + * of the appropriate type and returns a BooleanAttribute + * indicating whether both of the operands are equal. If either of the + * operands is indeterminate, an indeterminate result is returned. + * + * @since 1.0 + * @author Steve Hanna + * @author Seth Proctor + */ +public class EqualFunction extends FunctionBase +{ + + /** + * Standard identifier for the string-equal function. + */ + public static final String NAME_STRING_EQUAL = + FUNCTION_NS + "string-equal"; + + /** + * Standard identifier for the boolean-equal function. + */ + public static final String NAME_BOOLEAN_EQUAL = + FUNCTION_NS + "boolean-equal"; + + /** + * Standard identifier for the integer-equal function. + */ + public static final String NAME_INTEGER_EQUAL = + FUNCTION_NS + "integer-equal"; + + /** + * Standard identifier for the double-equal function. + */ + public static final String NAME_DOUBLE_EQUAL = + FUNCTION_NS + "double-equal"; + + /** + * Standard identifier for the date-equal function. + */ + public static final String NAME_DATE_EQUAL = + FUNCTION_NS + "date-equal"; + + /** + * Standard identifier for the time-equal function. + */ + public static final String NAME_TIME_EQUAL = + FUNCTION_NS + "time-equal"; + + /** + * Standard identifier for the dateTime-equal function. + */ + public static final String NAME_DATETIME_EQUAL = + FUNCTION_NS + "dateTime-equal"; + + /** + * Standard identifier for the dayTimeDuration-equal function. + */ + public static final String NAME_DAYTIME_DURATION_EQUAL = + FUNCTION_NS + "dayTimeDuration-equal"; + + /** + * Standard identifier for the yearMonthDuration-equal function. + */ + public static final String NAME_YEARMONTH_DURATION_EQUAL = + FUNCTION_NS + "yearMonthDuration-equal"; + + /** + * Standard identifier for the anyURI-equal function. + */ + public static final String NAME_ANYURI_EQUAL = + FUNCTION_NS + "anyURI-equal"; + + /** + * Standard identifier for the x500Name-equal function. + */ + public static final String NAME_X500NAME_EQUAL = + FUNCTION_NS + "x500Name-equal"; + + /** + * Standard identifier for the rfc822Name-equal function. + */ + public static final String NAME_RFC822NAME_EQUAL = + FUNCTION_NS + "rfc822Name-equal"; + + /** + * Standard identifier for the hexBinary-equal function. + */ + public static final String NAME_HEXBINARY_EQUAL = + FUNCTION_NS + "hexBinary-equal"; + + /** + * Standard identifier for the base64Binary-equal function. + */ + public static final String NAME_BASE64BINARY_EQUAL = + FUNCTION_NS + "base64Binary-equal"; + + /** + * Standard identifier for the ipAddress-equal function. + */ + public static final String NAME_IPADDRESS_EQUAL = + FUNCTION_NS_2 + "ipAddress-equal"; + + /** + * Standard identifier for the dnsName-equal function. + */ + public static final String NAME_DNSNAME_EQUAL = + FUNCTION_NS_2 + "dnsName-equal"; + + // private mapping of standard functions to their argument types + private static HashMap typeMap; + + /** + * Static initializer sets up a map of standard function names to their + * associated datatypes + */ + static { + typeMap = new HashMap(); + + typeMap.put(NAME_STRING_EQUAL, StringAttribute.identifier); + typeMap.put(NAME_BOOLEAN_EQUAL, BooleanAttribute.identifier); + typeMap.put(NAME_INTEGER_EQUAL, IntegerAttribute.identifier); + typeMap.put(NAME_DOUBLE_EQUAL, DoubleAttribute.identifier); + typeMap.put(NAME_DATE_EQUAL, DateAttribute.identifier); + typeMap.put(NAME_TIME_EQUAL, TimeAttribute.identifier); + typeMap.put(NAME_DATETIME_EQUAL, DateTimeAttribute.identifier); + typeMap.put(NAME_DAYTIME_DURATION_EQUAL, + DayTimeDurationAttribute.identifier); + typeMap.put(NAME_YEARMONTH_DURATION_EQUAL, + YearMonthDurationAttribute.identifier); + typeMap.put(NAME_ANYURI_EQUAL, AnyURIAttribute.identifier); + typeMap.put(NAME_X500NAME_EQUAL, X500NameAttribute.identifier); + typeMap.put(NAME_RFC822NAME_EQUAL, RFC822NameAttribute.identifier); + typeMap.put(NAME_HEXBINARY_EQUAL, HexBinaryAttribute.identifier); + typeMap.put(NAME_BASE64BINARY_EQUAL, Base64BinaryAttribute.identifier); + typeMap.put(NAME_IPADDRESS_EQUAL, IPAddressAttribute.identifier); + typeMap.put(NAME_DNSNAME_EQUAL, DNSNameAttribute.identifier); + } + + /** + * Returns an EqualFunction that provides the type-equal + * functionality over the given attribute type. This should be used to + * create new function instances for any new attribute types, and the + * resulting object should be put into the FunctionFactory + * (instances for the standard types are pre-installed in the standard + * factory). + *

+ * Note that this method has the same affect as invoking the constructor + * with the same parameters. This method is provided as a convenience, + * and for symmetry with the bag and set functions. + * + * @param functionName the name to use for the function + * @param argumentType the type to operate on + * + * @return a new EqualFunction + */ + public static EqualFunction getEqualInstance(String functionName, + String argumentType) { + return new EqualFunction(functionName, argumentType); + } + + /** + * Creates a new EqualFunction object that supports one + * of the standard type-equal functions. If you need to create an + * instance for a custom type, use the getEqualInstance + * method or the alternate constructor. + * + * @param functionName the standard XACML name of the function to be + * handled by this object, including the full namespace + * + * @throws IllegalArgumentException if the function isn't standard + */ + public EqualFunction(String functionName) { + this(functionName, getArgumentType(functionName)); + } + + /** + * Creates a new EqualFunction object. + * + * @param functionName the standard XACML name of the function to be + * handled by this object, including the full namespace + * @param argumentType the standard XACML name for the type of + * the arguments, inlcuding the full namespace + */ + public EqualFunction(String functionName, String argumentType) { + super(functionName, 0, argumentType, false, 2, + BooleanAttribute.identifier, false); + } + + /** + * Private helper that returns the type used for the given standard + * type-equal function. + */ + private static String getArgumentType(String functionName) { + String datatype = (String)(typeMap.get(functionName)); + + if (datatype == null) { + throw new IllegalArgumentException("not a standard function: " + + functionName); + } + return datatype; + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + return Collections.unmodifiableSet(typeMap.keySet()); + } + + /** + * Evaluate the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + // Evaluate the arguments + AttributeValue [] argValues = new AttributeValue[inputs.size()]; + EvaluationResult result = evalArgs(inputs, context, argValues); + if (result != null) { + return result; + } + // Now that we have real values, perform the equals operation + return EvaluationResult.getInstance(argValues[0].equals(argValues[1])); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/Evaluatable.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/Evaluatable.java new file mode 100644 index 0000000..e2e5baf --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/Evaluatable.java @@ -0,0 +1,75 @@ + +/* + * @(#)Evaluatable.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.cond; + +import com.sun.xacml.EvaluationCtx; + +import java.util.List; + + +/** + * Generic interface that is implemented by all objects that can be evaluated + * directly (AttributeDesignator, Apply, + * AttributeValue, etc.). As of version 2.0 several methods + * were extracted to the new Expression super-interface. + * + * @since 1.0 + * @author Seth Proctor + */ +public interface Evaluatable extends Expression +{ + + /** + * Evaluates the object using the given context, and either returns an + * error or a resulting value. + * + * @param context the representation of the request + * + * @return the result of evaluation + */ + public EvaluationResult evaluate(EvaluationCtx context); + + /** + * Returns all children, in order, of this element in the Condition + * tree, or en empty set if this element has no children. In XACML 1.x, + * only the ApplyType ever has children. + * + * @return a List of Evaluatables + */ + public List getChildren(); + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/EvaluationResult.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/EvaluationResult.java new file mode 100644 index 0000000..16761c8 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/EvaluationResult.java @@ -0,0 +1,195 @@ + +/* + * @(#)EvaluationResult.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.cond; + +import java.util.List; +import java.util.Vector; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BooleanAttribute; + +import com.sun.xacml.ctx.Status; + + +/** + * This is used in cases where a normal result is some AttributeValue, but + * if an attribute couldn't be resolved (or some other problem occurred), + * then a Status object needs to be returned instead. This is used instead of + * throwing an exception for performance, but mainly because failure to resolve + * an attribute is not an error case for the code, merely for the evaluation, + * and represents normal operation. Separate exception types will be added + * later to represent errors in pdp operation. + * + * @since 1.0 + * @author Seth Proctor + * @author Ludwig Seitz + */ +public class EvaluationResult +{ + + /** + * This indicates that the result was indeterminate. + */ + private boolean wasInd; + + /** + * The attribute value returned by this evaluation. + */ + private AttributeValue value; + + /** + * The status of this evaluation (i.e. ok, missing attribute, + * syntax error, processing error) + */ + private Status status; + + /** + * Single instances of EvaluationResults with false and true + * BooleanAttributes in them. This avoids the need to create + * new objects when performing boolean operations, which we + * do a lot of. + */ + private static EvaluationResult falseBooleanResult; + private static EvaluationResult trueBooleanResult; + + /** + * Constructor that creates an EvaluationResult containing + * a single AttributeValue + * + * @param value the attribute value + */ + public EvaluationResult(AttributeValue value) { + this.wasInd = false; + this.value = value; + this.status = null; + } + + /** + * Constructor that creates an EvaluationResult of + * Indeterminate, including Status data. + * + * @param status the error information + */ + public EvaluationResult(Status status) { + this.wasInd = true; + this.value = null; + this.status = status; + } + + /** + * Returns true if the result was indeterminate + * + * @return true if there was an error + */ + public boolean indeterminate() { + return this.wasInd; + } + + /** + * Returns the attribute value, or null if there was an error + * + * @return the attribute value or null + */ + public AttributeValue getAttributeValue() { + return this.value; + } + + /** + * Returns the status if there was an error, or null it no error occurred + * + * @return the status or null + */ + public Status getStatus() { + return this.status; + } + + /** + * Returns an EvaluationResult that represents + * the boolean value provided. + * + * @param value a boolean representing the desired value + * @return an EvaluationResult representing the + * appropriate value + */ + public static EvaluationResult getInstance(boolean value) { + if (value) { + return getTrueInstance(); + } + return getFalseInstance(); + } + + /** + * Returns an EvaluationResult that represents + * a false value. + * + * @return an EvaluationResult representing a + * false value + */ + public static EvaluationResult getFalseInstance() { + if (falseBooleanResult == null) { + falseBooleanResult = + new EvaluationResult(BooleanAttribute.getFalseInstance()); + } + return falseBooleanResult; + } + + /** + * Returns an EvaluationResult that represents + * a true value. + * + * @return an EvaluationResult representing a + * true value + */ + public static EvaluationResult getTrueInstance() { + if (trueBooleanResult == null) { + trueBooleanResult = + new EvaluationResult(BooleanAttribute.getTrueInstance()); + } + return trueBooleanResult; + } + + /** + * Creates a missing attribute evaluation result. + * @param message + * @return + */ + public static EvaluationResult createMissingAttributeInstance(String message) { + List statusMsg = new Vector(); + statusMsg.add(Status.STATUS_MISSING_ATTRIBUTE); + return new EvaluationResult(new Status(statusMsg, message)); + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/Expression.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/Expression.java new file mode 100644 index 0000000..ca708d4 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/Expression.java @@ -0,0 +1,108 @@ + +/* + * @(#)Expression.java + * + * Copyright 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.cond; + +import com.sun.xacml.Indenter; +import com.sun.xacml.debug.Locatable; + +import java.net.URI; +import java.util.Collections; +import java.util.List; + +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; + + +/** + * This interface represents the expression type in the XACML 2.0 schema. + * + * @since 2.0 + * @author Seth Proctor + */ +public interface Expression extends Locatable +{ + public static List EMPTY_LIST = Collections.emptyList(); + + /** + * Returns the type of the expression. This may be the data type of + * an AttributeValue, the return type of a + * Function, etc. + * + * @return the attribute type of the referenced expression + */ + public URI getType(); + + /** + * Returns whether or not this expression returns, or evaluates to a + * Bag. Note that Evaluatable, which extends this interface, + * defines evaluatesToBag which is essentially the same + * function. This method has been deprecated, and returnsBag + * is now the preferred way to query all Expressions. + * + * @return true or false. + */ + public boolean returnsBag(); + + /** + * Encodes this Expression into its XML representation and + * writes this encoding to the given OutputStream 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 Expression into its XML representation and + * writes this encoding to the given OutputStream 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; + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/ExpressionHandler.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/ExpressionHandler.java new file mode 100644 index 0000000..c20ed6b --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/ExpressionHandler.java @@ -0,0 +1,138 @@ + +/* + * ExpressionHandler.java + * + * Created by: seth proctor (stp) + * Created on: Wed Dec 29, 2004 8:24:30 PM + * Desc: + * + */ + +package com.sun.xacml.cond; + +import com.sun.xacml.ParsingException; +import com.sun.xacml.PolicyMetaData; +import com.sun.xacml.UnknownIdentifierException; + +import com.sun.xacml.attr.AttributeDesignator; +import com.sun.xacml.attr.AttributeFactory; +import com.sun.xacml.attr.AttributeSelector; +import com.sun.xacml.debug.RuntimeInfo; +import com.sun.xacml.debug.RuntimeInfo.ELEMENT_TYPE; + +import org.w3c.dom.Node; + + +/** + * This is a package-private utility class that handles parsing all the + * possible expression types. It was added becuase in 2.0 multiple classes + * needed this. Note that this could also be added to Expression and + * that interface could be made an abstract class, but that would require + * substantial change. + * + * @since 2.0 + * @author Seth Proctor + * @author Ludwig Seitz + */ +class ExpressionHandler +{ + + /** + * Parses an expression, recursively handling any sub-elements. This is + * provided as a utility class, but in practice is used only by + * Apply, Condition, and + * VariableDefinition. + * + * @param root the DOM root of an ExpressionType XML type + * @param metaData the meta-data associated with the containing policy + * @param manager VariableManager used to connect references + * and definitions while parsing + * + * @return an Expression or null if the root node cannot be + * parsed as a valid Expression + * + * @throws ParsingException + */ + public static Expression parseExpression(Node root, + PolicyMetaData metaData, VariableManager manager ) + throws ParsingException { + if (root.getNodeType() != Node.ELEMENT_NODE) { + return null; + } + + String name = root.getLocalName(); + + if (name.equals("Apply")) { + return Apply.getInstance(root, metaData, manager); + } else if (name.equals("AttributeValue")) { + try { + return AttributeFactory.getInstance().createValue(root); + } catch (UnknownIdentifierException uie) { + RuntimeInfo src = RuntimeInfo.getRuntimeInfo(root, ELEMENT_TYPE.ATTRIBUTE_VALUE); + throw new ParsingException("Unknown DataType" + + (src != null ? src.getLocationMsgForError() : ""), uie); + } + } else if (name.endsWith("AttributeDesignator")) { + return AttributeDesignator.getInstance(root, metaData); + } else if (name.equals("AttributeSelector")) { + return AttributeSelector.getInstance(root, metaData); + } else if (name.equals("Function")) { + return getFunction(root, metaData, + FunctionFactory.getGeneralInstance()); + } else if (name.equals("VariableReference")) { + return VariableReference.getInstance(root, metaData, manager); + } + + // return null if it was none of these + return null; + } + + /** + * Helper method that tries to get a function instance + * + * @param root the root node of the XML defining this expression. + * @param metaData the policy meta data for this expression. + * @param factory the function factory for this expression. + * + * @return The function of this expression. + * + * @throws ParsingException + */ + public static Function getFunction(Node root, PolicyMetaData metaData, + FunctionFactory factory) + throws ParsingException { + RuntimeInfo src = RuntimeInfo.getRuntimeInfo(root, ELEMENT_TYPE.FUNCTION); + if (root.getNodeType() != Node.ELEMENT_NODE || + root.getAttributes().getNamedItem("FunctionId") == null) { + throw new ParsingException("Error: tried to parse Function from" + + " non Element type node or with missing FunctionId (ELEMENT_NODE: " + + (root.getNodeType() == Node.ELEMENT_NODE) + ", Node: " + root.getLocalName() + + ", FunctionId: " + root.getAttributes().getNamedItem("FunctionId") + ")" + + (src != null ? src.getLocationMsgForError() : "")); + } + Node functionNode = root.getAttributes().getNamedItem("FunctionId"); + String functionName = functionNode.getNodeValue(); + + try { + // try to get an instance of the given function + return factory.createFunction(functionName); + } catch (UnknownIdentifierException uie) { + throw new ParsingException("Unknown FunctionId: " + uie.getMessage() + + (src != null ? src.getLocationMsgForError() : ""), uie); + } catch (FunctionTypeException fte) { + // try creating as an abstract function + try { + FunctionFactory ff = FunctionFactory.getGeneralInstance(); + return ff.createAbstractFunction(functionName, root, + metaData. + getXPathIdentifier()); + } catch (Exception e) { + // any exception at this point is a failure + throw new ParsingException("failed to create abstract function" + + " " + functionName + + (src != null ? src.getLocationMsgForError() : ""), e); + } + } + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FloorFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FloorFunction.java new file mode 100644 index 0000000..1b1ea1c --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FloorFunction.java @@ -0,0 +1,122 @@ + +/* + * @(#)FloorFunction.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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.DoubleAttribute; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +/** + * A class that implements the floor function. It takes one double + * operand, chooses the largest integer less than or equal to that + * value, and returns that integer (as a double). If the operand + * is indeterminate, an indeterminate result is returned. + * + * @since 1.0 + * @author Steve Hanna + * @author Seth Proctor + */ +public class FloorFunction extends FunctionBase +{ + + /** + * Standard identifier for the floor function. + */ + public static final String NAME_FLOOR = FUNCTION_NS + "floor"; + + /** + * Creates a new FloorFunction object. + * + * @param functionName the standard XACML name of the function to be + * handled by this object, including the full namespace + * + * @throws IllegalArgumentException if the function is unknown + */ + public FloorFunction(String functionName) { + super(NAME_FLOOR, 0, DoubleAttribute.identifier, false, 1, + DoubleAttribute.identifier, false); + + if (! functionName.equals(NAME_FLOOR)) { + throw new IllegalArgumentException("unknown floor function: " + + functionName); + } + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + Set set = new HashSet(); + + set.add(NAME_FLOOR); + + return set; + } + + /** + * Evaluate the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + + // Evaluate the arguments + AttributeValue [] argValues = new AttributeValue[inputs.size()]; + EvaluationResult result = evalArgs(inputs, context, argValues); + if (result != null) { + return result; + } + // Now that we have real values, perform the floor operation + double arg = ((DoubleAttribute) argValues[0]).getValue(); + + return new EvaluationResult(new DoubleAttribute(Math.floor(arg))); + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/Function.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/Function.java new file mode 100644 index 0000000..cdcfc40 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/Function.java @@ -0,0 +1,169 @@ + +/* + * @(#)Function.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.cond; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.debug.IndirectLocatable; +import com.sun.xacml.debug.RuntimeInfo; + +import java.net.URI; + +import java.util.List; + + +/** + * Interface that all functions in the system must implement. + * + * @since 1.0 + * @author Seth Proctor + */ +public interface Function extends Expression, IndirectLocatable +{ + + /** + * Evaluates the Function using the given inputs. + * The List contains Evaluatables which are all + * of the correct type if the Function has been created as + * part of an Apply or TargetMatch, but which + * may otherwise be invalid. Each parameter should be evaluated by the + * Function, unless the Function + * doesn't need to evaluate all inputs to determine a result (as in the + * case of the or function). The order of the List is + * significant, so a Function should have a very good reason + * if it wants to evaluate the inputs in a different order. + *

+ * Note that if this is a higher-order function, like any-of, then + * some argument (typically the first) in the List will + * actually be a Function object representing the function to apply to + * some bag. A function needs to know if it's a higher-order function, + * and therefore whether or not to look for this case. Also, a + * higher-order function is responsible for checking that the inputs + * that it will pass to the Function provided as the first + * parameter are valid, ie. it must do a checkInputs on + * its sub-function when checkInputs is called on the + * higher-order function. + * + * @param inputs the List of inputs for the function + * @param context the representation of the request + * + * @return a result containing the AttributeValue computed + * when evaluating the function, or Status + * specifying some error condition + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context); + + /** + * Returns the identifier of this function as known by the factories. + * In the case of the standard XACML functions, this will be one of the + * URIs defined in the standard namespace. This function must always + * return the complete namespace and identifier of this function. + * + * @return the function's identifier + */ + public URI getIdentifier(); + + /** + * Provides the type of AttributeValue that this function + * returns from evaluate in a successful evaluation. + * + * @return the type returned by this function + */ + public URI getReturnType(); + + /** + * Tells whether this function will return a bag of values or just a + * single value. + * + * @return true if evaluation will return a bag, false otherwise + */ + public boolean returnsBag(); + + /** + * Checks that the given inputs are of the right types, in the right + * order, and are the right number for this function to evaluate. If + * the function cannot accept the inputs for evaluation, an + * IllegalArgumentException is thrown. + * + * @param inputs a List of Evaluatables, with + * the first argument being a Function if + * this is a higher-order function + * + * @throws IllegalArgumentException if the inputs do match what the + * function accepts for evaluation + */ + public void checkInputs(List inputs) throws IllegalArgumentException; + + /** + * Checks that the given inputs are of the right types, in the right + * order, and are the right number for this function to evaluate. If + * the function cannot accept the inputs for evaluation, an + * IllegalArgumentException is thrown. + * + * @param inputs a List of Evaluatables, with + * the first argument being a Function if + * this is a higher-order function + * + * @throws IllegalArgumentException if the inputs do match what the + * function accepts for evaluation + */ + public void checkInputs(List inputs, RuntimeInfo src) throws IllegalArgumentException; + + /** + * Checks that the given inputs are of the right types, in the right + * order, and are the right number for this function to evaluate. If + * the function cannot accept the inputs for evaluation, an + * IllegalArgumentException is thrown. Unlike the other + * checkInput method in this interface, this assumes that + * the parameters will never provide bags of values. This is useful if + * you're considering a target function which has a designator or + * selector in its input list, but which passes the values from the + * derived bags one at a time to the function, so the function doesn't + * have to deal with the bags that the selector or designator + * generates. + * + * @param inputs a List of Evaluatables, with + * the first argument being a Function if + * this is a higher-order function + * + * @throws IllegalArgumentException if the inputs do match what the + * function accepts for evaluation + */ + public void checkInputsNoBag(List inputs) throws IllegalArgumentException; + + + public void checkInputsNoBag(List inputs, RuntimeInfo src) throws IllegalArgumentException; +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FunctionBase.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FunctionBase.java new file mode 100644 index 0000000..3afecfb --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FunctionBase.java @@ -0,0 +1,763 @@ + +/* + * @(#)FunctionBase.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.cond; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.Indenter; + +import com.sun.xacml.attr.AttributeValue; + +import com.sun.xacml.ctx.Status; +import com.sun.xacml.debug.RuntimeInfo; + +import java.net.URI; +import java.net.URISyntaxException; + +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Stack; + +import org.apache.log4j.Logger; + + + +/** + * An abstract utility superclass for functions. Supplies several useful + * methods, making it easier to implement a Function. You can + * extend this class or implement Function directly, depending + * on your needs. + * + * @since 1.0 + * @author Steve Hanna + * @author Seth Proctor + */ +public abstract class FunctionBase implements Function +{ + + /** + * The standard namespace where all XACML 1.0 spec-defined functions live + */ + public static final String FUNCTION_NS = + "urn:oasis:names:tc:xacml:1.0:function:"; + + /** + * The standard namespace where all XACML 2.0 spec-defined functions live + */ + public static final String FUNCTION_NS_2 = + "urn:oasis:names:tc:xacml:2.0:function:"; + + // A List used by makeProcessingError() to save some steps. + private static List processingErrList = null; + + // the name of this function + private String functionName; + + // the id used by this function + private int functionId; + + // the return type of this function, and whether it's a bag + private String returnType; + private boolean returnsBag; + + // flag that tells us which of the two constructors was used + private boolean singleType; + + // parameter data if we're only using a single type + private String paramType; + private boolean paramIsBag; + private int numParams; + private int minParams; + + // paramater data if we're using different types + private List paramTypes; + private List paramsAreBags; + + private Logger logger = Logger.getLogger(FunctionBase.class); + + //private RuntimeInfo src; + private Stack src; + + /** + * Constructor that sets up the function as having some number of + * parameters all of the same given type. If numParams is + * -1, then the length is variable + * + * @param functionName the name of this function as used by the factory + * and any XACML policies + * @param functionId an optional identifier that can be used by your + * code for convenience + * @param paramType the type of all parameters to this function, as used + * by the factory and any XACML documents + * @param paramIsBag whether or not every parameter is actually a bag + * of values + * @param numParams the number of parameters required by this function, + * or -1 if any number are allowed + * @param returnType the type returned by this function, as used by + * the factory and any XACML documents + * @param returnsBag whether or not this function returns a bag of values + */ + public FunctionBase(String functionName, int functionId, String paramType, + boolean paramIsBag, int numParams, + String returnType, boolean returnsBag) { + this(functionName, functionId, returnType, returnsBag); + + this.singleType = true; + + this.paramType = paramType; + this.paramIsBag = paramIsBag; + this.numParams = numParams; + this.minParams = 0; + } + + /** + * Constructor that sets up the function as having some number of + * parameters all of the same given type. If numParams is + * -1, then the length is variable, and then minParams may + * be used to specify a minimum number of parameters. If + * numParams is not -1, then minParams is + * ignored. + * + * @param functionName the name of this function as used by the factory + * and any XACML policies + * @param functionId an optional identifier that can be used by your + * code for convenience + * @param paramType the type of all parameters to this function, as used + * by the factory and any XACML documents + * @param paramIsBag whether or not every parameter is actually a bag + * of values + * @param numParams the number of parameters required by this function, + * or -1 if any number are allowed + * @param minParams the minimum number of parameters required if + * numParams is -1 + * @param returnType the type returned by this function, as used by + * the factory and any XACML documents + * @param returnsBag whether or not this function returns a bag of values + */ + public FunctionBase(String functionName, int functionId, String paramType, + boolean paramIsBag, int numParams, int minParams, + String returnType, boolean returnsBag) { + this(functionName, functionId, returnType, returnsBag); + + this.singleType = true; + + this.paramType = paramType; + this.paramIsBag = paramIsBag; + this.numParams = numParams; + this.minParams = minParams; + } + + + /** + * Constructor that sets up the function as having different types for + * each given parameter. + * + * @param functionName the name of this function as used by the factory + * and any XACML policies + * @param functionId an optional identifier that can be used by your + * code for convenience + * @param paramTypes the type of each parameter, in order, required by + * this function, as used by the factory and any XACML + * documents + * @param paramIsBag whether or not each parameter is actually a bag + * of values + * @param returnType the type returned by this function, as used by + * the factory and any XACML documents + * @param returnsBag whether or not this function returns a bag of values + */ + public FunctionBase(String functionName, int functionId, + String [] paramTypes, boolean [] paramIsBag, + String returnType, boolean returnsBag) { + this(functionName, functionId, returnType, returnsBag); + + this.singleType = false; + + this.paramTypes = Arrays.asList(paramTypes); + this.paramsAreBags = new ArrayList(); + for (int i=0; i < paramIsBag.length; i++) { + this.paramsAreBags.add(Boolean.valueOf(paramIsBag[i])); + } + } + + /** + * Constructor that sets up some basic values for functions that will + * take care of parameter checking on their own. If you use this + * constructor for your function class, then you must override the + * two check methods to make sure that parameters are correct. + * + * @param functionName the name of this function as used by the factory + * and any XACML policies + * @param functionId an optional identifier that can be used by your + * code for convenience + * @param returnType the type returned by this function, as used by + * the factory and any XACML documents + * @param returnsBag whether or not this function returns a bag of values + */ + public FunctionBase(String functionName, int functionId, + String returnType, boolean returnsBag) { + this.functionName = functionName; + this.functionId = functionId; + this.returnType = returnType; + this.returnsBag = returnsBag; + } + + /** + * Returns the full identifier of this function, as known by the factories. + * + * @return the function's identifier + * + * @throws IllegalArgumentException if the identifier isn't a valid URI + */ + public URI getIdentifier() { + // this is to get around the exception handling problems, but may + // change if this code changes to include exceptions from the + // constructors + try { + return new URI(this.functionName); + } catch (URISyntaxException use) { + throw new IllegalArgumentException("invalid URI: " + this.functionName); + } + } + + /** + * Returns the name of the function to be handled by this particular + * object. + * + * @return the function name + */ + public String getFunctionName() { + return this.functionName; + } + + /** + * Returns the Identifier of the function to be handled by this + * particular object. + * + * @return the function Id + */ + public int getFunctionId() { + return this.functionId; + } + + /** + * Returns the same value as getReturnType. This is here + * to support the Expression interface. + * + * @return the return type + */ + public URI getType() { + return getReturnType(); + } + + /** + * Get the attribute type returned by this function. + * + * @return a URI indicating the attribute type + * returned by this function + */ + public URI getReturnType() { + try { + return new URI(this.returnType); + } catch (Exception e) { + return null; + } + } + + /** + * @return A Boolean determining + * wether the parameter(s) is bag(s) or not. Null if this is + * not a single type function. + */ + + public boolean getParamIsBag() { + return this.paramIsBag; + } + + /** + * Returns true if this function returns a bag of values. + * + * @return true if the function returns a bag, false otherwise + */ + public boolean returnsBag() { + return this.returnsBag; + } + + /** + * Returns the return type for this particular object. + * + * @return the return type + */ + public String getReturnTypeAsString() { + return this.returnType; + } + + /** + * Create an EvaluationResult that indicates a + * processing error with the specified message. This method + * may be useful to subclasses. + * + * @param message a description of the error + * (null if none) + * @return the desired EvaluationResult + */ + protected static EvaluationResult makeProcessingError(String message) { + // Build up the processing error Status. + if (processingErrList == null) { + String [] errStrings = { Status.STATUS_PROCESSING_ERROR }; + processingErrList = Arrays.asList(errStrings); + } + Status errStatus = new Status(processingErrList, message); + EvaluationResult processingError = new EvaluationResult(errStatus); + + return processingError; + } + + /** + * Evaluates each of the parameters, in order, filling in the argument + * array with the resulting values. If any error occurs, this method + * returns the error, otherwise null is returned, signalling that + * evaluation was successful for all inputs, and the resulting argument + * list can be used. + * + * @param params a List of Evaluatable + * objects representing the parameters to evaluate + * @param context the representation of the request + * @param args an array as long as the params List that + * will, on return, contain the AttributeValues + * generated from evaluating all parameters + * + * @return null if no errors were encountered, otherwise + * an EvaluationResult representing the error + */ + protected EvaluationResult evalArgs(List params, EvaluationCtx context, + AttributeValue [] args) { + Iterator it = params.iterator(); + int index = 0; + + while (it.hasNext()) { + // get and evaluate the next parameter + Evaluatable eval = (Evaluatable)(it.next()); + EvaluationResult result = eval.evaluate(context); + + // If there was an error, pass it back... + if (result.indeterminate()) { + return result; + } + // ...otherwise save it and keep going + args[index++] = result.getAttributeValue(); + } + + // if no error occurred then we got here, so we return no errors + return null; + } + + /** + * Default handling of input checking. This does some simple checking + * based on the type of constructor used. If you need anything more + * complex, or if you used the simple constructor, then you must + * override this method. + * + * @param inputs a List> of Evaluatables + * + * @throws IllegalArgumentException if the inputs won't work + */ + public void checkInputs(List inputs) throws IllegalArgumentException { + checkInputs(inputs, null); + } + + /** + * Default handling of input checking. This does some simple checking + * based on the type of constructor used. If you need anything more + * complex, or if you used the simple constructor, then you must + * override this method. + * + * @param inputs a List> of Evaluatables + * @param src provides information about the source of the checked function, + * e.g., providing information in with file and which line number the error is located + * + * @throws IllegalArgumentException if the inputs won't work + */ + public void checkInputs(List inputs, RuntimeInfo src) throws IllegalArgumentException { + // first off, see what kind of function we are + if (this.singleType) { + // first, check the length of the inputs, if appropriate + if (this.numParams != -1) { + if (inputs.size() != this.numParams) { + throw new IllegalArgumentException("wrong number of args" + + " to " + this.functionName + + (src != null ? src.getLocationMsgForError() : "")); + } + } else { + if (inputs.size() < this.minParams) { + throw new IllegalArgumentException("not enough args" + + " to " + this.functionName + + (src != null ? src.getLocationMsgForError() : "")); + } + } + + + // now, make sure everything is of the same, correct type + Iterator it = inputs.iterator(); + while (it.hasNext()) { + Evaluatable eval = (Evaluatable)(it.next()); + + if ( ! eval.getType().toString().equals(this.paramType)) { + throw new IllegalArgumentException("illegal parameter for function " + + this.getFunctionName() + ": expected " + this.paramType + + ", but got " + eval.getType() + + (src != null ? src.getLocationMsgForError() : "")); + } + + if ( eval.returnsBag() != this.paramIsBag) { + if ( this.paramIsBag ) { + throw new IllegalArgumentException("illegal parameter for function " + + this.getFunctionName() + ": required a bag, but got none" + + (src != null ? src.getLocationMsgForError() : "")); + } else { + throw new IllegalArgumentException("illegal parameter for function " + + this.getFunctionName() + ": no bag supported, but got one" + + (src != null ? src.getLocationMsgForError() : "")); + } + } + } + } else { + // first, check the length of the inputs + if (this.paramTypes.size() != inputs.size()) { + throw new IllegalArgumentException("wrong number of args" + + " to " + this.functionName + + (src != null ? src.getLocationMsgForError() : "")); + } + + // now, make sure everything is of the same, correct type + Iterator it = inputs.iterator(); + int i = 0; + while (it.hasNext()) { + Evaluatable eval = (Evaluatable)(it.next()); + + if ( ! eval.getType().toString().equals(this.paramTypes.get(i))) { + throw new IllegalArgumentException("illegal parameter (" + i + + ") for function" + this.getFunctionName() + ": expected " + + this.paramTypes.get(i) + ", but received " + + eval.getType().toString() + + (src != null ? src.getLocationMsgForError() : "")); + } + + if ( eval.returnsBag() != ((Boolean)this.paramsAreBags.get(i)).booleanValue() ) { + if ( eval.returnsBag() ) { + throw new IllegalArgumentException("illegal parameter for function " + + this.getFunctionName() + ": no bag supported, but got one" + + (src != null ? src.getLocationMsgForError() : "")); + } else { + throw new IllegalArgumentException("illegal parameter for function " + + this.getFunctionName() + ": required a bag, but got none" + + (src != null ? src.getLocationMsgForError() : "")); + } + } + + + +// if ((! eval.getType().toString().equals( +// this.paramTypes.get(i))) +// || (eval.returnsBag() +// != ((Boolean)this.paramsAreBags +// .get(i)) +// .booleanValue())) { +// throw new IllegalArgumentException("illegal parameter"); +// } + i++; + } + } + } + + /** + * Default handling of input checking. This does some simple checking + * based on the type of constructor used. If you need anything more + * complex, or if you used the simple constructor, then you must + * override this method. + * + * @param inputs a List> of Evaluatables + * + * @throws IllegalArgumentException if the inputs won't work + */ + public void checkInputsNoBag(List inputs) throws IllegalArgumentException { + checkInputsNoBag(inputs, null); + } + + /** + * Default handling of input checking. This does some simple checking + * based on the type of constructor used. If you need anything more + * complex, or if you used the simple constructor, then you must + * override this method. + * + * @param inputs a List> of Evaluatables + * @param src provides information about the source of the checked function, + * e.g., providing information in with file and which line number the error is located + * + * @throws IllegalArgumentException if the inputs won't work + */ + public void checkInputsNoBag(List inputs, RuntimeInfo src) throws IllegalArgumentException { + // first off, see what kind of function we are + if (this.singleType) { + // first check to see if we need bags + if (this.paramIsBag) { + throw new IllegalArgumentException(this.functionName + "needs" + + "bags on input" + + (src != null ? src.getLocationMsgForError() : "")); + } + + // now check on the length + if (this.numParams != -1) { + if (inputs.size() != this.numParams) { + throw new IllegalArgumentException("wrong number of args" + + " to " + this.functionName + + (src != null ? src.getLocationMsgForError() : "")); + } + } else { + if (inputs.size() < this.minParams) { + throw new IllegalArgumentException("not enough args" + + " to " + this.functionName + + (src != null ? src.getLocationMsgForError() : "")); + } + } + + // finally check param list + Iterator it = inputs.iterator(); + while (it.hasNext()) { + Evaluatable eval = it.next(); + + if (! eval.getType().toString().equals(this.paramType)) { + throw new IllegalArgumentException("illegal parameter (" + + eval.getType().toString() + " <> " + this.paramType + ")" + + (src != null ? src.getLocationMsgForError() : "")); + } + } + } else { + // first, check the length of the inputs + if (this.paramTypes.size() != inputs.size()) { + throw new IllegalArgumentException("wrong number of args" + + " to " + this.functionName + + (src != null ? src.getLocationMsgForError() : "")); + } + + // now, make sure everything is of the same, correct type + Iterator it = inputs.iterator(); + int i = 0; + while (it.hasNext()) { + Evaluatable eval = it.next(); + + if ((! eval.getType().toString().equals( + this.paramTypes.get(i))) + || ((Boolean)( + this.paramsAreBags.get(i))).booleanValue()) { + throw new IllegalArgumentException("illegal parameter" + + (src != null ? src.getLocationMsgForError() : "")); + } + i++; + } + } + } + + /** + * A utility method for the getters. + * + * @return True if the function has only one dataType of parameters. + */ + public boolean isSingleType() { + return this.singleType; + } + + /** + * @return The number of parameters for this function. + */ + public int getNumberOfParameters() { + if (this.singleType) { + return this.numParams; + } + return this.paramTypes.size(); + } + + /** + * @return The minimum number of parameters. + */ + public int getMinimumParameters() { + if (this.singleType) { + return this.minParams; + } + return this.paramTypes.size(); + } + + /** + * @return The parameter type for single parameter functions + * or null if this is not a single parameter function. + */ + public String getParamType() { + if (this.singleType) { + return this.paramType; + } + return null; + } + + /** + * @return The List of parameter types for multi parameter + * functions or null if this is a single parameter function. + */ + public List getParamTypes() { + if (this.singleType) { + return null; + } + return Collections.unmodifiableList(this.paramTypes); + } + + /** + * @return A List of Booleans determining + * wether the parameters are bags or not. Null if this is + * a single type function. + */ + public List getParamsAreBag() { + if (this.singleType) { + return null; + } + return Collections.unmodifiableList(this.paramsAreBags); + } + + /** + * Implements the IndirectLocatable interface + */ + public void setRuntimeInfo(RuntimeInfo src) { + if ( this.src == null ) { + this.src = new Stack(); + } + this.src.push(src); + //System.out.println("// set " + src.getLocationMsgRuntime() + " on stack position " + this.src.size()); + /* + + if ( this.src != null ) { + logger.warn("Overwriting SourceLocator! This indicates that " + + "serveral threads are used to query the enginge which " + + "should NOT be the case when the source locator feature " + + "is enabled (overwrite" + + ( this.src == null ? "null" : this.src.getLocationMsgForError()) + " with " + + ( src == null ? "null" : src.getLocationMsgForError())); + } + this.src = src; + + */ + } + + /** + * Implements the IndirectLocatable interface + */ + public void unsetRuntimeInfo(RuntimeInfo src) { + if ( this.src != null ) { + RuntimeInfo src_pop = this.src.pop(); + if ( src_pop != src ) { + logger.warn("Unset Source Locator Object which did not match the current " + + "element on the stack"); + this.src.removeAllElements(); + } + } + /* + + if ( src != this.src ) { + logger.warn("Unset Source Locator Object which is currently unvalid! (from " + + ( this.src == null ? "null" : this.src.getLocationMsgForError()) + " with " + + ( src == null ? "null" : src.getLocationMsgForError())); + } + this.src = null; + + */ + } + + public RuntimeInfo getRuntimeInfo() { + if ( this.src != null && this.src.size() > 0 ) { + return this.src.get(this.src.size()-1); + } else { + return null; + } + //return this.src; + } + + /** + * Encodes this FunctionBase into its XML representation and + * writes this encoding to the given OutputStream 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 FunctionBase into its XML representation and + * writes this encoding to the given OutputStream 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); + } + out.println(indenter.makeString() + ""); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FunctionFactory.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FunctionFactory.java new file mode 100644 index 0000000..3695ba0 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FunctionFactory.java @@ -0,0 +1,566 @@ + +/* + * @(#)FunctionFactory.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.cond; + +import com.sun.xacml.Constants; +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; + +import java.net.URI; + +import java.util.HashMap; +import java.util.Set; + +import org.w3c.dom.Node; + + +/** + * Factory used to create all functions. There are three kinds of factories: + * general, condition, and target. These provide functions that can be used + * anywhere, only in a condition's root and only in a target (respectively). + *

+ * Note that all functions, except for abstract functions, are singletons, so + * any instance that is added to a factory will be the same one returned + * from the create methods. This is done because most functions don't have + * state, so there is no need to have more than one, or to spend the time + * creating multiple instances that all do the same thing. + * + * @since 1.0 + * @author Marco Barreno + * @author Seth Proctor + */ +public abstract class FunctionFactory +{ + + // the proxies used to get the default factorys + private static FunctionFactoryProxy defaultFactoryProxy; + + // the map of registered factories + private static HashMap registeredFactories; + + /** + * static intialiazer that sets up the default factory proxies and + * registers the standard namespaces + */ + static { + FunctionFactoryProxy proxy = new FunctionFactoryProxy() { + public FunctionFactory getTargetFactory() { + return StandardFunctionFactory.getTargetFactory(); + } + public FunctionFactory getConditionFactory() { + return StandardFunctionFactory.getConditionFactory(); + } + public FunctionFactory getGeneralFactory() { + return StandardFunctionFactory.getGeneralFactory(); + } + }; + registeredFactories = new HashMap(); + registeredFactories.put(Constants.XACML_1_0_IDENTIFIER, proxy); + registeredFactories.put(Constants.XACML_2_0_IDENTIFIER, proxy); + registeredFactories.put(Constants.XACML_3_0_IDENTIFIER, proxy); + defaultFactoryProxy = proxy; + } + + /** + * Default constructor. Used only by subclasses. + */ + protected FunctionFactory() { + //used only by subclasses + } + + /** + * Returns the default FunctionFactory that will only provide those + * functions that are usable in Target matching. + * + * @return a FunctionFactory for target functions + */ + public static final FunctionFactory getTargetInstance() { + return defaultFactoryProxy.getTargetFactory(); + } + + /** + * Returns a factory based on the given identifier. You may register + * as many factories as you like, and then retrieve them through this + * interface, but a factory may only be registered once using a given + * identifier. By default, the standard XACML 1.0 and 2.0 identifiers + * are regsietered to provide the standard factory. + * + * @param identifier the identifier for a factory + * + * @return a FunctionFactory that supports Target functions + * + * @throws UnknownIdentifierException if the given identifier isn't + * registered + */ + public static final FunctionFactory getTargetInstance(String identifier) + throws UnknownIdentifierException + { + return getRegisteredProxy(identifier).getTargetFactory(); + } + + /** + * Returns the default FuntionFactory that will only provide those + * functions that are usable in the root of the Condition. These Functions + * are a superset of the Target functions. + * + * @return a FunctionFactory for condition functions + */ + public static final FunctionFactory getConditionInstance() { + return defaultFactoryProxy.getConditionFactory(); + } + + /** + * Returns a factory based on the given identifier. You may register + * as many factories as you like, and then retrieve them through this + * interface, but a factory may only be registered once using a given + * identifier. By default, the standard XACML 1.0 and 2.0 identifiers + * are regsietered to provide the standard factory. + * + * @param identifier the identifier for a factory + * + * @return a FunctionFactory that supports Condition functions + * + * @throws UnknownIdentifierException if the given identifier isn't + * registered + */ + public static final FunctionFactory getConditionInstance(String identifier) + throws UnknownIdentifierException + { + return getRegisteredProxy(identifier).getConditionFactory(); + } + + /** + * Returns the default FunctionFactory that provides access to all the + * functions. These Functions are a superset of the Condition functions. + * + * @return a FunctionFactory for all functions + */ + public static final FunctionFactory getGeneralInstance() { + return defaultFactoryProxy.getGeneralFactory(); + } + + /** + * Returns a factory based on the given identifier. You may register + * as many factories as you like, and then retrieve them through this + * interface, but a factory may only be registered once using a given + * identifier. By default, the standard XACML 1.0 and 2.0 identifiers + * are regsietered to provide the standard factory. + * + * @param identifier the identifier for a factory + * + * @return a FunctionFactory that supports General functions + * + * @throws UnknownIdentifierException if the given identifier isn't + * registered + */ + public static final FunctionFactory getGeneralInstance(String identifier) + throws UnknownIdentifierException + { + return getRegisteredProxy(identifier).getGeneralFactory(); + } + + /** + * Returns the default FunctionFactoryProxy that provides access to all + * the functions. + * + * @return a FunctionFactoryProxy for all functions + */ + public static final FunctionFactoryProxy getInstance() { + return defaultFactoryProxy; + } + + /** + * Returns a factory based on the given identifier. You may register + * as many factories as you like, and then retrieve them through this + * interface, but a factory may only be registered once using a given + * identifier. By default, the standard XACML 1.0 and 2.0 identifiers + * are regsietered to provide the standard factory. + * + * @param identifier the identifier for a factory + * + * @return a FunctionFactoryProxy + * + * @throws UnknownIdentifierException if the given identifier isn't + * registered + */ + public static final FunctionFactoryProxy getInstance(String identifier) + throws UnknownIdentifierException + { + return getRegisteredProxy(identifier); + } + + /** + * Private helper that resolves the proxy for the given identifier, or + * throws an exception if no proxy is registered for that identifier. + */ + private static FunctionFactoryProxy getRegisteredProxy(String identifier) + throws UnknownIdentifierException + { + FunctionFactoryProxy proxy = + (FunctionFactoryProxy)(registeredFactories.get(identifier)); + + if (proxy == null) { + throw new UnknownIdentifierException("Uknown FunctionFactory " + + "identifier: " + identifier); + } + return proxy; + } + + /** + * Sets the default factory. This does not register the factory proxy as + * an identifiable factory. + * + * @param proxy the FunctionFactoryProxy to set as the new + * default factory proxy + */ + public static final void setDefaultFactory(FunctionFactoryProxy proxy) { + defaultFactoryProxy = proxy; + } + + /** + * Registers the given factory proxy with the given identifier. If the + * identifier is already used, then this throws an exception. If the + * identifier is not already used, then it will always be bound to the + * given proxy. + * + * @param identifier the identifier for the proxy + * @param proxy the FunctionFactoryProxy to register with + * the given identifier + * + * @throws IllegalArgumentException if the identifier is already used + */ + public static final void registerFactory(String identifier, + FunctionFactoryProxy proxy) + throws IllegalArgumentException + { + synchronized (registeredFactories) { + if (registeredFactories.containsKey(identifier)) { + throw new IllegalArgumentException("Identifier is already " + + "registered as " + + "FunctionFactory: " + + identifier); + } + registeredFactories.put(identifier, proxy); + } + } + + /** + * Adds the function to the factory. Most functions have no state, so + * the singleton model used here is typically desireable. The factory will + * not enforce the requirement that a Target or Condition matching function + * must be boolean. If a function is already contained in the factory, an + * error will be thrown. + * + * @param function the Function to add to the factory + * + * @throws IllegalArgumentException if the function's identifier is already + * used + */ + public abstract void addFunction(Function function); + + + /** + * Adds the function to the factory. Most functions have no state, so + * the singleton model used here is typically desireable. The factory will + * not enforce the requirement that a Target or Condition matching function + * must be boolean. + * + * Allows to define if an already existing function should be overwritten + * or not. + * + * @param function the Function to add to the factory + * + * @throws IllegalArgumentException if the function's identifier is already + * used + */ + public abstract void addFunction(Function function, boolean overwrite); + + /** + * Adds the abstract function proxy to the factory. This is used for + * those functions which have state, or change behavior (for instance + * the standard map function, which changes its return type based on + * how it is used). + * + * @param proxy the FunctionProxy to add to the factory + * @param identity the function's identifier + * + * @throws IllegalArgumentException if the function's identifier is already + * used + */ + public abstract void addAbstractFunction(FunctionProxy proxy, + URI identity); + + /** + * Adds a target function. + * + * @deprecated As of version 1.2, replaced by + * {@link #addFunction(Function)}. + * The new factory system requires you to get a factory + * instance and then call the non-static methods on that + * factory. The static versions of these methods have been + * left in for now, but are slower and will be removed in + * a future version. + * + * @param function the function to add + * + * @throws IllegalArgumentException if the name is already in use + */ + public static void addTargetFunction(Function function) { + getTargetInstance().addFunction(function); + } + + /** + * Adds an abstract target function. + * + * @deprecated As of version 1.2, replaced by + * {@link #addAbstractFunction(FunctionProxy,URI)}. + * The new factory system requires you to get a factory + * instance and then call the non-static methods on that + * factory. The static versions of these methods have been + * left in for now, but are slower and will be removed in + * a future version. + * + * @param proxy the function proxy to add + * @param identity the name of the function + * + * @throws IllegalArgumentException if the name is already in use + */ + public static void addAbstractTargetFunction(FunctionProxy proxy, + URI identity) { + getTargetInstance().addAbstractFunction(proxy, identity); + } + + /** + * Adds a condition function. + * + * @deprecated As of version 1.2, replaced by + * {@link #addFunction(Function)}. + * The new factory system requires you to get a factory + * instance and then call the non-static methods on that + * factory. The static versions of these methods have been + * left in for now, but are slower and will be removed in + * a future version. + * + * @param function the function to add + * + * @throws IllegalArgumentException if the name is already in use + */ + public static void addConditionFunction(Function function) { + getConditionInstance().addFunction(function); + } + + /** + * Adds an abstract condition function. + * + * @deprecated As of version 1.2, replaced by + * {@link #addAbstractFunction(FunctionProxy,URI)}. + * The new factory system requires you to get a factory + * instance and then call the non-static methods on that + * factory. The static versions of these methods have been + * left in for now, but are slower and will be removed in + * a future version. + * + * @param proxy the function proxy to add + * @param identity the name of the function + * + * @throws IllegalArgumentException if the name is already in use + */ + public static void addAbstractConditionFunction(FunctionProxy proxy, + URI identity) { + getConditionInstance().addAbstractFunction(proxy, identity); + } + + /** + * Adds a general function. + * + * @deprecated As of version 1.2, replaced by + * {@link #addFunction(Function)}. + * The new factory system requires you to get a factory + * instance and then call the non-static methods on that + * factory. The static versions of these methods have been + * left in for now, but are slower and will be removed in + * a future version. + * + * @param function the function to add + * + * @throws IllegalArgumentException if the name is already in use + */ + public static void addGeneralFunction(Function function) { + getGeneralInstance().addFunction(function); + } + + /** + * Adds an abstract general function. + * + * @deprecated As of version 1.2, replaced by + * {@link #addAbstractFunction(FunctionProxy,URI)}. + * The new factory system requires you to get a factory + * instance and then call the non-static methods on that + * factory. The static versions of these methods have been + * left in for now, but are slower and will be removed in + * a future version. + * + * @param proxy the function proxy to add + * @param identity the name of the function + * + * @throws IllegalArgumentException if the name is already in use + */ + public static void addAbstractGeneralFunction(FunctionProxy proxy, + URI identity) { + getGeneralInstance().addAbstractFunction(proxy, identity); + } + + /** + * Returns the function identifiers supported by this factory. + * + * @return a Set of Strings + */ + public abstract Set getSupportedFunctions(); + + /** + * Tries to get an instance of the specified function. + * + * @param identity the name of the function + * + * @return the function that was created. + * + * @throws UnknownIdentifierException if the name isn't known + * @throws FunctionTypeException if the name is known to map to an + * abstract function, and should therefore + * be created through createAbstractFunction + */ + public abstract Function createFunction(URI identity) + throws UnknownIdentifierException, FunctionTypeException; + + /** + * Tries to get an instance of the specified function. + * + * @param identity the name of the function + * + * @return the function that was created. + * + * @throws UnknownIdentifierException if the name isn't known + * @throws FunctionTypeException if the name is known to map to an + * abstract function, and should therefore + * be created through createAbstractFunction + */ + public abstract Function createFunction(String identity) + throws UnknownIdentifierException, FunctionTypeException; + + /** + * Tries to get an instance of the specified abstract function. + * + * @param identity the name of the function + * @param root the DOM root containing info used to create the function + * + * @return the function that was created. + * + * @throws UnknownIdentifierException if the name isn't known + * @throws FunctionTypeException if the name is known to map to a + * concrete function, and should therefore + * be created through createFunction + * @throws ParsingException if the function can't be created with the + * given inputs + */ + public abstract Function createAbstractFunction(URI identity, Node root) + throws UnknownIdentifierException, ParsingException, + FunctionTypeException; + + /** + * Tries to get an instance of the specified abstract function. + * + * @param identity the name of the function + * @param root the DOM root containing info used to create the function + * @param xpathVersion the version specified in the contianing policy, or + * null if no version was specified + * + * @return the function that was created. + * + * @throws UnknownIdentifierException if the name isn't known + * @throws FunctionTypeException if the name is known to map to a + * concrete function, and should therefore + * be created through createFunction + * @throws ParsingException if the function can't be created with the + * given inputs + */ + public abstract Function createAbstractFunction(URI identity, Node root, + String xpathVersion) + throws UnknownIdentifierException, ParsingException, + FunctionTypeException; + + /** + * Tries to get an instance of the specified abstract function. + * + * @param identity the name of the function + * @param root the DOM root containing info used to create the function + * + * @return the function that was created. + * + * @throws UnknownIdentifierException if the name isn't known + * @throws FunctionTypeException if the name is known to map to a + * concrete function, and should therefore + * be created through createFunction + * @throws ParsingException if the function can't be created with the + * given inputs + */ + public abstract Function createAbstractFunction(String identity, Node root) + throws UnknownIdentifierException, ParsingException, + FunctionTypeException; + + /** + * Tries to get an instance of the specified abstract function. + * + * @param identity the name of the function + * @param root the DOM root containing info used to create the function + * @param xpathVersion the version specified in the contianing policy, or + * null if no version was specified + * + * @return the function that was created. + * + * @throws UnknownIdentifierException if the name isn't known + * @throws FunctionTypeException if the name is known to map to a + * concrete function, and should therefore + * be created through createFunction + * @throws ParsingException if the function can't be created with the + * given inputs + */ + public abstract Function createAbstractFunction(String identity, Node root, + String xpathVersion) + throws UnknownIdentifierException, ParsingException, + FunctionTypeException; + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FunctionFactoryProxy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FunctionFactoryProxy.java new file mode 100644 index 0000000..0070608 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FunctionFactoryProxy.java @@ -0,0 +1,76 @@ + +/* + * @(#)FunctionFactoryProxy.java + * + * Copyright 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.cond; + + +/** + * A simple proxy interface used to install new FunctionFactorys. + * The three kinds of factory (Target, Condition, and General) are tied + * together in this interface because implementors writing new factories + * should always implement all three types and provide them together. + * + * @since 1.2 + * @author Seth Proctor + */ +public interface FunctionFactoryProxy +{ + + /** + * Returns the Target version of an instance of the + * FunctionFactory for which this is a proxy. + * + * @return a FunctionFactory instance + */ + public FunctionFactory getTargetFactory(); + + /** + * Returns the Condition version of an instance of the + * FunctionFactory for which this is a proxy. + * + * @return a FunctionFactory instance + */ + public FunctionFactory getConditionFactory(); + + /** + * Returns the General version of an instance of the + * FunctionFactory for which this is a proxy. + * + * @return a FunctionFactory instance + */ + public FunctionFactory getGeneralFactory(); + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FunctionProxy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FunctionProxy.java new file mode 100644 index 0000000..5a5b5e3 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FunctionProxy.java @@ -0,0 +1,70 @@ + +/* + * @(#)FunctionProxy.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.cond; + +import org.w3c.dom.Node; + + +/** + * Used by abstract functions to define how new functions are created by + * the factory. Note that all functions using XPath are defined to be + * abstract functions, so they must be created using this interface. + * + * @since 1.0 + * @author Seth Proctor + */ +public interface FunctionProxy +{ + + /** + * Creates an instance of some abstract function. If the function + * being created is not using XPath, then the version parameter can be + * ignored, otherwise a value must be present and the version must + * be acceptable. + * + * @param root the DOM root of the apply statement containing the function + * @param xpathVersion the version specified in the contianing policy, or + * null if no version was specified + * + * @return the function + * + * @throws Exception if the underlying code experienced any error + */ + public Function getInstance(Node root, String xpathVersion) + throws Exception; + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FunctionTypeException.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FunctionTypeException.java new file mode 100644 index 0000000..0f79785 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/FunctionTypeException.java @@ -0,0 +1,107 @@ + +/* + * @(#)FunctionTypeException.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.cond; + + +/** + * Exception that gets thrown if one of the createFunction methods on the + * FunctionFactory was called, but the other method should have + * been called instead. + * + * @since 1.0 + * @author Seth Proctor + */ +public class FunctionTypeException extends Exception +{ + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Constructs a new FunctionTypeException with no message + * or cause. + */ + public FunctionTypeException() { + // no message or cause + } + + /** + * Constructs a new FunctionTypeException 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 (null if nonexistent + * or unknown) + */ + public FunctionTypeException(String message) { + super(message); + } + + /** + * Constructs a new FunctionTypeException 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 (null if nonexistent + * or unknown) + */ + public FunctionTypeException(Throwable cause) { + super(cause); + } + + /** + * Constructs a new FunctionTypeException 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 (null if nonexistent + * or unknown) + * @param cause the cause (null if nonexistent + * or unknown) + */ + public FunctionTypeException(String message, Throwable cause) { + super(message, cause); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/GeneralBagFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/GeneralBagFunction.java new file mode 100644 index 0000000..b5380ae --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/GeneralBagFunction.java @@ -0,0 +1,371 @@ + +/* + * @(#)GeneralBagFunction.java + * + * Copyright 2004-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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BagAttribute; +import com.sun.xacml.attr.IntegerAttribute; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +/** + * Specific BagFunction class that supports all of the + * general-purpose bag functions: type-one-and-only, type-bag-size, and + * type-bag. + * + * @since 1.2 + * @author Seth Proctor + */ +public class GeneralBagFunction extends BagFunction +{ + + // private identifiers for the supported functions + private static final int ID_BASE_ONE_AND_ONLY = 0; + private static final int ID_BASE_BAG_SIZE = 1; + private static final int ID_BASE_BAG = 2; + + // mapping of function name to its associated parameters + private static HashMap paramMap; + private static Set supportedIds; + + /** + * Static initializer that sets up the parameter info for all the + * supported functions. + */ + static { + paramMap = new HashMap(); + + for (int i = 0; i < baseTypes.length; i++) { + String baseType = baseTypes[i]; + String functionBaseName = FUNCTION_NS + simpleTypes[i]; + + paramMap.put(functionBaseName + NAME_BASE_ONE_AND_ONLY, + new BagParameters(ID_BASE_ONE_AND_ONLY, baseType, + true, 1, baseType, false)); + + paramMap.put(functionBaseName + NAME_BASE_BAG_SIZE, + new BagParameters(ID_BASE_BAG_SIZE, baseType, true, + 1, IntegerAttribute.identifier, + false)); + + paramMap.put(functionBaseName + NAME_BASE_BAG, + new BagParameters(ID_BASE_BAG, baseType, false, -1, + baseType, true)); + } + + for (int i = 0; i < baseTypes2.length; i++) { + String baseType = baseTypes2[i]; + String functionBaseName = FUNCTION_NS_2 + simpleTypes2[i]; + + paramMap.put(functionBaseName + NAME_BASE_ONE_AND_ONLY, + new BagParameters(ID_BASE_ONE_AND_ONLY, baseType, + true, 1, baseType, false)); + + paramMap.put(functionBaseName + NAME_BASE_BAG_SIZE, + new BagParameters(ID_BASE_BAG_SIZE, baseType, true, + 1, IntegerAttribute.identifier, + false)); + + paramMap.put(functionBaseName + NAME_BASE_BAG, + new BagParameters(ID_BASE_BAG, baseType, false, -1, + baseType, true)); + } + + supportedIds = Collections. + unmodifiableSet(new HashSet(paramMap.keySet())); + + paramMap.put(NAME_BASE_ONE_AND_ONLY, + new BagParameters(ID_BASE_ONE_AND_ONLY, null, true, 1, + null, false)); + paramMap.put(NAME_BASE_BAG_SIZE, + new BagParameters(ID_BASE_BAG_SIZE, null, true, 1, + IntegerAttribute.identifier, false)); + paramMap.put(NAME_BASE_BAG, + new BagParameters(ID_BASE_BAG, null, false, -1, null, + true)); + + + } + + /** + * Constructor that is used to create one of the general-purpose standard + * bag functions. The name supplied must be one of the standard XACML + * functions supported by this class, including the full namespace, + * otherwise an exception is thrown. Look in BagFunction + * for details about the supported names. + * + * @param functionName the name of the function to create + * + * @throws IllegalArgumentException if the function is unknown + */ + public GeneralBagFunction(String functionName) { + super(functionName, getId(functionName), getArgumentType(functionName), + getIsBag(functionName), getNumArgs(functionName), + getReturnType(functionName), getReturnsBag(functionName)); + } + + /** + * Constructor that is used to create instances of general-purpose bag + * functions for new (non-standard) datatypes. This is equivalent to + * using the getInstance methods in BagFunction + * and is generally only used by the run-time configuration code. + * + * @param functionName the name of the new function + * @param datatype the full identifier for the supported datatype + * @param functionType which kind of Bag function, based on the + * NAME_BASE_* fields + */ + public GeneralBagFunction(String functionName, String datatype, + String functionType) { + super(functionName, getId(functionType), datatype, + getIsBag(functionType), getNumArgs(functionType), + getCustomReturnType(functionType, datatype), + getReturnsBag(functionType)); + } + + /** + * Private helper that returns the internal identifier used for the + * given standard function. + */ + private static int getId(String functionName) { + BagParameters params = (BagParameters)(paramMap.get(functionName)); + + if (params == null) { + throw new IllegalArgumentException("unknown bag function: " + + functionName); + } + return params.id; + } + + /** + * Private helper that returns the argument type for the given standard + * function. Note that this doesn't check on the return value since the + * method always is called after getId, so we assume that the function + * is present. + */ + private static String getArgumentType(String functionName) { + return ((BagParameters)(paramMap.get(functionName))).arg; + } + + /** + * Private helper that returns if the given standard function takes + * a bag. Note that this doesn't check on the return value since the + * method always is called after getId, so we assume that the function + * is present. + */ + private static boolean getIsBag(String functionName) { + return ((BagParameters)(paramMap.get(functionName))).argIsBag; + } + + /** + * Private helper that returns the argument count for the given standard + * function. Note that this doesn't check on the return value since the + * method always is called after getId, so we assume that the function + * is present. + */ + private static int getNumArgs(String functionName) { + return ((BagParameters)(paramMap.get(functionName))).params; + } + + /** + * Private helper that returns the return type for the given standard + * function. Note that this doesn't check on the return value since the + * method always is called after getId, so we assume that the function + * is present. + */ + private static String getReturnType(String functionName) { + return ((BagParameters)(paramMap.get(functionName))).returnType; + } + + /** + * Private helper that returns if the return type is a bag for the given + * standard function. Note that this doesn't check on the return value + * since the method always is called after getId, so we assume that the + * function is present. + */ + private static boolean getReturnsBag(String functionName) { + return ((BagParameters)(paramMap.get(functionName))).returnsBag; + } + + /** + * Private helper used by the custom datatype constructor to figure out + * what the return type is. Note that this doesn't check on the return + * value since the method always is called after getId, so we assume that + * the function is present. + */ + private static String getCustomReturnType(String functionType, + String datatype) { + String ret = ((BagParameters)(paramMap.get(functionType))).returnType; + + if (ret == null) { + return datatype; + } + return ret; + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + return supportedIds; + } + + /** + * Evaluate the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + // Evaluate the arguments + AttributeValue [] argValues = new AttributeValue[inputs.size()]; + EvaluationResult result = evalArgs(inputs, context, argValues); + if (result != null) { + return result; + } + + // Now that we have real values, perform the requested operation. + AttributeValue attrResult = null; + + switch (getFunctionId()) { + + // *-one-and-only takes a single bag and returns a + // single value of baseType + case ID_BASE_ONE_AND_ONLY: { + BagAttribute bag = (BagAttribute)(argValues[0]); + + if (bag.size() != 1) { + //return new EvaluationResult(Status) + return makeProcessingError(getFunctionName() + " expects " + + "a bag that contains a single element," + + "got a bag with " + bag.size() + " elements"); + } + attrResult = (AttributeValue)(bag.iterator().next()); + break; + } + + // *-size takes a single bag and returns an integer + case ID_BASE_BAG_SIZE: { + BagAttribute bag = (BagAttribute)(argValues[0]); + + attrResult = new IntegerAttribute(bag.size()); + break; + } + + // *-bag takes any number of elements of baseType and + // returns a bag containing those elements + case ID_BASE_BAG: { + List argsList = Arrays.asList(argValues); + + attrResult = new BagAttribute(getReturnType(), argsList); + break; + } + } + + return new EvaluationResult(attrResult); + } + + /** + * Private class that is used for mapping each function to it set of + * parameters. + */ + private static class BagParameters { + /** + * + */ + public int id; + + /** + * + */ + public String arg; + + /** + * + */ + public boolean argIsBag; + + /** + * + */ + public int params; + + /** + * + */ + public String returnType; + + /** + * + */ + public boolean returnsBag; + + /** + * @param id + * @param arg + * @param argIsBag + * @param params + * @param returnType + * @param returnsBag + */ + public BagParameters(int id, String arg, boolean argIsBag, int params, + String returnType, boolean returnsBag) { + this.id = id; + this.arg = arg; + this.argIsBag = argIsBag; + this.params = params; + this.returnType = returnType; + this.returnsBag = returnsBag; + } + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/GeneralSetFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/GeneralSetFunction.java new file mode 100644 index 0000000..a4dc397 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/GeneralSetFunction.java @@ -0,0 +1,245 @@ + +/* + * @(#)GeneralSetFunction.java + * + * Copyright 2004-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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BagAttribute; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + + +/** + * Specific SetFunction class that supports all of the + * general-purpose set functions: type-intersection and type-union. + * + * @since 1.2 + * @author Seth Proctor + */ +public class GeneralSetFunction extends SetFunction +{ + + // private identifiers for the supported functions + private static final int ID_BASE_INTERSECTION = 0; + private static final int ID_BASE_UNION = 1; + + // mapping of function name to its associated id and parameter type + private static HashMap idMap; + private static HashMap typeMap; + + /** + * Static initializer that sets up the parameter info for all the + * supported functions. + */ + static { + idMap = new HashMap(); + typeMap = new HashMap(); + + idMap.put(NAME_BASE_INTERSECTION, Integer.valueOf(ID_BASE_INTERSECTION)); + idMap.put(NAME_BASE_UNION, Integer.valueOf(ID_BASE_UNION)); + + for (int i = 0; i < baseTypes.length; i++) { + String baseName = FUNCTION_NS + simpleTypes[i]; + String baseType = baseTypes[i]; + + idMap.put(baseName + NAME_BASE_INTERSECTION, + Integer.valueOf(ID_BASE_INTERSECTION)); + idMap.put(baseName + NAME_BASE_UNION, + Integer.valueOf(ID_BASE_UNION)); + + typeMap.put(baseName + NAME_BASE_INTERSECTION, baseType); + typeMap.put(baseName + NAME_BASE_UNION, baseType); + } + + for (int i = 0; i < baseTypes2.length; i++) { + String baseName = FUNCTION_NS_2 + simpleTypes2[i]; + String baseType = baseTypes2[i]; + + idMap.put(baseName + NAME_BASE_INTERSECTION, + Integer.valueOf(ID_BASE_INTERSECTION)); + idMap.put(baseName + NAME_BASE_UNION, + Integer.valueOf(ID_BASE_UNION)); + + typeMap.put(baseName + NAME_BASE_INTERSECTION, baseType); + typeMap.put(baseName + NAME_BASE_UNION, baseType); + } + } + + /** + * Constructor that is used to create one of the general-purpose standard + * set functions. The name supplied must be one of the standard XACML + * functions supported by this class, including the full namespace, + * otherwise an exception is thrown. Look in SetFunction + * for details about the supported names. + * + * @param functionName the name of the function to create + * + * @throws IllegalArgumentException if the function is unknown + */ + public GeneralSetFunction(String functionName) { + super(functionName, getId(functionName), getArgumentType(functionName), + getArgumentType(functionName), true); + } + + /** + * Constructor that is used to create instances of general-purpose set + * functions for new (non-standard) datatypes. This is equivalent to + * using the getInstance methods in SetFunction + * and is generally only used by the run-time configuration code. + * + * @param functionName the name of the new function + * @param datatype the full identifier for the supported datatype + * @param functionType which kind of Set function, based on the + * NAME_BASE_* fields + */ + public GeneralSetFunction(String functionName, String datatype, + String functionType) { + super(functionName, getId(functionType), datatype, datatype, true); + } + + /** + * Private helper that returns the internal identifier used for the + * given standard function. + */ + private static int getId(String functionName) { + Integer id = (Integer)(idMap.get(functionName)); + + if (id == null) { + throw new IllegalArgumentException("unknown set function " + + functionName); + } + return id.intValue(); + } + + /** + * Private helper that returns the argument type for the given standard + * function. Note that this doesn't check on the return value since the + * method always is called after getId, so we assume that the function + * is present. + */ + private static String getArgumentType(String functionName) { + return (String)(typeMap.get(functionName)); + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + return Collections.unmodifiableSet(idMap.keySet()); + } + + /** + * Evaluates the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + + // Evaluate the arguments + AttributeValue [] argValues = new AttributeValue[inputs.size()]; + EvaluationResult evalResult = evalArgs(inputs, context, argValues); + if (evalResult != null) { + return evalResult; + } + // setup the two bags we'll be using + BagAttribute [] bags = new BagAttribute[2]; + bags[0] = (BagAttribute)(argValues[0]); + bags[1] = (BagAttribute)(argValues[1]); + + AttributeValue result = null; + Set set = new HashSet(); + + if (getFunctionId() == ID_BASE_INTERSECTION) { + // *-intersection takes two bags of the same type and returns + // a bag of that type + + // create a bag with the common elements of both inputs, removing + // all duplicate values + Iterator it = bags[0].iterator(); + + // find all the things in bags[0] that are also in bags[1] + while (it.hasNext()) { + AttributeValue value = it.next(); + if (bags[1].contains(value)) { + // sets won't allow duplicates, so this addition is ok + set.add(value); + } + } + + result = new BagAttribute(bags[0].getType(), set); + + } else if (getFunctionId() == ID_BASE_UNION) { + // *-union takes two bags of the same type and returns a bag of + // that type + + // create a bag with all the elements from both inputs, removing + // all duplicate values + Iterator it0 = bags[0].iterator(); + while (it0.hasNext()) { + // first off, add all elements from the first bag...the set + // will ignore all duplicates + set.add(it0.next()); + } + + Iterator it1 = bags[1].iterator(); + while (it1.hasNext()) { + // now add all the elements from the second bag...again, all + // duplicates will be ignored by the set + set.add(it1.next()); + } + + result = new BagAttribute(bags[0].getType(), set); + } + + return new EvaluationResult(result); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/HigherOrderFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/HigherOrderFunction.java new file mode 100644 index 0000000..f1bf69e --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/HigherOrderFunction.java @@ -0,0 +1,715 @@ + +/* + * @(#)HigherOrderFunction.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.cond; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.Indenter; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BagAttribute; +import com.sun.xacml.attr.BooleanAttribute; +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.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.apache.log4j.Logger; + + +/** + * Represents all of the higher order bag functions, except map, which has + * its own class due to the issues with its return type. Unlike the other + * functions that are designed to work over any types (the type-* functions) + * these functions don't use specific names to describe what type they + * operate over, so you don't need to install new instances for any new + * datatypes you define. + * + * @since 1.0 + * @author Seth Proctor + */ +public class HigherOrderFunction implements Function +{ + + /** + * Standard identifier for the any-of function. + */ + public static final String NAME_ANY_OF = + FunctionBase.FUNCTION_NS + "any-of"; + + /** + * Standard identifier for the all-of function. + */ + public static final String NAME_ALL_OF = + FunctionBase.FUNCTION_NS + "all-of"; + + /** + * Standard identifier for the any-of-any function. + */ + public static final String NAME_ANY_OF_ANY = + FunctionBase.FUNCTION_NS + "any-of-any"; + + /** + * Standard identifier for the all-of-any function. + */ + public static final String NAME_ALL_OF_ANY = + FunctionBase.FUNCTION_NS + "all-of-any"; + + /** + * Standard identifier for the any-of-all function. + */ + public static final String NAME_ANY_OF_ALL = + FunctionBase.FUNCTION_NS + "any-of-all"; + + /** + * Standard identifier for the all-of-all function. + */ + public static final String NAME_ALL_OF_ALL = + FunctionBase.FUNCTION_NS + "all-of-all"; + + // internal identifiers for each of the supported functions + private static final int ID_ANY_OF = 0; + private static final int ID_ALL_OF = 1; + private static final int ID_ANY_OF_ANY = 2; + private static final int ID_ALL_OF_ANY = 3; + private static final int ID_ANY_OF_ALL = 4; + private static final int ID_ALL_OF_ALL = 5; + + // internal mapping of names to ids + private static HashMap idMap; + + // the internal identifier for each function + private int functionId; + + // the real identifier for each function + private URI identifier; + + // should the second argument (the first arg passed to the sub-function) + // be a bag + private boolean secondIsBag; + + // the stuff used to make sure that we have a valid return type or a + // known error, just like in the attribute classes + private static URI returnTypeURI; + private static RuntimeException earlyException; + + private static Logger logger = Logger.getLogger(HigherOrderFunction.class); + + private RuntimeInfo src; + + // try to create the return type URI, and also setup the id map + static { + try { + returnTypeURI = URI.create(BooleanAttribute.identifier); + } catch (IllegalArgumentException e) { + earlyException = e; + } + + idMap = new HashMap(); + + idMap.put(NAME_ANY_OF, Integer.valueOf(ID_ANY_OF)); + idMap.put(NAME_ALL_OF, Integer.valueOf(ID_ALL_OF)); + idMap.put(NAME_ANY_OF_ANY, Integer.valueOf(ID_ANY_OF_ANY)); + idMap.put(NAME_ALL_OF_ANY, Integer.valueOf(ID_ALL_OF_ANY)); + idMap.put(NAME_ANY_OF_ALL, Integer.valueOf(ID_ANY_OF_ALL)); + idMap.put(NAME_ALL_OF_ALL, Integer.valueOf(ID_ALL_OF_ALL)); + } + + /** + * Creates a new instance of the given function. + * + * @param functionName the function to create + * + * @throws IllegalArgumentException if the function is unknown + */ + public HigherOrderFunction(String functionName) { + // try to get the function's identifier + Integer i = (Integer)(idMap.get(functionName)); + if (i == null) { + throw new IllegalArgumentException("unknown function: " + + functionName); + } + this.functionId = i.intValue(); + + // setup the URI form of this function's idenitity + try { + this.identifier = new URI(functionName); + } catch (URISyntaxException use) { + throw new IllegalArgumentException("invalid URI"); + } + + // see if the second arg is a bag + if ((this.functionId != ID_ANY_OF) && (this.functionId != ID_ALL_OF)) { + this.secondIsBag = true; + } + else { + this.secondIsBag = false; + } + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + return Collections.unmodifiableSet(idMap.keySet()); + } + + /** + * Returns the full identifier of this function, as known by the factories. + * + * @return the function's identifier + */ + public URI getIdentifier() { + return this.identifier; + } + + /** + * Returns the same value as getReturnType. This is here + * to support the Expression interface. + * + * @return the return type + */ + public URI getType() { + return getReturnType(); + } + + /** + * Returns the type of attribute value that will be returned by + * this function. + * + * @return the return type + */ + public URI getReturnType() { + if (earlyException != null) { + throw earlyException; + } + + return returnTypeURI; + } + + /** + * Returns whether or not this function will actually return a bag + * of values. + * + * @return true if the function returns a bag of values, otherwise false + */ + public boolean returnsBag() { + return false; + } + + /** + * Evaluates the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + + Iterator iterator = inputs.iterator(); + + // get the first arg, which is the function + Expression xpr = iterator.next(); + Function function = null; + + if (xpr instanceof Function) { + function = (Function)xpr; + } else { + function = (Function)(((VariableReference)xpr). + getReferencedDefinition().getExpression()); + } + + + // get the two inputs, and if anything is INDETERMINATE, then we + // stop right away + AttributeValue [] args = new AttributeValue[2]; + + Evaluatable eval = (Evaluatable)(iterator.next()); + EvaluationResult result = eval.evaluate(context); + if (result.indeterminate()) { + return result; + } + args[0] = (result.getAttributeValue()); + + eval = (Evaluatable)(iterator.next()); + result = eval.evaluate(context); + if (result.indeterminate()) { + return result; + } + args[1] = (result.getAttributeValue()); + + // now we're ready to do the evaluation + result = null; + + switch(this.functionId) { + + case ID_ANY_OF: { + + // param: boolean-function, single value, bag of same type + // return: boolean + // using the function, iterate through the bag, and if one + // of the bag elements matches the single value, return + // true, otherwise return false + + result = any(args[0], (BagAttribute)(args[1]), function, context, + false); + break; + } + + case ID_ALL_OF: { + + // param: boolean-function, single value, bag of same type + // return: boolean + // using the function, iterate through the bag, and if all + // of the bag elements match the single value, return + // true, otherwise return false + + result = all(args[0], (BagAttribute)(args[1]), function, context); + break; + } + + case ID_ANY_OF_ANY: { + + // param: boolean-function, bag, bag of same type + // return: boolean + // apply the function to every combination of a single value from + // the first bag and a single value from the second bag, and if + // any evaluation is true return true, otherwise return false + + result = new EvaluationResult(BooleanAttribute.getInstance(false)); + Iterator it = ((BagAttribute)args[0]).iterator(); + BagAttribute bag = (BagAttribute)(args[1]); + + while (it.hasNext()) { + AttributeValue value = it.next(); + result = any(value, bag, function, context, false); + + if (result.indeterminate()) { + return result; + } + + if (((BooleanAttribute)(result. + getAttributeValue())).getValue()) { + break; + } + } + break; + } + + case ID_ALL_OF_ANY: { + + // param: boolean-function, bag, bag of same type + // return: boolean + // iterate through the first bag, and if for each of those values + // one of the values in the second bag matches then return true, + // otherwise return false + + result = allOfAny((BagAttribute)(args[1]), (BagAttribute)(args[0]), + function, context); + break; + } + + case ID_ANY_OF_ALL: { + + // param: boolean-function, bag, bag of same type + // return: boolean + // iterate through the second bag, and if for each of those values + // one of the values in the first bag matches then return true, + // otherwise return false + + result = anyOfAll((BagAttribute)(args[0]), (BagAttribute)(args[1]), + function, context); + break; + } + + case ID_ALL_OF_ALL: { + + // param: boolean-function, bag, bag of same type + // return: boolean + // iterate through the first bag, and for each of those values + // if every value in the second bag matches using the given + // function, then return true, otherwise return false + + result = new EvaluationResult(BooleanAttribute.getInstance(true)); + Iterator it = ((BagAttribute)args[0]).iterator(); + BagAttribute bag = (BagAttribute)(args[1]); + + while (it.hasNext()) { + AttributeValue value = (AttributeValue)(it.next()); + result = all(value, bag, function, context); + + if (result.indeterminate()) { + return result; + } + + if (! ((BooleanAttribute)(result. + getAttributeValue())).getValue()) { + break; + } + } + break; + } + + } + + return result; + } + + /** + * Checks that the given inputs are valid for this function. + * + * @param inputs a List of Evaluatables + * + * @throws IllegalArgumentException if the inputs are invalid + */ + public void checkInputs(List inputs) throws IllegalArgumentException { + checkInputs(inputs, null); + } + + /** + * Checks that the given inputs are valid for this function. + * + * @param inputs a List of Evaluatables + * + * @throws IllegalArgumentException if the inputs are invalid + */ + public void checkInputs(List inputs, RuntimeInfo src) throws IllegalArgumentException { + Object [] list = inputs.toArray(); + + // first off, check that we got the right number of paramaters + if (list.length != 3) { + throw new IllegalArgumentException("requires three inputs" + + (src != null ? src.getLocationMsgForError() : "")); + } + // now, try to cast the first element into a function + Function function = null; + + if (list[0] instanceof Function) { + function = (Function)(list[0]); + } else if (list[0] instanceof VariableReference) { + Expression xpr = ((VariableReference)(list[0])). + getReferencedDefinition().getExpression(); + if (xpr instanceof Function) { + function = (Function)xpr; + } + } + + if (function == null) { + throw new IllegalArgumentException("first arg to higher-order " + + " function must be a function" + + (src != null ? src.getLocationMsgForError() : "")); + } + + // check that the function returns a boolean + if (! function.getReturnType().toString(). + equals(BooleanAttribute.identifier)) { + throw new IllegalArgumentException("higher-order function must " + + "use a boolean function" + + (src != null ? src.getLocationMsgForError() : "")); + } + + // get the two inputs + Evaluatable eval1 = (Evaluatable)(list[1]); + Evaluatable eval2 = (Evaluatable)(list[2]); + + // make sure the two args are of the same type + if (! eval1.getType().equals(eval2.getType())) { + throw new IllegalArgumentException("input types to the any/all " + + "functions must match" + + (src != null ? src.getLocationMsgForError() : "")); + } + + // the first arg might be a bag + if (this.secondIsBag && (! eval1.returnsBag())) { + throw new IllegalArgumentException("first arg has to be a bag" + + (src != null ? src.getLocationMsgForError() : "")); + } + + // the second arg must be a bag + if (! eval2.returnsBag()) { + throw new IllegalArgumentException("second arg has to be a bag" + + (src != null ? src.getLocationMsgForError() : "")); + } + + // finally, we need to make sure that the given type will work on + // the given function + List args = new ArrayList(); + args.add(eval1); + args.add(eval2); + function.checkInputsNoBag(args); + } + /** + * Checks that the given inputs are valid for this function if all + * inputs are considered to not be bags. This always throws an + * exception, since this function by definition must work on bags. + * + * @param inputs a List of Evaluatables + * + * @throws IllegalArgumentException always + */ + public void checkInputsNoBag(List inputs) throws IllegalArgumentException { + checkInputsNoBag(inputs, null); + } + + /** + * Checks that the given inputs are valid for this function if all + * inputs are considered to not be bags. This always throws an + * exception, since this function by definition must work on bags. + * + * @param inputs a List of Evaluatables + * + * @throws IllegalArgumentException always + */ + public void checkInputsNoBag(List inputs, RuntimeInfo src) throws IllegalArgumentException { + throw new IllegalArgumentException("higher-order functions require " + + "use of bags"); + } + + /** + * Private helper function that performs the any function, but lets you + * swap the argument order (so it can be used by any-of-all) + */ + private EvaluationResult any(AttributeValue value, BagAttribute bag, + Function function, EvaluationCtx context, + boolean argumentsAreSwapped) { + return anyAndAllHelper(value, bag, function, context, false, + argumentsAreSwapped); + } + + /** + * Private helper function that performs the all function + */ + private EvaluationResult all(AttributeValue value, BagAttribute bag, + Function function, EvaluationCtx context) { + return anyAndAllHelper(value, bag, function, context, true, false); + } + + /** + * Private helper for any & all functions + */ + private EvaluationResult anyAndAllHelper(AttributeValue value, + BagAttribute bag, + Function function, + EvaluationCtx context, + boolean allFunction, + boolean argumentsAreSwapped) { + BooleanAttribute attr = BooleanAttribute.getInstance(allFunction); + Iterator it = bag.iterator(); + + while (it.hasNext()) { + List params = new ArrayList(); + + if (argumentsAreSwapped) { + params.add((it.next())); + params.add(value); + } else { + params.add(value); + params.add((it.next())); + } + + //Do some event recoding for the function + context.newEvent(function); + + //set (context dependent) source locator for function + RuntimeInfo funcSrc = null; + if ( src != null ) { + funcSrc = src.getIndirectRuntimeInfo(function, ELEMENT_TYPE.FUNCTION); + function.setRuntimeInfo(funcSrc); + } + + EvaluationResult result = function.evaluate(params, context); + //unset source locator + if ( funcSrc != null ) { + function.unsetRuntimeInfo(funcSrc) ; + } + + //Record the result for the function + context.closeCurrentEvent(result); + + if (result.indeterminate()) { + return result; + } + + BooleanAttribute bool = + (BooleanAttribute)(result.getAttributeValue()); + if (bool.getValue() != allFunction) { + attr = bool; + break; + } + } + + return new EvaluationResult(attr); + } + + /** + * any-of-all + */ + private EvaluationResult anyOfAll(BagAttribute anyBag, BagAttribute allBag, + Function function, + EvaluationCtx context) { + return allAnyHelper(anyBag, allBag, function, context, true); + } + + /** + * all-of-any + */ + private EvaluationResult allOfAny(BagAttribute anyBag, BagAttribute allBag, + Function function, + EvaluationCtx context) { + return allAnyHelper(anyBag, allBag, function, context, false); + } + + /** + * Private helper for the all-of-any and any-of-all functions + */ + private EvaluationResult allAnyHelper(BagAttribute anyBag, + BagAttribute allBag, + Function function, + EvaluationCtx context, + boolean argumentsAreSwapped) { + Iterator it = allBag.iterator(); + + while (it.hasNext()) { + AttributeValue value = (AttributeValue)(it.next()); + EvaluationResult result = + any(value, anyBag, function, context, argumentsAreSwapped); + + if (result.indeterminate()) { + return result; + } + + if (! ((BooleanAttribute)(result. + getAttributeValue())).getValue()) { + return result; + } + } + + return new EvaluationResult(BooleanAttribute.getTrueInstance()); + } + + /** + * Encodes this HigherOrderFunction into its XML + * representation and writes this encoding to the given + * OutputStream 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 HigherOrderFunction into its XML + * representation and writes this encoding to the given + * OutputStream 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); + } + out.println(indenter.makeString() + ""); + } + + public RuntimeInfo getRuntimeInfo() { + return this.src; + } + + public void setRuntimeInfo(RuntimeInfo src) { + if ( this.src != null ) { + logger.warn("Overwriting SourceLocator! This indicates that " + + "serveral threads are used to query the enginge which " + + "should NOT be the case when the source locator feature " + + "is enabled (overwrite" + + ( this.src == null ? "null" : this.src.getLocationMsgForError()) + " with " + + ( src == null ? "null" : src.getLocationMsgForError())); + } + this.src = src; +// if (logger.isDebugEnabled() ) { +// logger.debug("Set SourceLocator for Function " + this.getIdentifier() + " (" + (src != null ? src.getLocationMsgForError() : "no src") + ")"); +// } + } + + public void unsetRuntimeInfo(RuntimeInfo src) { + if ( src != this.src ) { + logger.warn("Unset Source Locator Object which is currently unvalid! (from " + + ( this.src == null ? "null" : this.src.getLocationMsgForError()) + " with " + + ( src == null ? "null" : src.getLocationMsgForError())); + } + this.src = null; +// if (logger.isDebugEnabled() ) { +// logger.debug("Unset SourceLocator for Function " + this.getIdentifier() + " (" + (src != null ? src.getLocationMsgForError() : "no src") + ")"); +// } + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/LogicalFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/LogicalFunction.java new file mode 100644 index 0000000..dbd41ca --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/LogicalFunction.java @@ -0,0 +1,165 @@ + +/* + * @(#)LogicalFunction.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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BooleanAttribute; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + + +/** + * A class that implements the logical functions "or" and "and". + * These functions take any number of boolean arguments and evaluate + * them one at a time, starting with the first argument. As soon as + * the result of the function can be determined, evaluation stops and + * that result is returned. During this process, if any argument + * evaluates to indeterminate, an indeterminate result is returned. + * + * @since 1.0 + * @author Steve Hanna + * @author Seth Proctor + */ +public class LogicalFunction extends FunctionBase +{ + + /** + * Standard identifier for the or function. + */ + public static final String NAME_OR = FUNCTION_NS + "or"; + + /** + * Standard identifier for the and function. + */ + public static final String NAME_AND = FUNCTION_NS + "and"; + + // internal identifiers for each of the supported functions + private static final int ID_OR = 0; + private static final int ID_AND = 1; + + /** + * Creates a new LogicalFunction object. + * + * @param functionName the standard XACML name of the function to be + * handled by this object, including the full namespace + * + * @throws IllegalArgumentException if the functionName is unknown + */ + public LogicalFunction(String functionName) { + super(functionName, getId(functionName), BooleanAttribute.identifier, + false, -1, BooleanAttribute.identifier, false); + } + + /** + * Private helper that looks up the private id based on the function name. + */ + private static int getId(String functionName) { + if (functionName.equals(NAME_OR)) { + return ID_OR; + } else if (functionName.equals(NAME_AND)) { + return ID_AND; + } else { + throw new IllegalArgumentException("unknown logical function: " + + functionName); + } + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + Set set = new HashSet(); + + set.add(NAME_OR); + set.add(NAME_AND); + + return set; + } + + /** + * Evaluate the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + + // Evaluate the arguments one by one. As soon as we can + // return a result, do so. Return Indeterminate if any argument + // evaluated is indeterminate. + Iterator it = inputs.iterator(); + while (it.hasNext()) { + Evaluatable eval = (Evaluatable)(it.next()); + + // Evaluate the argument + EvaluationResult result = eval.evaluate(context); + if (result.indeterminate()) { + return result; + } + + AttributeValue value = result.getAttributeValue(); + boolean argBooleanValue = ((BooleanAttribute)value).getValue(); + + if (getFunctionId() == ID_OR) { + if (argBooleanValue) { + return EvaluationResult.getTrueInstance(); + } + } else if (getFunctionId() == ID_AND) { + if (!argBooleanValue) { + return EvaluationResult.getFalseInstance(); + } + } + } + + if (getFunctionId() == ID_OR) { + return EvaluationResult.getFalseInstance(); + } + return EvaluationResult.getTrueInstance(); + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/MapFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/MapFunction.java new file mode 100644 index 0000000..d984b9b --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/MapFunction.java @@ -0,0 +1,420 @@ + +/* + * @(#)MapFunction.java 1.4 01/30/03 + * + * 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.cond; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.Indenter; +import com.sun.xacml.ParsingException; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BagAttribute; +import com.sun.xacml.debug.RuntimeInfo; + +import java.net.URI; + +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + + +/** + * Represents the higher order bag function map. + * + * @since 1.0 + * @author Seth Proctor + */ +class MapFunction implements Function +{ + + /** + * The name of this function + */ + public static final String NAME_MAP = FunctionBase.FUNCTION_NS + "map"; + + // the return type for this instance + private URI returnType; + + // the stuff used to make sure that we have a valid identifier or a + // known error, just like in the attribute classes + private static URI identifier; + private static RuntimeException earlyException; + + private static Logger logger = Logger.getLogger(MapFunction.class); + + // try to initialize the identifier + static { + try { + identifier = URI.create(NAME_MAP); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * Creates a new instance of a MapFunction. + * + * @param returnType the type returned by this function + */ + public MapFunction(URI returnType) { + this.returnType = returnType; + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + Set set = new HashSet(); + + set.add(NAME_MAP); + + return set; + } + + /** + * Creates a new instance of the map function using the data found in + * the DOM node provided. This is called by a proxy when the factory + * is asked to create one of these functions. + * + * @param root the DOM node of the apply tag containing this function + * + * @return a MapFunction instance + * + * @throws ParsingException if the DOM data was incorrect + */ + public static MapFunction getInstance(Node root) throws ParsingException { + URI returnType = null; + // check if this really is a Function (may be an Apply element too + if (root.getNodeType() != Node.ELEMENT_NODE) { + throw new ParsingException("Can't create a Function from a " + + root.getLocalName() + " element"); + } + 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("Function")) { + + String funcName = null; + if (node.getAttributes().getNamedItem("FunctionId") != null) { + funcName = node.getAttributes().getNamedItem("FunctionId") + .getNodeValue(); + } else { + throw new ParsingException("Required xml-attribute" + + " FunctionId not found in Function element"); + } + FunctionFactory factory = FunctionFactory.getGeneralInstance(); + try { + Function function = factory.createFunction(funcName); + returnType = function.getReturnType(); + break; + } catch (FunctionTypeException fte) { + // try to get this as an abstract function + try { + Function function = factory. + createAbstractFunction(funcName, root); + returnType = function.getReturnType(); + break; + } catch (Exception e) { + // any exception here is an error + throw new ParsingException("invalid abstract map", e); + } + } catch (Exception e) { + // any exception that's not function type is an error + throw new ParsingException("couldn't parse map body", e); + } + } + } + + // see if we found the return type + if (returnType == null) { + throw new ParsingException("couldn't find the return type"); + } + + return new MapFunction(returnType); + } + + /** + * Returns the full identifier of this function, as known by the factories. + * + * @return the function's identifier + */ + public URI getIdentifier() { + // strictly speaking, this should never happen + if (earlyException != null) { + throw earlyException; + } + + return identifier; + } + + /** + * Returns the same value as getReturnType. This is here + * to support the Expression interface. + * + * @return the return type + */ + public URI getType() { + return getReturnType(); + } + + /** + * Returns the attribute type returned by this function. + * + * @return the return type + */ + public URI getReturnType() { + return this.returnType; + } + + /** + * Returns true, since the map function always returns a bag + * + * @return true + */ + public boolean returnsBag() { + return true; + } + + /** + * Evaluates the function given the input data. Map expects a + * Function followed by a BagAttribute. + * + * @param inputs the input agrument list + * @param context the representation of the request + * + * @return the result of evaluation + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + + // get the inputs, which we expect to be correct + Iterator iterator = inputs.iterator(); + Function function = null; + + Expression xpr = (Expression)(iterator.next()); + if (xpr instanceof Function) { + function = (Function)xpr; + } else { + function = (Function)(((VariableReference)xpr). + getReferencedDefinition().getExpression()); + } + + Evaluatable eval = (Evaluatable)(iterator.next()); + EvaluationResult result = eval.evaluate(context); + + // in a higher-order case, if anything is INDETERMINATE, then + // we stop right away + if (result.indeterminate()) { + return result; + } + BagAttribute bag = (BagAttribute)(result.getAttributeValue()); + + // param: function, bag + // return: bag + // for each value in the bag evaluate the given function with + // the value and put the function result in a new bag that + // is ultimately returned + + Iterator it = bag.iterator(); + List outputs = new ArrayList(); + + while (it.hasNext()) { + List params = new ArrayList(); + params.add(it.next()); + result = function.evaluate(params, context); + + if (result.indeterminate()) { + return result; + } + + outputs.add(result.getAttributeValue()); + } + + return new EvaluationResult(new BagAttribute(this.returnType, + outputs)); + } + + /** + * Checks that the input list is valid for evaluation. + * + * @param inputs a List of inputs + * + * @throws IllegalArgumentException if the inputs cannot be evaluated + */ + public void checkInputs(List inputs) throws IllegalArgumentException { + checkInputs(inputs, null); + } + + /** + * Checks that the input list is valid for evaluation. + * + * @param inputs a List of inputs + * + * @throws IllegalArgumentException if the inputs cannot be evaluated + */ + public void checkInputs(List inputs, RuntimeInfo src) throws IllegalArgumentException { + Expression [] list = inputs.toArray(new Expression[inputs.size()]); + + // check that we've got the right number of arguments + if (list.length != 2) { + throw new IllegalArgumentException("map requires two inputs" + + (src != null ? src.getLocationMsgForError() : "")); + } + + // now check that we've got the right types for map + Function function = null; + + if (list[0] instanceof Function) { + function = (Function)(list[0]); + } else if (list[0] instanceof VariableReference) { + Expression xpr = ((VariableReference)(list[0])). + getReferencedDefinition().getExpression(); + if (xpr instanceof Function) { + function = (Function)xpr; + } + } + + if (function == null) { + throw new IllegalArgumentException("first argument to map must " + + "be a Function" + (src != null ? src.getLocationMsgForError() : "")); + } + Evaluatable eval = (Evaluatable)(list[1]); + if (! eval.returnsBag()) { + throw new IllegalArgumentException("second argument to map must " + + "be a bag" + (src != null ? src.getLocationMsgForError() : "")); + } + + // finally, check that the type in the bag is right for the function + List input = new ArrayList(); + input.add( (Evaluatable) list[1]); + function.checkInputsNoBag(input); + } + + /** + * Always throws IllegalArgumentException since map needs + * to work on a bag + * + * @param inputs a List of inputs + * + * @throws IllegalArgumentException always + */ + public void checkInputsNoBag(List inputs) throws IllegalArgumentException { + checkInputsNoBag(inputs); + } + + /** + * Always throws IllegalArgumentException since map needs + * to work on a bag + * + * @param inputs a List of inputs + * + * @throws IllegalArgumentException always + */ + public void checkInputsNoBag(List inputs, RuntimeInfo src) throws IllegalArgumentException { + throw new IllegalArgumentException("map requires a bag"); + } + + /** + * Encodes this MapFunction into its XML representation and + * writes this encoding to the given OutputStream 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 MapFunction into its XML representation and + * writes this encoding to the given OutputStream 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); + } + out.println(indenter.makeString() + ""); + } + + public RuntimeInfo getRuntimeInfo() { + logger.warn("SourceLocator feature currently not supported for Map Function"); + return null; + //throw new RuntimeException(); + } + + public void setRuntimeInfo(RuntimeInfo src) { + logger.warn("SourceLocator feature currently not supported for Map Function"); + } + + public void unsetRuntimeInfo(RuntimeInfo src) { + logger.warn("SourceLocator feature currently not supported for Map Function"); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/MapFunctionProxy.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/MapFunctionProxy.java new file mode 100644 index 0000000..2d03883 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/MapFunctionProxy.java @@ -0,0 +1,63 @@ + +/* + * @(#)MapFunctionProxy.java + * + * Copyright 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.cond; + +import org.w3c.dom.Node; + + +/** + * A basic proxy class that supports map, the only standard abstract function. + * This is useful if you're configuring the PDP at runtime. + * + * @since 1.2 + * @author Seth Proctor + */ +public class MapFunctionProxy implements FunctionProxy { + + /** + * Default constructor. + */ + public MapFunctionProxy() { + //default constructor + } + + public Function getInstance(Node root, String xpathVersion) + throws Exception { + return MapFunction.getInstance(root); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/MatchFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/MatchFunction.java new file mode 100644 index 0000000..59690fb --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/MatchFunction.java @@ -0,0 +1,441 @@ + +/* + * @(#)MatchFunction.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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AnyURIAttribute; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BooleanAttribute; +import com.sun.xacml.attr.DNSNameAttribute; +import com.sun.xacml.attr.IPAddressAttribute; +import com.sun.xacml.attr.RFC822NameAttribute; +import com.sun.xacml.attr.StringAttribute; +import com.sun.xacml.attr.X500NameAttribute; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import java.util.regex.Pattern; + +import javax.security.auth.x500.X500Principal; + + +/** + * Implements the standard matching and regular expression functions. + * + * @since 1.0 + * @author Seth Proctor + * @author Yassir Elley + */ +public class MatchFunction extends FunctionBase +{ + + /** + * Standard identifier for the string-regexp-match function. + */ + public static final String NAME_REGEXP_STRING_MATCH = + FUNCTION_NS + "string-regexp-match"; + + /** + * Standard identifier for the x500Name-match function. + */ + public static final String NAME_X500NAME_MATCH = + FUNCTION_NS + "x500Name-match"; + + /** + * Standard identifier for the rfc822Name-match function. + */ + public static final String NAME_RFC822NAME_MATCH = + FUNCTION_NS + "rfc822Name-match"; + + /** + * Standard identifier for the string-regexp-match function. NOTE: this + * in the 1.0 namespace right now because of a bug in the XACML 2.0 + * specification, but this will be changed to the 2.0 namespace as soon + * as the errata is recognized. + */ + public static final String NAME_STRING_REGEXP_MATCH = + FUNCTION_NS + "string-regexp-match"; + + /** + * Standard identifier for the anyURI-regexp-match function. + */ + public static final String NAME_ANYURI_REGEXP_MATCH = + FUNCTION_NS_2 + "anyURI-regexp-match"; + + /** + * Standard identifier for the ipAddress-regexp-match function. + */ + public static final String NAME_IPADDRESS_REGEXP_MATCH = + FUNCTION_NS_2 + "ipAddress-regexp-match"; + + /** + * Standard identifier for the dnsName-regexp-match function. + */ + public static final String NAME_DNSNAME_REGEXP_MATCH = + FUNCTION_NS_2 + "dnsName-regexp-match"; + + /** + * Standard identifier for the rfc822Name-regexp-match function. + */ + public static final String NAME_RFC822NAME_REGEXP_MATCH = + FUNCTION_NS_2 + "rfc822Name-regexp-match"; + + /** + * Standard identifier for the x500Name-regexp-match function. + */ + public static final String NAME_X500NAME_REGEXP_MATCH = + FUNCTION_NS_2 + "x500Name-regexp-match"; + + // private identifiers for the supported functions + private static final int ID_REGEXP_STRING_MATCH = 0; + private static final int ID_X500NAME_MATCH = 1; + private static final int ID_RFC822NAME_MATCH = 2; + private static final int ID_STRING_REGEXP_MATCH = 3; + private static final int ID_ANYURI_REGEXP_MATCH = 4; + private static final int ID_IPADDRESS_REGEXP_MATCH = 5; + private static final int ID_DNSNAME_REGEXP_MATCH = 6; + private static final int ID_RFC822NAME_REGEXP_MATCH = 7; + private static final int ID_X500NAME_REGEXP_MATCH = 8; + + // private mappings for the input arguments + private static final String regexpParams [] = { + StringAttribute.identifier, + StringAttribute.identifier }; + private static final String x500Params [] = { + X500NameAttribute.identifier, + X500NameAttribute.identifier }; + private static final String rfc822Params [] = { + StringAttribute.identifier, + RFC822NameAttribute.identifier}; + private static final String stringRegexpParams [] = { + StringAttribute.identifier, + StringAttribute.identifier}; + private static final String anyURIRegexpParams [] = { + StringAttribute.identifier, + AnyURIAttribute.identifier}; + private static final String ipAddressRegexpParams [] = { + StringAttribute.identifier, + IPAddressAttribute.identifier}; + private static final String dnsNameRegexpParams [] = { + StringAttribute.identifier, + DNSNameAttribute.identifier}; + private static final String rfc822NameRegexpParams [] = { + StringAttribute.identifier, + RFC822NameAttribute.identifier}; + private static final String x500NameRegexpParams [] = { + StringAttribute.identifier, + X500NameAttribute.identifier}; + + // private mapping for bag input options + private static final boolean bagParams [] = { false, false }; + + /** + * Creates a new MatchFunction based on the given name. + * + * @param functionName the name of the standard match function, including + * the complete namespace + * + * @throws IllegalArgumentException if the function is unknown + */ + public MatchFunction(String functionName) { + super(functionName, getId(functionName), + getArgumentTypes(functionName), bagParams, + BooleanAttribute.identifier, false); + } + + /** + * Private helper that returns the internal identifier used for the + * given standard function. + */ + private static int getId(String functionName) { + if (functionName.equals(NAME_REGEXP_STRING_MATCH)) { + return ID_REGEXP_STRING_MATCH; + } else if (functionName.equals(NAME_X500NAME_MATCH)) { + return ID_X500NAME_MATCH; + } else if (functionName.equals(NAME_RFC822NAME_MATCH)) { + return ID_RFC822NAME_MATCH; + } else if (functionName.equals(NAME_STRING_REGEXP_MATCH)) { + return ID_STRING_REGEXP_MATCH; + } else if (functionName.equals(NAME_ANYURI_REGEXP_MATCH)) { + return ID_ANYURI_REGEXP_MATCH; + } else if (functionName.equals(NAME_IPADDRESS_REGEXP_MATCH)) { + return ID_IPADDRESS_REGEXP_MATCH; + } else if (functionName.equals(NAME_DNSNAME_REGEXP_MATCH)) { + return ID_DNSNAME_REGEXP_MATCH; + } else if (functionName.equals(NAME_RFC822NAME_REGEXP_MATCH)) { + return ID_RFC822NAME_REGEXP_MATCH; + } else if (functionName.equals(NAME_X500NAME_REGEXP_MATCH)) { + return ID_X500NAME_REGEXP_MATCH; + } + throw new IllegalArgumentException("unknown match function: " + + functionName); + } + + /** + * Private helper that returns the types used for the given standard + * function. Note that this doesn't check on the return value since the + * method always is called after getId, so we assume that the function + * is present. + */ + private static String [] getArgumentTypes(String functionName) { + if (functionName.equals(NAME_REGEXP_STRING_MATCH)) { + return regexpParams; + } else if (functionName.equals(NAME_X500NAME_MATCH)) { + return x500Params; + } else if (functionName.equals(NAME_RFC822NAME_MATCH)) { + return rfc822Params; + } else if (functionName.equals(NAME_STRING_REGEXP_MATCH)) { + return stringRegexpParams; + } else if (functionName.equals(NAME_ANYURI_REGEXP_MATCH)) { + return anyURIRegexpParams; + } else if (functionName.equals(NAME_IPADDRESS_REGEXP_MATCH)) { + return ipAddressRegexpParams; + } else if (functionName.equals(NAME_DNSNAME_REGEXP_MATCH)) { + return dnsNameRegexpParams; + } else if (functionName.equals(NAME_RFC822NAME_REGEXP_MATCH)) { + return rfc822NameRegexpParams; + } else if (functionName.equals(NAME_X500NAME_REGEXP_MATCH)) { + return x500NameRegexpParams; + } + return null; + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + Set set = new HashSet(); + + set.add(NAME_REGEXP_STRING_MATCH); + set.add(NAME_X500NAME_MATCH); + set.add(NAME_RFC822NAME_MATCH); + set.add(NAME_STRING_REGEXP_MATCH); + set.add(NAME_ANYURI_REGEXP_MATCH); + set.add(NAME_IPADDRESS_REGEXP_MATCH); + set.add(NAME_DNSNAME_REGEXP_MATCH); + set.add(NAME_RFC822NAME_REGEXP_MATCH); + set.add(NAME_X500NAME_REGEXP_MATCH); + + return set; + } + + /** + * Evaluate the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + // Evaluate the arguments + AttributeValue [] argValues = new AttributeValue[inputs.size()]; + EvaluationResult result = evalArgs(inputs, context, argValues); + + // make sure we didn't get an error in processing the args + if (result != null) { + return result; + } + // now that we're setup, we can do the matching operations + + boolean boolResult = false; + + switch (getFunctionId()) { + + case ID_REGEXP_STRING_MATCH: + case ID_STRING_REGEXP_MATCH: { + // arg0 is a regular expression; arg1 is a general string + String arg0 = ((StringAttribute)(argValues[0])).getValue(); + String arg1 = ((StringAttribute)(argValues[1])).getValue(); + + boolResult = regexpHelper(arg0, arg1); + + break; + } + + case ID_X500NAME_MATCH: { + X500Principal arg0 = + ((X500NameAttribute)(argValues[0])).getValue(); + X500Principal arg1 = + ((X500NameAttribute)(argValues[1])).getValue(); + + boolResult = arg1.getName(X500Principal.CANONICAL). + endsWith(arg0.getName(X500Principal.CANONICAL)); + + break; + } + + case ID_RFC822NAME_MATCH: { + String arg0 = ((StringAttribute)(argValues[0])).getValue(); + String arg1 = ((RFC822NameAttribute)(argValues[1])).getValue(); + + if (arg0.indexOf('@') != -1) { + // this is case #1 : a whole address + String normalized = (new RFC822NameAttribute(arg0)).getValue(); + boolResult = normalized.equals(arg1); + } else if (arg0.charAt(0) == '.') { + // this is case #3 : a sub-domain + boolResult = arg1.endsWith(arg0.toLowerCase()); + } else { + // this is case #2 : any mailbox at a specific domain + String mailDomain = arg1.substring(arg1.indexOf('@') + 1); + boolResult = arg0.toLowerCase().equals(mailDomain); + } + + break; + } + + case ID_ANYURI_REGEXP_MATCH: { + // arg0 is a regular expression; arg1 is a general string + String arg0 = ((StringAttribute)(argValues[0])).getValue(); + String arg1 = ((AnyURIAttribute)(argValues[1])).encode(); + + boolResult = regexpHelper(arg0, arg1); + + break; + } + + case ID_IPADDRESS_REGEXP_MATCH: { + // arg0 is a regular expression; arg1 is a general string + String arg0 = ((StringAttribute)(argValues[0])).getValue(); + String arg1 = ((IPAddressAttribute)(argValues[1])).encode(); + + boolResult = regexpHelper(arg0, arg1); + + break; + } + + case ID_DNSNAME_REGEXP_MATCH: { + // arg0 is a regular expression; arg1 is a general string + String arg0 = ((StringAttribute)(argValues[0])).getValue(); + String arg1 = ((DNSNameAttribute)(argValues[1])).encode(); + + boolResult = regexpHelper(arg0, arg1); + + break; + } + + case ID_RFC822NAME_REGEXP_MATCH: { + // arg0 is a regular expression; arg1 is a general string + String arg0 = ((StringAttribute)(argValues[0])).getValue(); + String arg1 = ((RFC822NameAttribute)(argValues[1])).encode(); + + boolResult = regexpHelper(arg0, arg1); + + break; + } + + case ID_X500NAME_REGEXP_MATCH: { + // arg0 is a regular expression; arg1 is a general string + String arg0 = ((StringAttribute)(argValues[0])).getValue(); + String arg1 = ((X500NameAttribute)(argValues[1])).encode(); + + boolResult = regexpHelper(arg0, arg1); + + break; + } + + } + + // Return the result as a BooleanAttribute. + return EvaluationResult.getInstance(boolResult); + } + + /** + * + */ + private boolean regexpHelper(String xpr, String str) { + // the regular expression syntax required by XACML differs + // from the syntax supported by java.util.regex.Pattern + // in several ways; the next several code blocks transform + // the XACML syntax into a semantically equivalent Pattern syntax + + StringBuffer buf = new StringBuffer(xpr); + + // in order to handle the requirement that the string is + // considered to match the pattern if any substring matches + // the pattern, we prepend ".*" and append ".*" to the reg exp, + // but only if there isn't an anchor (^ or $) in place + + if (xpr.charAt(0) != '^') { + buf = buf.insert(0, ".*"); + } + if (xpr.charAt(xpr.length() - 1) != '$') { + buf = buf.insert(buf.length(), ".*"); + } + // in order to handle Unicode blocks, we replace all + // instances of "\p{Is" with "\p{In" in the reg exp + + int idx = -1; + idx = buf.indexOf("\\p{Is", 0); + while (idx != -1){ + buf = buf.replace(idx, idx+5, "\\p{In"); + idx = buf.indexOf("\\p{Is", idx); + } + + // in order to handle Unicode blocks, we replace all instances + // of "\P{Is" with "\P{In" in the reg exp + + idx = -1; + idx = buf.indexOf("\\P{Is", 0); + while (idx != -1){ + buf = buf.replace(idx, idx+5, "\\P{In"); + idx = buf.indexOf("\\P{Is", idx); + } + + // in order to handle character class subtraction, we + // replace all instances of "-[" with "&&[^" in the reg exp + + idx = -1; + idx = buf.indexOf("-[", 0); + while (idx != -1){ + buf = buf.replace(idx, idx+2, "&&[^"); + idx = buf.indexOf("-[", idx); + } + + return Pattern.matches(buf.toString(), str); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/ModFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/ModFunction.java new file mode 100644 index 0000000..ab68282 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/ModFunction.java @@ -0,0 +1,122 @@ + +/* + * @(#)ModFunction.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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.IntegerAttribute; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +/** + * A class that implements the integer-mod function. It takes two + * integer operands and returns the remainder. If either of the + * operands is indeterminate, an indeterminate result is returned. + * + * @since 1.0 + * @author Steve Hanna + * @author Seth Proctor + */ +public class ModFunction extends FunctionBase +{ + + /** + * Standard identifier for the integer-mod function. + */ + public static final String NAME_INTEGER_MOD = FUNCTION_NS + "integer-mod"; + + /** + * Creates a new ModFunction object. + * + * @param functionName the standard XACML name of the function to be + * handled by this object, including the full namespace + * + * @throws IllegalArgumentException if the function is unknown + */ + public ModFunction(String functionName) { + super(NAME_INTEGER_MOD, 0, IntegerAttribute.identifier, false, + 2, IntegerAttribute.identifier, false); + + if (! functionName.equals(NAME_INTEGER_MOD)) { + throw new IllegalArgumentException("unknown mod function: " + + functionName); + } + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + Set set = new HashSet(); + + set.add(NAME_INTEGER_MOD); + + return set; + } + + /** + * Evaluate the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + + // Evaluate the arguments + AttributeValue [] argValues = new AttributeValue[inputs.size()]; + EvaluationResult result = evalArgs(inputs, context, argValues); + if (result != null) { + return result; + } + // Now that we have real values, perform the mod operation + long arg0 = ((IntegerAttribute) argValues[0]).getValue(); + long arg1 = ((IntegerAttribute) argValues[1]).getValue(); + + return new EvaluationResult(new IntegerAttribute(arg0 % arg1)); + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/MultiplyFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/MultiplyFunction.java new file mode 100644 index 0000000..ff1e755 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/MultiplyFunction.java @@ -0,0 +1,170 @@ + +/* + * @(#)MultiplyFunction.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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.DoubleAttribute; +import com.sun.xacml.attr.IntegerAttribute; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +/** + * A class that implements all the *-multiply functions. It takes two + * operands of the appropriate type and returns the product of the + * operands. If either of the operands is indeterminate, an indeterminate + * result is returned. + * + * @since 1.0 + * @author Steve Hanna + * @author Seth Proctor + */ +public class MultiplyFunction extends FunctionBase +{ + + /** + * Standard identifier for the integer-multiply function. + */ + public static final String NAME_INTEGER_MULTIPLY = + FUNCTION_NS + "integer-multiply"; + + /** + * Standard identifier for the double-multiply function. + */ + public static final String NAME_DOUBLE_MULTIPLY = + FUNCTION_NS + "double-multiply"; + + // inernal identifiers for each of the supported functions + private static final int ID_INTEGER_MULTIPLY = 0; + private static final int ID_DOUBLE_MULTIPLY = 1; + + /** + * Creates a new MultiplyFunction object. + * + * @param functionName the standard XACML name of the function to be + * handled by this object, including the full namespace + * + * @throws IllegalArgumentException if the function is unknown + */ + public MultiplyFunction(String functionName) { + super(functionName, getId(functionName), getArgumentType(functionName), + false, 2, getArgumentType(functionName), false); + } + + /** + * Private helper that returns the internal identifier used for the + * given standard function. + */ + private static int getId(String functionName) { + if (functionName.equals(NAME_INTEGER_MULTIPLY)) { + return ID_INTEGER_MULTIPLY; + } else if (functionName.equals(NAME_DOUBLE_MULTIPLY)) { + return ID_DOUBLE_MULTIPLY; + } else { + throw new IllegalArgumentException("unknown multiply function " + + functionName); + } + } + + /** + * Private helper that returns the type used for the given standard + * function. Note that this doesn't check on the return value since the + * method always is called after getId, so we assume that the function + * is present. + */ + private static String getArgumentType(String functionName) { + if (functionName.equals(NAME_INTEGER_MULTIPLY)) { + return IntegerAttribute.identifier; + } + return DoubleAttribute.identifier; + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + Set set = new HashSet(); + + set.add(NAME_INTEGER_MULTIPLY); + set.add(NAME_DOUBLE_MULTIPLY); + + return set; + } + + /** + * Evaluate the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + + // Evaluate the arguments + AttributeValue [] argValues = new AttributeValue[inputs.size()]; + EvaluationResult result = evalArgs(inputs, context, argValues); + if (result != null) { + return result; + } + + // Now that we have real values, perform the multiply operation + // in the manner appropriate for the type of the arguments. + if (getFunctionId() == ID_INTEGER_MULTIPLY) { + long arg0 = ((IntegerAttribute) argValues[0]).getValue(); + long arg1 = ((IntegerAttribute) argValues[1]).getValue(); + long product = arg0 * arg1; + result = new EvaluationResult(new IntegerAttribute(product)); + } else if (getFunctionId() == ID_DOUBLE_MULTIPLY) { + double arg0 = ((DoubleAttribute) argValues[0]).getValue(); + double arg1 = ((DoubleAttribute) argValues[1]).getValue(); + double product = arg0 * arg1; + result = new EvaluationResult(new DoubleAttribute(product)); + } + + return result; + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/NOfFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/NOfFunction.java new file mode 100644 index 0000000..671620c --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/NOfFunction.java @@ -0,0 +1,229 @@ + +/* + * @(#)NOfFunction.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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.BooleanAttribute; +import com.sun.xacml.attr.IntegerAttribute; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + + +/** + * A class that implements the n-of function. It requires + * at least one argument. The first argument must be an integer + * and the rest of the arguments must be booleans. If the number of + * boolean arguments that evaluate to true is at least the value of the + * first argument, the function returns true. Otherwise, it returns false + * (or indeterminate, as described in the next paragraph. + *

+ * This function evaluates the arguments one at a time, starting with + * the first one. As soon as the result of the function can be determined, + * evaluation stops and that result is returned. During this process, if + * any argument evaluates to indeterminate, an indeterminate result is + * returned. + * + * @since 1.0 + * @author Steve Hanne + * @author Seth Proctor + */ +public class NOfFunction extends FunctionBase +{ + + /** + * Standard identifier for the n-of function. + */ + public static final String NAME_N_OF = FUNCTION_NS + "n-of"; + + /** + * Creates a new NOfFunction object. + * + * @param functionName the standard XACML name of the function to be + * handled by this object, including the full namespace + * + * @throws IllegalArgumentException if the function is unknown + */ + public NOfFunction(String functionName) { + super(NAME_N_OF, 0, BooleanAttribute.identifier, false); + + if (! functionName.equals(NAME_N_OF)) { + throw new IllegalArgumentException("unknown nOf function: " + + functionName); + } + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + Set set = new HashSet(); + + set.add(NAME_N_OF); + + return set; + } + + /** + * Evaluate the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + + // Evaluate the arguments one by one. As soon as we can return + // a result, do so. Return Indeterminate if any argument + // evaluated is indeterminate. + Iterator it = inputs.iterator(); + Evaluatable eval = (Evaluatable)(it.next()); + + // Evaluate the first argument + EvaluationResult result = eval.evaluate(context); + if (result.indeterminate()) { + return result; + } + // if there were no problems, we know 'n' + long n = ((IntegerAttribute)(result.getAttributeValue())).getValue(); + + // If the number of trues needed is less than zero, report an error. + if (n < 0) { + return makeProcessingError("First argument to " + getFunctionName() + + " cannot be negative."); + } + // If the number of trues needed is zero, return true. + if (n == 0) { + return EvaluationResult.getTrueInstance(); + } + // make sure it's possible to find n true values + long remainingArgs = inputs.size() - 1; + if (n > remainingArgs) { + return makeProcessingError("not enough arguments to n-of to " + + "find " + n + " true values"); + } + // loop through the inputs, trying to find at least n trues + while (remainingArgs >= n) { + eval = (Evaluatable)(it.next()); + + // evaluate the next argument + result = eval.evaluate(context); + if (result.indeterminate()) { + return result; + } + // get the next value, and see if it's true + if (((BooleanAttribute)(result.getAttributeValue())).getValue()) { + // we're one closer to our goal...see if we met it + if (--n == 0) { + return EvaluationResult.getTrueInstance(); + } + } + + // we're still looking, but we've got one fewer arguments + remainingArgs--; + } + + // if we got here then we didn't meet our quota + return EvaluationResult.getFalseInstance(); + } + + /** + * @param inputs The inputs for this function. + * + * @throws IllegalArgumentException + * + */ + public void checkInputs(List inputs) throws IllegalArgumentException { + // check that none of the inputs is a bag + Evaluatable [] list = inputs.toArray(new Evaluatable[inputs.size()]); + for (int i = 0; i < list.length; i++) { + if ( list[i].returnsBag()) { + throw new IllegalArgumentException("n-of can't use bags"); + } + } + // if we got here then there were no bags, so ask the other check + // method to finish the checking + //List copy = new ArrayList(inputs); + + List copy = new ArrayList(inputs.size()); + for (int i = 0; i < inputs.size(); ++i ) { + copy.add( list[i]); + } + + checkInputsNoBag(copy); + } + + /**:-( + * @param inputs The inputs for this function. + * + * @throws IllegalArgumentException + * + */ + public void checkInputsNoBag(List inputs) throws IllegalArgumentException { + Object [] list = inputs.toArray(); + + // check that there is at least one arg + if (list.length == 0) { + throw new IllegalArgumentException("n-of requires an argument"); + } + // check that the first element is an Integer + Evaluatable eval = (Evaluatable)(list[0]); + if (! eval.getType().toString().equals(IntegerAttribute.identifier)) { + throw new IllegalArgumentException("first argument to n-of must" + + " be an integer"); + } + // now check that the rest of the args are booleans + for (int i = 1; i < list.length; i++) { + if (! ((Evaluatable)(list[i])).getType().toString(). + equals(BooleanAttribute.identifier)) { + throw new IllegalArgumentException("invalid parameter in n-of" + + ": expected boolean"); + } + } + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/NotFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/NotFunction.java new file mode 100644 index 0000000..d7ed6e5 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/NotFunction.java @@ -0,0 +1,121 @@ + +/* + * @(#)NotFunction.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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BooleanAttribute; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +/** + * A class that implements the not function. This function takes + * one boolean argument and returns the logical negation of that + * value. If the argument evaluates to indeterminate, an + * indeterminate result is returned. + * + * @since 1.0 + * @author Steve Hanna + * @author Seth Proctor + */ +public class NotFunction extends FunctionBase +{ + + /** + * Standard identifier for the not function. + */ + public static final String NAME_NOT = FUNCTION_NS + "not"; + + /** + * Creates a new NotFunction object. + * + * @param functionName the standard XACML name of the function to be + * handled by this object, including the full namespace + * + * @throws IllegalArgumentException if the function is unknown + */ + public NotFunction(String functionName) { + super(NAME_NOT, 0, BooleanAttribute.identifier, false, 1, + BooleanAttribute.identifier, false); + + if (! functionName.equals(NAME_NOT)) { + throw new IllegalArgumentException("unknown not function: " + + functionName); + } + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + Set set = new HashSet(); + + set.add(NAME_NOT); + + return set; + } + + /** + * Evaluate the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + + // Evaluate the arguments + AttributeValue [] argValues = new AttributeValue[inputs.size()]; + EvaluationResult result = evalArgs(inputs, context, argValues); + if (result != null) { + return result; + } + // Now that we have a real value, perform the not operation. + boolean arg = ((BooleanAttribute) argValues[0]).getValue(); + return EvaluationResult.getInstance(!arg); + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/NumericConvertFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/NumericConvertFunction.java new file mode 100644 index 0000000..e6629d0 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/NumericConvertFunction.java @@ -0,0 +1,182 @@ + +/* + * @(#)NumericConvertFunction.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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.DoubleAttribute; +import com.sun.xacml.attr.IntegerAttribute; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +/** + * A class that implements all the numeric type conversion functions + * (double-to-integer and integer-to-double). It takes one argument + * of the appropriate type, converts that argument to the other type, + * and returns the result. If the argument is indeterminate, an + * indeterminate result is returned. + * + * @since 1.0 + * @author Steve Hanna + * @author Seth Proctor + */ +public class NumericConvertFunction extends FunctionBase +{ + + /** + * Standard identifier for the double-to-integer function. + */ + public static final String NAME_DOUBLE_TO_INTEGER = + FUNCTION_NS + "double-to-integer"; + + /** + * Standard identifier for the integer-to-double function. + */ + public static final String NAME_INTEGER_TO_DOUBLE = + FUNCTION_NS + "integer-to-double"; + + // private identifiers for the supported functions + private static final int ID_DOUBLE_TO_INTEGER = 0; + private static final int ID_INTEGER_TO_DOUBLE = 1; + + /** + * Creates a new NumericConvertFunction object. + * + * @param functionName the standard XACML name of the function to be + * handled by this object, including the full namespace + * + * @throws IllegalArgumentException if the function is unknwon + */ + public NumericConvertFunction(String functionName) { + super(functionName, getId(functionName), getArgumentType(functionName), + false, 1, getReturnType(functionName), false); + } + + /** + * Private helper that returns the internal identifier used for the + * given standard function. + */ + private static int getId(String functionName) { + if (functionName.equals(NAME_DOUBLE_TO_INTEGER)) { + return ID_DOUBLE_TO_INTEGER; + } else if (functionName.equals(NAME_INTEGER_TO_DOUBLE)) { + return ID_INTEGER_TO_DOUBLE; + } else { + throw new IllegalArgumentException("unknown convert function " + + functionName); + } + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + Set set = new HashSet(); + + set.add(NAME_DOUBLE_TO_INTEGER); + set.add(NAME_INTEGER_TO_DOUBLE); + + return set; + } + + /** + * Private helper that returns the type used for the given standard + * function. Note that this doesn't check on the return value since the + * method always is called after getId, so we assume that the function + * is present. + */ + private static String getArgumentType(String functionName) { + if (functionName.equals(NAME_DOUBLE_TO_INTEGER)) { + return DoubleAttribute.identifier; + } + return IntegerAttribute.identifier; + } + + /** + * Private helper that returns the return type for the given standard + * function. Note that this doesn't check on the return value since the + * method always is called after getId, so we assume that the function + * is present. + */ + private static String getReturnType(String functionName) { + if (functionName.equals(NAME_DOUBLE_TO_INTEGER)) { + return IntegerAttribute.identifier; + } + return DoubleAttribute.identifier; + } + + /** + * Evaluate the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + + // Evaluate the arguments + AttributeValue [] argValues = new AttributeValue[inputs.size()]; + EvaluationResult result = evalArgs(inputs, context, argValues); + if (result != null) { + return result; + } + + // Now that we have real values, perform the numeric conversion + // operation in the manner appropriate for this function. + if (getFunctionId() == ID_DOUBLE_TO_INTEGER) { + double arg0 = ((DoubleAttribute) argValues[0]).getValue(); + long longValue = (long) arg0; + result = new EvaluationResult(new IntegerAttribute(longValue)); + } else if (getFunctionId() == ID_INTEGER_TO_DOUBLE) { + long arg0 = ((IntegerAttribute) argValues[0]).getValue(); + double doubleValue = arg0; + result = new EvaluationResult(new DoubleAttribute(doubleValue)); + } + + return result; + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/RoundFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/RoundFunction.java new file mode 100644 index 0000000..de46ad1 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/RoundFunction.java @@ -0,0 +1,136 @@ + +/* + * @(#)RoundFunction.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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.DoubleAttribute; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +/** + * A class that implements the round function. It takes one double + * operand, rounds that value to an integer and returns that integer. + * If the operand is indeterminate, an indeterminate result is returned. + * + * @since 1.0 + * @author Steve Hanna + * @author Seth Proctor + */ +public class RoundFunction extends FunctionBase +{ + + /** + * Standard identifier for the round function. + */ + public static final String NAME_ROUND = FUNCTION_NS + "round"; + + /** + * Creates a new RoundFunction object. + * + * @param functionName the standard XACML name of the function to be + * handled by this object, including the full namespace + * + * @throws IllegalArgumentException if the function is unknown + */ + public RoundFunction(String functionName) { + super(NAME_ROUND, 0, DoubleAttribute.identifier, false, 1, + DoubleAttribute.identifier, false); + + if (! functionName.equals(NAME_ROUND)) { + throw new IllegalArgumentException("unknown round function: " + + functionName); + } + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + Set set = new HashSet(); + + set.add(NAME_ROUND); + + return set; + } + + /** + * Evaluate the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + + // Evaluate the arguments + AttributeValue [] argValues = new AttributeValue[inputs.size()]; + EvaluationResult result = evalArgs(inputs, context, argValues); + if (result != null) { + return result; + } + // Now that we have real values, perform the round operation + double arg = ((DoubleAttribute) argValues[0]).getValue(); + double roundValue = Math.round(arg); + + // Make it round half even, not round nearest + double lower = Math.floor(arg); + double higher = lower + 1; + + //Equality test for floating point numbers that is + //resilient against errors. + if (Math.abs((arg - lower) - (higher - arg)) < .0000001 ) { + if ((lower % 2) == 0) { + roundValue = lower; + } else { + roundValue = higher; + } + } + + return new EvaluationResult(new DoubleAttribute(roundValue)); + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/SetFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/SetFunction.java new file mode 100644 index 0000000..c8be7af --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/SetFunction.java @@ -0,0 +1,291 @@ + +/* + * @(#)SetFunction.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.cond; + +import com.sun.xacml.attr.AnyURIAttribute; +import com.sun.xacml.attr.Base64BinaryAttribute; +import com.sun.xacml.attr.BooleanAttribute; +import com.sun.xacml.attr.DateAttribute; +import com.sun.xacml.attr.DateTimeAttribute; +import com.sun.xacml.attr.DayTimeDurationAttribute; +import com.sun.xacml.attr.DNSNameAttribute; +import com.sun.xacml.attr.DoubleAttribute; +import com.sun.xacml.attr.HexBinaryAttribute; +import com.sun.xacml.attr.IntegerAttribute; +import com.sun.xacml.attr.IPAddressAttribute; +import com.sun.xacml.attr.RFC822NameAttribute; +import com.sun.xacml.attr.StringAttribute; +import com.sun.xacml.attr.TimeAttribute; +import com.sun.xacml.attr.X500NameAttribute; +import com.sun.xacml.attr.YearMonthDurationAttribute; + +import java.util.HashSet; +import java.util.Set; + + +/** + * Represents all of the Set functions, though the actual implementations + * are in two sub-classes specific to the condition and general set + * functions. + * + * @since 1.0 + * @author Seth Proctor + */ +public abstract class SetFunction extends FunctionBase +{ + + /** + * Base name for the type-intersection funtions. To get the standard + * identifier for a given type, use FunctionBase.FUNCTION_NS + * + the datatype's base name (e.g., string) + + * NAME_BASE_INTERSECTION. + */ + public static final String NAME_BASE_INTERSECTION = + "-intersection"; + + /** + * Base name for the type-at-least-one-member-of funtions. To get the + * standard identifier for a given type, use + * FunctionBase.FUNCTION_NS + the datatype's base name + * (e.g., string) + + * NAME_BASE_AT_LEAST_ONE_MEMBER_OF. + */ + public static final String NAME_BASE_AT_LEAST_ONE_MEMBER_OF = + "-at-least-one-member-of"; + + /** + * Base name for the type-union funtions. To get the standard + * identifier for a given type, use FunctionBase.FUNCTION_NS + * + the datatype's base name (e.g., string) + + * NAME_BASE_UNION. + */ + public static final String NAME_BASE_UNION = + "-union"; + + /** + * Base name for the type-subset funtions. To get the standard + * identifier for a given type, use FunctionBase.FUNCTION_NS + * + the datatype's base name (e.g., string) + + * NAME_BASE_SUBSET. + */ + public static final String NAME_BASE_SUBSET = + "-subset"; + + /** + * Base name for the type-set-equals funtions. To get the standard + * identifier for a given type, use FunctionBase.FUNCTION_NS + * + the datatype's base name (e.g., string) + + * NAME_BASE_SET_EQUALS. + */ + public static final String NAME_BASE_SET_EQUALS = + "-set-equals"; + + /** + * A complete list of all the XACML datatypes supported by the Set + * functions in XACML 1.x + */ + protected final static String baseTypes [] = { + StringAttribute.identifier, + BooleanAttribute.identifier, + IntegerAttribute.identifier, + DoubleAttribute.identifier, + DateAttribute.identifier, + DateTimeAttribute.identifier, + TimeAttribute.identifier, + AnyURIAttribute.identifier, + HexBinaryAttribute.identifier, + Base64BinaryAttribute.identifier, + DayTimeDurationAttribute.identifier, + YearMonthDurationAttribute.identifier, + X500NameAttribute.identifier, + RFC822NameAttribute.identifier + }; + + /** + * A complete list of all the XACML datatypes newly supported by the Set + * functions in XACML 2.0 + */ + protected final static String baseTypes2 [] = { + IPAddressAttribute.identifier, + DNSNameAttribute.identifier + }; + + /** + * A complete list of all the XACML datatypes supported by the Set + * functions in XACML 1.x, using the "simple" form of the names (eg, + * string instead of http://www.w3.org/2001/XMLSchema#string) + */ + protected static final String simpleTypes [] = { + "string", "boolean", "integer", "double", "date", "dateTime", + "time", "anyURI", "hexBinary", "base64Binary", "dayTimeDuration", + "yearMonthDuration", "x500Name", "rfc822Name" + }; + + /** + * A complete list of all the XACML datatypes newly supported by the Set + * functions in XACML 2.0, using the "simple" form of the names (eg, + * string instead of http://www.w3.org/2001/XMLSchema#string) + */ + protected static final String simpleTypes2 [] = { + "ipAddress", "dnsName" + }; + + /** + * Creates a new instance of the intersection set function. + * This should be used to create support for any new attribute types + * and then the new SetFunction object should be added + * to the factory (all set functions for the base types are already + * installed in the factory). + * + * @param functionName the name of the function + * @param argumentType the attribute type this function will work with + * + * @return a new SetFunction for the given type + */ + public static SetFunction getIntersectionInstance(String functionName, + String argumentType) { + return new GeneralSetFunction(functionName, argumentType, + NAME_BASE_INTERSECTION); + } + + /** + * Creates a new instance of the at-least-one-member-of set function. + * This should be used to create support for any new attribute types + * and then the new SetFunction object should be added + * to the factory (all set functions for the base types are already + * installed in the factory). + * + * @param functionName the name of the function + * @param argumentType the attribute type this function will work with + * + * @return a new SetFunction for the given type + */ + public static SetFunction getAtLeastOneInstance(String functionName, + String argumentType) { + return new ConditionSetFunction(functionName, argumentType, + NAME_BASE_AT_LEAST_ONE_MEMBER_OF); + } + + /** + * Creates a new instance of the union set function. + * This should be used to create support for any new attribute types + * and then the new SetFunction object should be added + * to the factory (all set functions for the base types are already + * installed in the factory). + * + * @param functionName the name of the function + * @param argumentType the attribute type this function will work with + * + * @return a new SetFunction for the given type + */ + public static SetFunction getUnionInstance(String functionName, + String argumentType) { + return new GeneralSetFunction(functionName, argumentType, + NAME_BASE_UNION); + } + + /** + * Creates a new instance of the subset set function. + * This should be used to create support for any new attribute types + * and then the new SetFunction object should be added + * to the factory (all set functions for the base types are already + * installed in the factory). + * + * @param functionName the name of the function + * @param argumentType the attribute type this function will work with + * + * @return a new SetFunction for the given type + */ + public static SetFunction getSubsetInstance(String functionName, + String argumentType) { + return new ConditionSetFunction(functionName, argumentType, + NAME_BASE_SUBSET); + } + + /** + * Creates a new instance of the equals set function. + * This should be used to create support for any new attribute types + * and then the new SetFunction object should be added + * to the factory (all set functions for the base types are already + * installed in the factory). + * + * @param functionName the name of the function + * @param argumentType the attribute type this function will work with + * + * @return a new SetFunction for the given type + */ + public static SetFunction getSetEqualsInstance(String functionName, + String argumentType) { + return new ConditionSetFunction(functionName, argumentType, + NAME_BASE_SET_EQUALS); + } + + /** + * Protected constuctor used by the general and condition subclasses. + * If you need to create a new SetFunction instance you + * should either use one of the getInstance methods or + * construct one of the sub-classes directly. + * + * @param functionName the identitifer for the function + * @param functionId an optional, internal numeric identifier + * @param argumentType the datatype this function accepts + * @param returnType the datatype this function returns + * @param returnsBag whether this function returns bags + */ + protected SetFunction(String functionName, int functionId, + String argumentType, String returnType, + boolean returnsBag) { + super(functionName, functionId, argumentType, true, 2, returnType, + returnsBag); + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + Set set = new HashSet(); + + set.addAll(ConditionSetFunction.getSupportedIdentifiers()); + set.addAll(GeneralSetFunction.getSupportedIdentifiers()); + + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/StandardFunctionFactory.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/StandardFunctionFactory.java new file mode 100644 index 0000000..73d8327 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/StandardFunctionFactory.java @@ -0,0 +1,424 @@ + +/* + * @(#)StandardFunctionFactory.java + * + * Copyright 2004-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.cond; + +import com.sun.xacml.cond.cluster.AbsFunctionCluster; +import com.sun.xacml.cond.cluster.AddFunctionCluster; +import com.sun.xacml.cond.cluster.ComparisonFunctionCluster; +import com.sun.xacml.cond.cluster.ConditionBagFunctionCluster; +import com.sun.xacml.cond.cluster.ConditionSetFunctionCluster; +import com.sun.xacml.cond.cluster.DateMathFunctionCluster; +import com.sun.xacml.cond.cluster.DivideFunctionCluster; +import com.sun.xacml.cond.cluster.EqualFunctionCluster; +import com.sun.xacml.cond.cluster.FloorFunctionCluster; +import com.sun.xacml.cond.cluster.GeneralBagFunctionCluster; +import com.sun.xacml.cond.cluster.GeneralSetFunctionCluster; +import com.sun.xacml.cond.cluster.HigherOrderFunctionCluster; +import com.sun.xacml.cond.cluster.LogicalFunctionCluster; +import com.sun.xacml.cond.cluster.MatchFunctionCluster; +import com.sun.xacml.cond.cluster.ModFunctionCluster; +import com.sun.xacml.cond.cluster.MultiplyFunctionCluster; +import com.sun.xacml.cond.cluster.NOfFunctionCluster; +import com.sun.xacml.cond.cluster.NotFunctionCluster; +import com.sun.xacml.cond.cluster.NumericConvertFunctionCluster; +import com.sun.xacml.cond.cluster.RoundFunctionCluster; +import com.sun.xacml.cond.cluster.StringFunctionCluster; +import com.sun.xacml.cond.cluster.StringNormalizeFunctionCluster; +import com.sun.xacml.cond.cluster.SubtractFunctionCluster; + +//import foo.xacml.cond.cluster.EmergencyLevelFunctionCluster; + +import java.net.URI; + +import java.util.HashSet; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import org.apache.log4j.Logger; + + +/** + * This factory supports the standard set of functions specified in XACML + * 1.x and 2.0. It is the default factory used by the system, and imposes + * a singleton pattern insuring that there is only ever one instance of + * this class. + *

+ * Note that because this supports only the standard functions, this + * factory does not allow the addition of any other functions. If you call + * addFunction on an instance of this class, an exception + * will be thrown. If you need a standard factory that is modifiable, + * you can either create a new BaseFunctionFactory (or some + * other implementation of FunctionFactory) populated with + * the standard functions from getStandardFunctions or + * you can use getNewFactoryProxy to get a proxy containing + * a new, modifiable set of factories. + * + * @since 1.2 + * @author Seth Proctor + */ +public class StandardFunctionFactory extends BaseFunctionFactory +{ + + // the three singleton instances + private static StandardFunctionFactory targetFactory = null; + private static StandardFunctionFactory conditionFactory = null; + private static StandardFunctionFactory generalFactory = null; + + // the three function sets/maps that we use internally + private static Set targetFunctions = null; + private static Set conditionFunctions = null; + private static Set generalFunctions = null; + + private static Map targetAbstractFunctions = null; + private static Map conditionAbstractFunctions = null; + private static Map generalAbstractFunctions = null; + + // the logger we'll use for all messages + private static final Logger logger = + Logger.getLogger(StandardFunctionFactory.class.getName()); + + /** + * Creates a new StandardFunctionFactory, making sure that the default + * maps are initialized correctly. Standard factories can't be modified, + * so there is no notion of supersetting since that's only used for + * correctly propagating new functions. + */ + private StandardFunctionFactory(Set supportedFunctions, + Map supportedAbstractFunctions) { + super(supportedFunctions, supportedAbstractFunctions); + } + + /** + * Private initializer for the target functions. This is only ever + * called once. + */ + private static void initTargetFunctions() { + logger.debug("Initializing standard Target functions"); + + targetFunctions = new HashSet(); + + // add EqualFunction + targetFunctions.addAll((new EqualFunctionCluster()). + getSupportedFunctions()); + // add LogicalFunction + targetFunctions.addAll((new LogicalFunctionCluster()). + getSupportedFunctions()); + // add NOfFunction + targetFunctions.addAll((new NOfFunctionCluster()). + getSupportedFunctions()); + // add NotFunction + targetFunctions.addAll((new NotFunctionCluster()). + getSupportedFunctions()); + // add ComparisonFunction + targetFunctions.addAll((new ComparisonFunctionCluster()). + getSupportedFunctions()); + // add MatchFunction + targetFunctions.addAll((new MatchFunctionCluster()). + getSupportedFunctions()); + +// targetFunctions.addAll((new EmergencyLevelFunctionCluster()). +// getSupportedFunctions()); + + targetAbstractFunctions = new HashMap(); + } + + /** + * Private initializer for the condition functions. This is only ever + * called once. + */ + private static void initConditionFunctions() { + logger.debug("Initializing standard Condition functions"); + + if (targetFunctions == null) { + initTargetFunctions(); + } + + conditionFunctions = new HashSet(targetFunctions); + + // add condition functions from BagFunction + conditionFunctions.addAll((new ConditionBagFunctionCluster()). + getSupportedFunctions()); + // add condition functions from SetFunction + conditionFunctions.addAll((new ConditionSetFunctionCluster()). + getSupportedFunctions()); + // add condition functions from HigherOrderFunction + conditionFunctions.addAll((new HigherOrderFunctionCluster()). + getSupportedFunctions()); + + conditionAbstractFunctions = new HashMap(targetAbstractFunctions); + } + + /** + * Private initializer for the general functions. This is only ever + * called once. + */ + private static void initGeneralFunctions() { + logger.debug("Initializing standard General functions"); + + if (conditionFunctions == null) { + initConditionFunctions(); + } + + generalFunctions = new HashSet(conditionFunctions); + + // add AddFunction + generalFunctions.addAll((new AddFunctionCluster()). + getSupportedFunctions()); + // add SubtractFunction + generalFunctions.addAll((new SubtractFunctionCluster()). + getSupportedFunctions()); + // add MultiplyFunction + generalFunctions.addAll((new MultiplyFunctionCluster()). + getSupportedFunctions()); + // add DivideFunction + generalFunctions.addAll((new DivideFunctionCluster()). + getSupportedFunctions()); + // add ModFunction + generalFunctions.addAll((new ModFunctionCluster()). + getSupportedFunctions()); + // add AbsFunction + generalFunctions.addAll((new AbsFunctionCluster()). + getSupportedFunctions()); + // add RoundFunction + generalFunctions.addAll((new RoundFunctionCluster()). + getSupportedFunctions()); + // add FloorFunction + generalFunctions.addAll((new FloorFunctionCluster()). + getSupportedFunctions()); + // add DateMathFunction + generalFunctions.addAll((new DateMathFunctionCluster()). + getSupportedFunctions()); + // add general functions from BagFunction + generalFunctions.addAll((new GeneralBagFunctionCluster()). + getSupportedFunctions()); + // add NumericConvertFunction + generalFunctions.addAll((new NumericConvertFunctionCluster()). + getSupportedFunctions()); + // add StringNormalizeFunction + generalFunctions.addAll((new StringNormalizeFunctionCluster()). + getSupportedFunctions()); + // add general functions from SetFunction + generalFunctions.addAll((new GeneralSetFunctionCluster()). + getSupportedFunctions()); + // add the XACML 2.0 string functions + generalFunctions.addAll((new StringFunctionCluster()). + getSupportedFunctions()); + + + generalAbstractFunctions = new HashMap(conditionAbstractFunctions); + + // add the map function's proxy + + generalAbstractFunctions.put(URI.create(MapFunction.NAME_MAP), + new MapFunctionProxy()); + + } + + /** + * Returns a FunctionFactory that will only provide those functions that + * are usable in Target matching. This method enforces a singleton + * model, meaning that this always returns the same instance, creating + * the factory if it hasn't been requested before. This is the default + * model used by the FunctionFactory, ensuring quick + * access to this factory. + * + * @return a FunctionFactory for target functions + */ + public static synchronized StandardFunctionFactory getTargetFactory() { + if (targetFactory == null) { + if (targetFunctions == null) { + initTargetFunctions(); + } + if (targetFactory == null) { + targetFactory = + new StandardFunctionFactory(targetFunctions, + targetAbstractFunctions); + } + } + + return targetFactory; + } + + /** + * Returns a FuntionFactory that will only provide those functions that + * are usable in the root of the Condition. These Functions are a + * superset of the Target functions. This method enforces a singleton + * model, meaning that this always returns the same instance, creating + * the factory if it hasn't been requested before. This is the default + * model used by the FunctionFactory, ensuring quick + * access to this factory. + * + * @return a FunctionFactory for condition functions + */ + public static synchronized StandardFunctionFactory getConditionFactory() { + if (conditionFactory == null) { + if (conditionFunctions == null) { + initConditionFunctions(); + } + if (conditionFactory == null) { + conditionFactory = + new StandardFunctionFactory(conditionFunctions, + conditionAbstractFunctions); + } + } + + return conditionFactory; + } + + /** + * Returns a FunctionFactory that provides access to all the functions. + * These Functions are a superset of the Condition functions. This method + * enforces a singleton model, meaning that this always returns the same + * instance, creating the factory if it hasn't been requested before. + * This is the default model used by the FunctionFactory, + * ensuring quick access to this factory. + * + * @return a FunctionFactory for all functions + */ + public static StandardFunctionFactory getGeneralFactory() { + if (generalFactory == null) { + synchronized (StandardFunctionFactory.class) { + if (generalFunctions == null) { + initGeneralFunctions(); + generalFactory = + new StandardFunctionFactory(generalFunctions, + generalAbstractFunctions); + } + } + } + + return generalFactory; + } + + /** + * Returns the identifiers supported for the given version of XACML. + * Because this factory supports identifiers from all versions of theStandardFunctionFactory - Initializing standard Target functions + + * XACML specifications, this method is useful for getting a list of + * which specific identifiers are supported by a given version of XACML. + * + * @param xacmlVersion a standard XACML identifier string, as provided + * in PolicyMetaData + * + * @return a Set of identifiers + */ + public static Set getStandardFunctions(String xacmlVersion) { + // FIXME: collecting the identifiers needs to be implemented.. + throw new RuntimeException("This method isn't implemented yet."); + } + + + /** + * Returns the set of abstract functions that this standard factory + * supports as a mapping of identifier to proxy. + * + * @param xacmlVersion The XACML version number. + * + * @return a Map mapping URIs to + * FunctionProxys + */ + public static Map getStandardAbstractFunctions(String xacmlVersion) { + // FIXME: collecting the identifiers needs to be implemented.. + throw new RuntimeException("This method isn't implemented yet."); + } + + /** + * A convenience method that returns a proxy containing newly created + * instances of BaseFunctionFactorys that are correctly + * supersetted and contain the standard functions and abstract functions. + * These factories allow adding support for new functions. + * + * @return a new proxy containing new factories supporting the standard + * functions + */ + public static FunctionFactoryProxy getNewFactoryProxy() { + // first off, make sure everything's been initialized + getGeneralFactory(); + + // now create the new instances + FunctionFactory newGeneral = + new BaseFunctionFactory(generalFunctions, + generalAbstractFunctions); + + FunctionFactory newCondition = + new BaseFunctionFactory(newGeneral, conditionFunctions, + conditionAbstractFunctions); + + FunctionFactory newTarget = + new BaseFunctionFactory(newCondition, targetFunctions, + targetAbstractFunctions); + + return new BasicFunctionFactoryProxy(newTarget, newCondition, + newGeneral); + } + + /** + * Always throws an exception, since support for new functions may not be + * added to a standard factory. + * + * @param function the Function to add to the factory + * + * @throws IllegalArgumentException + * @throws UnsupportedOperationException always + */ + public void addFunction(Function function) + throws IllegalArgumentException + { + throw new UnsupportedOperationException("a standard factory cannot " + + "support new functions"); + } + + /** + * Always throws an exception, since support for new functions may not be + * added to a standard factory. + * + * @param proxy the FunctionProxy to add to the factory + * @param identity the function's identifier + * + * @throws IllegalArgumentException + * @throws UnsupportedOperationException always + */ + public void addAbstractFunction(FunctionProxy proxy, + URI identity) + throws IllegalArgumentException + { + throw new UnsupportedOperationException("a standard factory cannot " + + "support new functions"); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/StringFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/StringFunction.java new file mode 100644 index 0000000..e6cc981 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/StringFunction.java @@ -0,0 +1,123 @@ + +/* + * @(#)StringFunction.java + * + * Copyright 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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.StringAttribute; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +/** + * This class implements the string-concatenate function from XACML 2.0. + * + * @since 2.0 + * @author Seth Proctor + */ +public class StringFunction extends FunctionBase +{ + + /** + * Standard identifier for the string-concatenate function. + */ + public static final String NAME_STRING_CONCATENATE = + FUNCTION_NS_2 + "string-concatenate"; + + // private identifiers for the supported functions + private static final int ID_STRING_CONCATENATE = 0; + + /** + * Creates a new StringFunction object. + * + * @param functionName the standard XACML name of the function to be + * handled by this object, including the full namespace + * + * @throws IllegalArgumentException if the function is unknown + */ + public StringFunction(String functionName) { + super(functionName, ID_STRING_CONCATENATE, StringAttribute.identifier, + false, -1, 2, StringAttribute.identifier, false); + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + Set set = new HashSet(); + + set.add(NAME_STRING_CONCATENATE); + + return set; + } + + /** + * Evaluate the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + // Evaluate the arguments + AttributeValue [] argValues = new AttributeValue[inputs.size()]; + EvaluationResult result = evalArgs(inputs, context, argValues); + if (result != null) { + return result; + } + + if (getFunctionId() == ID_STRING_CONCATENATE) { + String str = ((StringAttribute)argValues[0]).getValue(); + for (int i = 1; i < argValues.length; i++) { + str += ((StringAttribute)(argValues[i])).getValue(); + } + result = new EvaluationResult(new StringAttribute(str)); + } + + return result; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/StringNormalizeFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/StringNormalizeFunction.java new file mode 100644 index 0000000..52631fd --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/StringNormalizeFunction.java @@ -0,0 +1,166 @@ + +/* + * @(#)StringNormalizeFunction.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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.StringAttribute; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +/** + * A class that implements all the string conversion functions + * (string-normalize-space and string-normalize-to-lower-case). + * It takes string argument, normalizes that value, and returns + * the result. If the argument is indeterminate, an indeterminate + * result is returned. + * + * @since 1.0 + * @author Steve Hanna + * @author Seth Proctor + */ +public class StringNormalizeFunction extends FunctionBase +{ + + /** + * Standard identifier for the string-normalize-space function. + */ + public static final String NAME_STRING_NORMALIZE_SPACE = + FUNCTION_NS + "string-normalize-space"; + + /** + * Standard identifier for the string-normalize-to-lower-case function. + */ + public static final String NAME_STRING_NORMALIZE_TO_LOWER_CASE = + FUNCTION_NS + "string-normalize-to-lower-case"; + + // private identifiers for the supported functions + private static final int ID_STRING_NORMALIZE_SPACE = 0; + private static final int ID_STRING_NORMALIZE_TO_LOWER_CASE = 1; + + /** + * Creates a new StringNormalizeFunction object. + * + * @param functionName the standard XACML name of the function to be + * handled by this object, including the full namespace + * + * @throws IllegalArgumentException if the function is unknown + */ + public StringNormalizeFunction(String functionName) { + super(functionName, getId(functionName), StringAttribute.identifier, + false, 1, StringAttribute.identifier, false); + } + + /** + * Private helper that returns the internal identifier used for the + * given standard function. + */ + private static int getId(String functionName) { + if (functionName.equals(NAME_STRING_NORMALIZE_SPACE)) { + return ID_STRING_NORMALIZE_SPACE; + } else if (functionName.equals(NAME_STRING_NORMALIZE_TO_LOWER_CASE)) { + return ID_STRING_NORMALIZE_TO_LOWER_CASE; + } else { + throw new IllegalArgumentException("unknown normalize function " + + functionName); + } + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + Set set = new HashSet(); + + set.add(NAME_STRING_NORMALIZE_SPACE); + set.add(NAME_STRING_NORMALIZE_TO_LOWER_CASE); + + return set; + } + + /** + * Evaluate the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + // Evaluate the arguments + AttributeValue [] argValues = new AttributeValue[inputs.size()]; + EvaluationResult result = evalArgs(inputs, context, argValues); + if (result != null) { + return result; + } + + // Now that we have real values, perform the numeric conversion + // operation in the manner appropriate for this function. + if (getFunctionId() == ID_STRING_NORMALIZE_SPACE) { + String str = ((StringAttribute) argValues[0]).getValue(); + // Trim whitespace from start and end of string + int startIndex = 0; + int endIndex = str.length() - 1; + while ((startIndex <= endIndex) && + Character.isWhitespace(str.charAt(startIndex))) { + startIndex++; + } + while ((startIndex <= endIndex) && + Character.isWhitespace(str.charAt(endIndex))) { + endIndex--; + } + String strResult = str.substring(startIndex, endIndex+1); + result = new EvaluationResult(new StringAttribute(strResult)); + } else if (getFunctionId() == ID_STRING_NORMALIZE_TO_LOWER_CASE) { + String str = ((StringAttribute) argValues[0]).getValue(); + // Convert string to lower case + String strResult = str.toLowerCase(); + result = new EvaluationResult(new StringAttribute(strResult)); + } + + return result; + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/SubtractFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/SubtractFunction.java new file mode 100644 index 0000000..9718e1a --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/SubtractFunction.java @@ -0,0 +1,170 @@ + +/* + * @(#)SubtractFunction.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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.DoubleAttribute; +import com.sun.xacml.attr.IntegerAttribute; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + + +/** + * A class that implements all the *-subtract functions. It takes two + * operands of the appropriate type and returns the difference of the + * operands. If either of the operands is indeterminate, an indeterminate + * result is returned. + * + * @since 1.0 + * @author Steve Hanna + * @author Seth Proctor + */ +public class SubtractFunction extends FunctionBase +{ + + /** + * Standard identifier for the integer-subtract function. + */ + public static final String NAME_INTEGER_SUBTRACT = + FUNCTION_NS + "integer-subtract"; + + /** + * Standard identifier for the integer-subtract function. + */ + public static final String NAME_DOUBLE_SUBTRACT = + FUNCTION_NS + "double-subtract"; + + // inernal identifiers for each of the supported functions + private static final int ID_INTEGER_SUBTRACT = 0; + private static final int ID_DOUBLE_SUBTRACT = 1; + + /** + * Creates a new SubtractFunction object. + * + * @param functionName the standard XACML name of the function to be + * handled by this object, including the full namespace + * + * @throws IllegalArgumentException if the function is unknown + */ + public SubtractFunction(String functionName) { + super(functionName, getId(functionName), getArgumentType(functionName), + false, 2, getArgumentType(functionName), false); + } + + /** + * Private helper that returns the internal identifier used for the + * given standard function. + */ + private static int getId(String functionName) { + if (functionName.equals(NAME_INTEGER_SUBTRACT)) { + return ID_INTEGER_SUBTRACT; + } else if (functionName.equals(NAME_DOUBLE_SUBTRACT)) { + return ID_DOUBLE_SUBTRACT; + } else { + throw new IllegalArgumentException("unknown subtract function " + + functionName); + } + } + + /** + * Private helper that returns the type used for the given standard + * function. Note that this doesn't check on the return value since the + * method always is called after getId, so we assume that the function + * is present. + */ + private static String getArgumentType(String functionName) { + if (functionName.equals(NAME_INTEGER_SUBTRACT)) { + return IntegerAttribute.identifier; + } + return DoubleAttribute.identifier; + } + + /** + * Returns a Set containing all the function identifiers + * supported by this class. + * + * @return a Set of Strings + */ + public static Set getSupportedIdentifiers() { + Set set = new HashSet(); + + set.add(NAME_INTEGER_SUBTRACT); + set.add(NAME_DOUBLE_SUBTRACT); + + return set; + } + + /** + * Evaluate the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + + // Evaluate the arguments + AttributeValue [] argValues = new AttributeValue[inputs.size()]; + EvaluationResult result = evalArgs(inputs, context, argValues); + if (result != null) { + return result; + } + + // Now that we have real values, perform the subtract operation + // in the manner appropriate for the type of the arguments. + if (getFunctionId() == ID_INTEGER_SUBTRACT) { + long arg0 = ((IntegerAttribute) argValues[0]).getValue(); + long arg1 = ((IntegerAttribute) argValues[1]).getValue(); + long difference = arg0 - arg1; + result = new EvaluationResult(new IntegerAttribute(difference)); + } else if (getFunctionId() == ID_DOUBLE_SUBTRACT) { + double arg0 = ((DoubleAttribute) argValues[0]).getValue(); + double arg1 = ((DoubleAttribute) argValues[1]).getValue(); + double difference = arg0 - arg1; + result = new EvaluationResult(new DoubleAttribute(difference)); + } + + return result; + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/TimeInRangeFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/TimeInRangeFunction.java new file mode 100644 index 0000000..9938cf3 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/TimeInRangeFunction.java @@ -0,0 +1,203 @@ + +/* + * @(#)TimeInRangeFunction.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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BooleanAttribute; +import com.sun.xacml.attr.TimeAttribute; + +import java.util.List; + + +/** + * This class implements the time-in-range function, which takes + * three time values and returns true if the first value falls between the + * second and the third value. This function was introduced in XACML 2.0. + *

+ * Note that this function allows any time ranges less than 24 hours. In + * other words, it is not bound by normal day boundries (midnight GMT), but + * by the minimum time in the range. This means that ranges like 9am-5pm + * are supported, as are ranges like 5pm-9am. + * + * @since 2.0 + * @author seth proctor + */ +public class TimeInRangeFunction extends FunctionBase +{ + + /** + * The identifier for this function + */ + public static final String NAME = FUNCTION_NS_2 + "time-in-range"; + + /** + * The number of milliseconds in a minute + */ + public static final long MILLIS_PER_MINUTE = 1000 * 60; + + /** + * The number of milliseconds in a day + */ + public static final long MILLIS_PER_DAY = MILLIS_PER_MINUTE * 60 * 24; + + /** + * Default constructor. + */ + public TimeInRangeFunction() { + super(NAME, 0, TimeAttribute.identifier, false, 3, + BooleanAttribute.identifier, false); + } + + /** + * Evaluates the time-in-range function, which takes three + * TimeAttribute values. This function return true + * if the first value falls between the second and third values + * (ie., on or after the second time and on or before the third + * time). If no time zone is specified for the second and/or third + * time value, then the timezone from the first time value is + * used. This lets you say time-in-range(current-time, 9am, 5pm) + * and always have the evaluation happen in your current-time + * timezone. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context the respresentation of the request + * + * @return an EvaluationResult containing true or false + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + AttributeValue [] argValues = new AttributeValue[inputs.size()]; + EvaluationResult result = evalArgs(inputs, context, argValues); + + // check if any errors occured while resolving the inputs + if (result != null) { + return result; + } + // get the three time values + TimeAttribute attr = (TimeAttribute)(argValues[0]); + long middleTime = attr.getMilliseconds(); + long minTime = resolveTime(attr, (TimeAttribute)(argValues[1])); + long maxTime = resolveTime(attr, (TimeAttribute)(argValues[2])); + + // first off, if the min and max are the same, then this can only + // be true is the middle is also the same value + if (minTime == maxTime) { + return EvaluationResult.getInstance(middleTime == minTime); + } + // shift the minTime to 00:00:00 so we can do a normal comparison, + // taking care to shift in the correct direction (left if the + // maxTime is bigger, otherwise right), and making sure that we + // handle any wrapping values for the middle time (the maxTime will + // never wrap around 00:00:00 GMT as long as we're dealing with + // windows of less than 24 hours) + + // the amount we're shifting + long shiftSpan; + + // figure out the right direction and get the shift amount + if (minTime < maxTime) { + shiftSpan = -minTime; + } else { + shiftSpan = MILLIS_PER_DAY - minTime; + } + // shift the maxTime and the middleTime + maxTime = maxTime + shiftSpan; + middleTime = handleWrap(middleTime + shiftSpan); + + // we're in the range if the middle is now between 0 and maxTime + return EvaluationResult. + getInstance((middleTime >= 0) && (middleTime <= maxTime)); + } + + /** + * Private helper method that is used to resolve the correct values for + * min and max. If an explicit timezone is provided for either, then + * that value gets used. Otherwise we need to pick the timezone the + * middle time is using, and move the other time into that timezone. + */ + private long resolveTime(TimeAttribute middleTime, + TimeAttribute otherTime) { + long time = otherTime.getMilliseconds(); + int tz = otherTime.getTimeZone(); + + // if there's no explicit timezone, then the otherTime needs to + // be shifted to the middleTime's timezone + if (tz == TimeAttribute.TZ_UNSPECIFIED) { + // the other time didn't specify a timezone, so we use the + // timezone specified in the middle time... + int middleTz = middleTime.getTimeZone(); + + // ...and we get the default timezone from the otherTime + tz = otherTime.getDefaultedTimeZone(); + + // if there was no specified timezone for the middleTime, use + // the default timezone for that too + if (middleTz == TimeAttribute.TZ_UNSPECIFIED) { + middleTz = middleTime.getDefaultedTimeZone(); + } + // use the timezone to offset the time value, if the two aren't + // already in the same timezone + if (middleTz != tz) { + time -= ((middleTz - tz) * MILLIS_PER_MINUTE); + time = handleWrap(time); + } + } + + return time; + } + + /** + * Private helper method that handles when a time value wraps no more + * than 24 hours either above 23:59:59 or below 00:00:00. + */ + private long handleWrap(long time) { + if (time < 0) { + // if it's negative, add one day + return time + MILLIS_PER_DAY; + } + + if (time > MILLIS_PER_DAY) { + // if it's more than 24 hours, subtract one day + return time - MILLIS_PER_DAY; + } + + return time; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/URIStringCatFunction.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/URIStringCatFunction.java new file mode 100644 index 0000000..bc2e246 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/URIStringCatFunction.java @@ -0,0 +1,171 @@ + +/* + * @(#)URIStringCatFunction.java + * + * Copyright 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.cond; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AnyURIAttribute; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.StringAttribute; + +import com.sun.xacml.ctx.Status; + +import java.net.URI; +import java.net.URISyntaxException; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + + +/** + * Represents the XACML 2.0 uri-string-concatenate function. + * + * @since 2.0 + * @author Seth Proctor + */ +public class URIStringCatFunction extends FunctionBase +{ + + /** + * Standard identifier for the url-string-concatenate function. + */ + public static final String NAME_URI_STRING_CONCATENATE = + FUNCTION_NS_2 + "uri-string-concatenate"; + + /** + * Creates an instance of this function. + */ + public URIStringCatFunction() { + super(NAME_URI_STRING_CONCATENATE, 0, AnyURIAttribute.identifier, + false); + } + + /** + * Checks the inputs of this function. + * + * @param inputs a List> of Evaluatables + * + * @throws IllegalArgumentException if the inputs won't work + */ + public void checkInputs(List inputs) throws IllegalArgumentException { + // scan the list to make sure nothing returns a bag + Iterator it = inputs.iterator(); + while (it.hasNext()) { + if (it.next().returnsBag() ) { + throw new IllegalArgumentException(NAME_URI_STRING_CONCATENATE + + " doesn't accept bags"); + } + } + + List copy = new ArrayList(inputs.size()); + for (int i = 0; i < inputs.size(); ++i ) { + copy.add( (Evaluatable)inputs.get(i)); + } + + // nothing is a bag, so check using the no-bag method + checkInputsNoBag(copy); + } + + /** + * Checks the inputs of this function assuming no parameters are bags. + * + * @param inputs a List> of Evaluatables + * + * @throws IllegalArgumentException if the inputs won't work + */ + public void checkInputsNoBag(List inputs) throws IllegalArgumentException { + // make sure it's long enough + if (inputs.size() < 2) { + throw new IllegalArgumentException("not enough args to " + + NAME_URI_STRING_CONCATENATE); + } + // check that the parameters are of the correct types... + Iterator it = inputs.iterator(); + + // ...the first argument must be a URI... + if (! it.next().getType().toString().equals(AnyURIAttribute.identifier)) { + throw new IllegalArgumentException("illegal parameter"); + } + // ...and all following arguments must be strings + while (it.hasNext()) { + if (! ((Expression)(it.next())).getType().toString(). + equals(StringAttribute.identifier)) { + throw new IllegalArgumentException("illegal parameter"); + } + } + } + + /** + * Evaluates the function given the input data. This function expects + * an AnyURIAttribute followed by one or more + * StringAttributes, and returns an + * AnyURIAttribute. + * + * @param inputs the input agrument list + * @param context the representation of the request + * + * @return the result of evaluation + */ + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + // Evaluate the arguments + AttributeValue [] argValues = new AttributeValue[inputs.size()]; + EvaluationResult result = evalArgs(inputs, context, argValues); + if (result != null) { + return result; + } + // the first argument is always a URI + String str = ((AnyURIAttribute)(argValues[0])).getValue().toString(); + + // the remaining arguments are strings + for (int i = 1; i < argValues.length; i++) { + str += ((StringAttribute)(argValues[i])).getValue(); + } + // finally, try to convert the string back to a URI + try { + return new EvaluationResult(new AnyURIAttribute(new URI(str))); + } catch (URISyntaxException use) { + List code = new ArrayList(); + code.add(Status.STATUS_PROCESSING_ERROR); + String message = NAME_URI_STRING_CONCATENATE + " didn't produce" + + " a valid URI: " + str; + + return new EvaluationResult(new Status(code, message)); + } + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/VariableDefinition.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/VariableDefinition.java new file mode 100644 index 0000000..f2bd162 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/VariableDefinition.java @@ -0,0 +1,213 @@ + +/* + * @(#)VariableDefinition.java + * + * Copyright 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.cond; + +import com.sun.xacml.Indenter; +import com.sun.xacml.ParsingException; +import com.sun.xacml.PolicyMetaData; +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.util.Collections; +import java.util.Set; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + + +/** + * This class supports the VariableDefinitionType type introuced in XACML + * 2.0. It allows a Policy to pre-define any number of expression blocks for + * general use. Note that it's legal (though not usually useful) to define + * expressions that don't get referenced within the Policy. It is illegal to + * have more than one definition with the same identifier within a Policy. + * + * @since 2.0 + * @author Seth Proctor + */ +public class VariableDefinition implements Locatable +{ + + // the identitifer for this definition + private String variableId; + + // the actual expression defined here + private Expression expression; + + public static final Set EMPTY_SET = Collections.emptySet(); + + private RuntimeInfo src; + + /** + * Creates a new VariableDefinition with the given + * identifier and expression. + * + * @param variableId the identifier for this definition + * @param expression the expression defined here + */ + public VariableDefinition(String variableId, Expression expression) { + this.variableId = variableId; + this.expression = expression; + } + + /** + * Returns a new instance of the VariableDefinition class + * based on a DOM node. The node must be the root of an XML + * VariableDefinitionType. + * + * @param root the DOM root of a VariableDefinitionType XML type + * @param metaData the meta-data associated with the containing policy + * @param manager VariableManager used to connect references + * to this definition + * + * @return The instance of this variable definition. + * + * @throws ParsingException if the VariableDefinitionType is invalid + */ + public static VariableDefinition getInstance(Node root, + PolicyMetaData metaData, VariableManager manager) + throws ParsingException { + RuntimeInfo src = RuntimeInfo.getRuntimeInfo(root, ELEMENT_TYPE.VARIABLE_DEFINITION); + // check if this really is a VariableDefinition + if (root.getNodeType() != Node.ELEMENT_NODE + || !root.getLocalName().equals("VariableDefinition")) { + throw new ParsingException("Can't create a VariableDefinition " + + "from a " + root.getLocalName() + " element"); + } + + String variableId = null; + if (root.getAttributes().getNamedItem("VariableId") != null) { + variableId = root.getAttributes().getNamedItem("VariableId") + .getNodeValue(); + } else { + throw new ParsingException("Required xml-attribute VariableId" + + " missing"); + } + + // get the first element, which is the expression node + NodeList nodes = root.getChildNodes(); + Node xprNode = nodes.item(0); + if (xprNode == null) { + throw new ParsingException("First expression node not found"); + } + int i = 1; + while (xprNode.getNodeType() != Node.ELEMENT_NODE) { + xprNode = nodes.item(i++); + } + // use that node to get the expression + Expression xpr = ExpressionHandler. + parseExpression(xprNode, metaData, manager); + + VariableDefinition varDef = new VariableDefinition(variableId, xpr); + varDef.src = src; + return varDef; + } + + /** + * Returns the identifier for this definition. + * + * @return the definition's identifier + */ + public String getVariableId() { + return this.variableId; + } + + /** + * Returns the expression provided by this definition. + * + * @return the definition's expression + */ + public Expression getExpression() { + return this.expression; + } + + /** + * Encodes this class into its XML representation and writes this + * encoding to the given OutputStream 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 class into its XML representation and writes this + * encoding to the given OutputStream 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 + ""); + indenter.in(); + + this.expression.encode(output, charsetName, indenter); + + out.println(""); + indenter.out(); + } + + public RuntimeInfo getRuntimeInfo() { + return this.src; + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/VariableManager.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/VariableManager.java new file mode 100644 index 0000000..fdd87f9 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/VariableManager.java @@ -0,0 +1,373 @@ + +/* + * @(#)VariableManager.java + * + * Copyright 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.cond; + +import com.sun.xacml.ParsingException; +import com.sun.xacml.PolicyMetaData; +import com.sun.xacml.ProcessingException; + +import java.net.URI; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + + +/** + * This class is used by the parsing routines to handle the relationships + * between variable references and definitions. Specifically, it takes care + * of the fact that definitions can be placed after their first reference, + * and can use references to create circular or recursive relationships. It + * keeps track of what's in the process of being parsed and will pre-parse + * elements as needed. + *

+ * Note that you should never have to use this class directly. It is really + * meant only as a utility for the internal parsing routines. Also, note that + * the operations on this class are not thread-safe. Typically this doesn't + * matter, since the code doesn't support using more than one thread to + * parse a single Policy. + * + * @since 2.0 + * @author Seth Proctor + * @author Ludwig Seitz + */ +public class VariableManager +{ + + // the map from identifiers to internal data + private Map idMap; + + // the meta-data for the containing policy + private PolicyMetaData metaData; + + /** + * Creates a manager with a fixed set of supported identifiers. For + * each of these identifiers, the map supplies a cooresponding DOM node + * used to parse the definition. This is used if, in the course of + * parsing one definition, a reference requires that you have information + * about another definition available. All parsed definitions are cached + * so that each is only parsed once. If a node is not provided, then the + * parsing code may throw an exception if out-of-order or circular + * refereces are used. + *

+ * Note that the use of a DOM node may change to an arbitrary interface, + * so that you could use your own mechanism, but this is still being + * hashed out. This interface will be forzed before a 2.0 release. + * + * @param variableIds a Map from an identifier to the + * Node that is the root of the + * cooresponding variable definition, or null + * @param metaData the meta-data associated with the containing policy + */ + public VariableManager(Map variableIds, PolicyMetaData metaData) { + this.idMap = new HashMap(); + + Iterator> it = variableIds.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry entry = it.next(); + Object key = entry.getKey(); + Node node = entry.getValue(); + this.idMap.put(key, new VariableState(null, node, null, + false, false)); + } + + this.metaData = metaData; + } + + /** + * Returns the definition with the given identifier. If the definition + * is not available, then this method will try to get the definition + * based on the DOM node given for this identifier. If parsing the + * definition requires loading another definition (because of a reference) + * then this method will be recursively invoked. This may make it slow + * to call this method once, but all retrieved definitions are cached, + * and once this manager has started parsing a definition it will never + * try parsing that definition again. If the definition cannot be + * retrieved, then an exception is thrown. + * + * @param variableId the definition's identifier + * + * @return the identified definition + * + * @throws ProcessingException if the definition cannot be resolved + */ + public VariableDefinition getDefinition(String variableId) { + VariableState state = (VariableState)(this.idMap.get(variableId)); + + // make sure this is an identifier we handle + if (state == null) { + throw new ProcessingException("variable is unsupported: " + + variableId); + } + + // if we've resolved the definition before, then we're done + if (state.definition != null) { + return state.definition; + } + + // we don't have the definition, so get the DOM node + Node node = state.rootNode; + + // we can't keep going unless we have a node to work with + if (node != null) { + // if we've already started parsing this node before, then + // don't start again + if (state.handled) { + throw new ProcessingException("processing in progress"); + } + + // keep track of the fact that we're parsing this node, and + // also get the type (if it's an Apply node) + state.handled = true; + discoverApplyType(node, state); + + try { + // now actually try parsing the definition...remember that + // if its expression has a reference, we could end up + // calling this manager method again + state.definition = + VariableDefinition.getInstance(state.rootNode, + this.metaData, this); + + return state.definition; + } catch (ParsingException pe) { + // we failed to parse the definition for some reason + throw new ProcessingException("failed to parse the definition", + pe); + } + } + + // we couldn't figure out how to resolve the definition + throw new ProcessingException("couldn't retrieve definition: " + + variableId); + } + + /** + * Private helper method to get the type of an expression, but only if + * that expression is an Apply. Basically, if there is a circular + * reference, then we'll need to know the types before we're done + * parsing one of the definitions. But, a circular reference that + * requires type-checking can only happen if the definition's expression + * is an Apply. So, we look here, and if it's an Apply, we get the + * type information and store that for later use, just in case. + *

+ * Note that we could wait until later to try this, or we could check + * first to see if there will be a circular reference. Comparatively, + * however, this isn't too expensive, and it makes the system much + * simpler. Still, it's worth re-examining this to see if there's a + * way that makes more sense. + */ + private void discoverApplyType(Node root, VariableState state) { + // get the first element, which is the expression node + NodeList nodes = root.getChildNodes(); + Node xprNode = nodes.item(0); + int i = 1; + while (xprNode.getNodeType() != Node.ELEMENT_NODE) { + xprNode = nodes.item(i++); + } + // now see if the node is an Apply + if (xprNode.getLocalName().equals("Apply")) { + try { + // get the function in the Apply... + Function function = ExpressionHandler. + getFunction(xprNode, this.metaData, + FunctionFactory.getGeneralInstance()); + + // ...and store the type information in the variable state + state.type = function.getReturnType(); + state.returnsBag = function.returnsBag(); + } catch (ParsingException pe) { + // we can just ignore this...if there really is an error, + // then it will come up during parsing in a code path that + // can handle the error cleanly + } + } + } + + /** + * Returns the datatype that the identified definition's expression + * resolves to on evaluation. Note that this method makes every attempt + * to discover this value, including parsing dependent definitions if + * needed and possible. + * + * @param variableId the identifier for the definition + * + * @return the datatype that the identified definition's expression + * evaluates to + * + * @throws ProcessingException if the identifier is not supported or if + * the result cannot be resolved + */ + public URI getVariableType(String variableId) { + VariableState state = (VariableState)(this.idMap.get(variableId)); + + // make sure the variable is supported + if (state == null) { + throw new ProcessingException("variable not supported: " + + variableId); + } + // if we've previously figured out the type, then return that + if (state.type != null) { + return state.type; + } + + // we haven't figured out the type already, so see if we have or + // can resolve the definition + VariableDefinition definition = state.definition; + if (definition == null) { + definition = getDefinition(variableId); + } + + // if we could get the definition, then ask it for the type + if (definition != null) { + return definition.getExpression().getType(); + } + + // we exhausted all our ways to get the right answer + throw new ProcessingException("we couldn't establish the type: " + + variableId); + } + + /** + * Returns true if the identified definition's expression resolves to + * a bag on evaluation. Note that this method makes every attempt to + * discover this value, including parsing dependent definitions if + * needed and possible. + * + * @param variableId the identifier for the definition + * + * @return true if the identified definition's expression evaluates + * to a bag + * + * @throws ProcessingException if the identifier is not supported or if + * the result cannot be resolved + */ + public boolean returnsBag(String variableId) { + VariableState state = (VariableState)(this.idMap.get(variableId)); + + // make sure the variable is supported + if (state == null) { + throw new ProcessingException("variable not supported: " + + variableId); + } + + // the flag is only valid if a type has also been determined + if (state.type != null) { + return state.returnsBag; + } + + // we haven't figured out the type already, so see if we have or + // can resolve the definition + VariableDefinition definition = state.definition; + if (definition == null) { + definition = getDefinition(variableId); + } + + // if we could get the definition, then ask it for the bag return + if (definition != null) { + return definition.getExpression().returnsBag(); + } + + // we exhausted all our ways to get the right answer + throw new ProcessingException("couldn't establish bag return for " + + variableId); + } + + /** + * Inner class that is used simply to manage fields associated with a + * given identifier. + */ + static class VariableState { + + /** + * the resolved definition for the identifier + */ + public VariableDefinition definition; + + /** + * the DOM node used to parse the definition + */ + public Node rootNode; + + /** + * the datatype returned when evaluating the definition + */ + public URI type; + + /** + * whether the definition's root evaluates to a Bag + */ + public boolean returnsBag; + + /** + * whether the definition is being parsed and constructed + */ + public boolean handled; + + /** + * + */ + public VariableState() { + this.definition = null; + this.rootNode = null; + this.type = null; + this.returnsBag = false; + this.handled = false; + } + + /** + * @param definition + * @param rootNode + * @param type + * @param returnsBag + * @param handled + */ + public VariableState(VariableDefinition definition, Node rootNode, + URI type, boolean returnsBag, + boolean handled) { + this.definition = definition; + this.rootNode = rootNode; + this.type = type; + this.returnsBag = returnsBag; + this.handled = handled; + } + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/VariableReference.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/VariableReference.java new file mode 100644 index 0000000..edefefc --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/VariableReference.java @@ -0,0 +1,351 @@ + +/* + * @(#)VariableReference.java + * + * Copyright 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.cond; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.Indenter; +import com.sun.xacml.ParsingException; +import com.sun.xacml.PolicyMetaData; +import com.sun.xacml.ProcessingException; +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.List; + +import org.w3c.dom.Node; + + +/** + * This class supports the VariableReferenceType type introuced in XACML + * 2.0. It allows an expression to reference a variable definition. If there + * is no such definition then the Policy is invalid. A reference can be + * included anywwhere in an expression where the referenced expression would + * be valid. + * + * @since 2.0 + * @author Seth Proctor + */ +public class VariableReference implements Evaluatable +{ + + // the identifier used to resolve the reference + private String variableId; + + // the actual definition we refernce, if it's known + private VariableDefinition definition = null; + + // a manager for resolving references, if it's been provided + private VariableManager manager = null; + + private RuntimeInfo src; + + /** + * Simple constructor that takes only the identifier. This is provided + * for tools that want to build policies only for the sake of encoding + * or displaying them. This constructor will not create a reference + * that can be followed to its associated definition, so it cannot be + * used in evaluation. + * + * @param variableId the reference identifier + */ + public VariableReference(String variableId) { + this.variableId = variableId; + } + + /** + * Constructor that takes the definition referenced by this class. If + * you're building policies programatically, this is typically the form + * you use. It does make the connection from reference to definition, + * so this will result in an evaluatable reference. + * + * @param definition the definition this class references + */ + public VariableReference(VariableDefinition definition) { + this.variableId = definition.getVariableId(); + this.definition = definition; + } + + /** + * Constructor that takes the reference identifier and a manager. This + * is typically only used by parsing code, since the manager is used + * to handle out-of-order definitions and circular references. + * + * @param variableId the reference identifier + * @param manager a VariableManager used to handle the + * dependencies between references and definitions during + * parsing + */ + public VariableReference(String variableId, VariableManager manager) { + this.variableId = variableId; + this.manager = manager; + } + + /** + * Returns a new instance of the VariableReference class + * based on a DOM node. The node must be the root of an XML + * VariableReferenceType. + * + * @param root the DOM root of a VariableReferenceType XML type + * @param metaData the meta-data associated with the containing policy + * @param manager the VariableManager used to connect this + * reference to its definition + * + * @return The instance of the variable reference. + */ + public static VariableReference getInstance(Node root, + PolicyMetaData metaData, VariableManager manager) + throws ParsingException { + RuntimeInfo src = RuntimeInfo.getRuntimeInfo(root, ELEMENT_TYPE.VARIABLE_REFERENCE); + // check if this really is a VariableReference + if (root.getNodeType() != Node.ELEMENT_NODE + || !root.getLocalName().equals("VariableReference")) { + throw new ParsingException("Can't create a VariableReference from " + + "a " + root.getLocalName() + " element"); + } + // pretty easy, since there's just an attribute... + String variableId = null; + if (root.getAttributes().getNamedItem("VariableId") != null) { + variableId = root.getAttributes().getNamedItem("VariableId") + .getNodeValue(); + } else { + throw new ParsingException("Required xml-attribute VariableId" + + " missing"); + } + + // ...but we keep the manager since after this we'll probably get + // asked for our type, etc., and the manager will also be used to + // resolve the actual definition + VariableReference variableReference = new VariableReference(variableId, manager); + if ( src != null ) { + variableReference.src = src; + src.setXACMLObject(variableReference); + } + return variableReference; + } + + /** + * Returns the reference identifier. + * + * @return the reference's identifier + */ + public String getVariableId() { + return this.variableId; + } + + /** + * Returns the VariableDefinition referenced by this class, + * or null if the definition cannot be resolved. + * + * @return the referenced definition or null + */ + public VariableDefinition getReferencedDefinition() { + // if this was created with a concrete definition, then that's what + // we return, otherwise we query the manager (if we have one) + if (this.definition != null) { + return this.definition; + } else if (this.manager != null) { + return this.manager.getDefinition(this.variableId); + } + + // if the simple constructor was used, then we have nothing + return null; + } + + /** + * Evaluates the referenced expression using the given context, and either + * returns an error or a resulting value. If this doesn't reference an + * evaluatable expression (eg, a single Function) then this will throw + * an exception. + * + * @param context the representation of the request + * + * @return the result of evaluation + * + * @throws ProcessingException if the expression isn't evaluatable + */ + public EvaluationResult evaluate(EvaluationCtx context) { + Expression xpr = getReferencedDefinition().getExpression(); + + // Note that it's technically possible for this expression to + // be something like a Function, which isn't Evaluatable. It + // wouldn't make sense to have this, but it is possible. Because + // it makes no sense, however, it's unlcear exactly what the + // error should be, so raising the ClassCastException here seems + // as good an approach as any for now... + return ((Evaluatable)xpr).evaluate(context); + } + + /** + * Returns the type of the referenced expression. + * + * @return the attribute return type of the referenced expression + * + * @throws ProcessingException if the type couldn't be resolved + */ + public URI getType() { + // if we have a concrete definition, then ask it for the type, + // otherwise query the manager using the getVariableType method, + // since this handles type-checking for definitions that haven't + // been parsed yet + if (this.definition != null) { + return this.definition.getExpression().getType(); + } + if (this.manager != null) { + return this.manager.getVariableType(this.variableId); + } + + throw new ProcessingException("couldn't resolve the type"); + } + + /** + * Tells whether evaluation will return a bag or a single value. + * + * @return true if evaluation will return a bag, false otherwise + * + * @throws ProcessingException if the return type couldn't be resolved + */ + public boolean returnsToBag() { + // see comment in getType() + if (this.definition != null) { + return getReferencedDefinition().getExpression().returnsBag(); + } + + if (this.manager != null) { + return this.manager.returnsBag(this.variableId); + } + + throw new ProcessingException("couldn't resolve the return type"); + } + + /** + * Tells whether evaluation will return a bag or a single value. + * + * @return true if evaluation will return a bag, false otherwise + * + * @throws ProcessingException if the return type couldn't be resolved + */ + public boolean returnsBag() { + // see comment in getType() + if (this.definition != null) { + return getReferencedDefinition().getExpression().returnsBag(); + } + if (this.manager != null) { + return this.manager.returnsBag(this.variableId); + } + + throw new ProcessingException("couldn't resolve the return type"); + } + + /** + * Tells whether evaluation will return a bag or a single value. + * + * @return true if evaluation will return a bag, false otherwise + * + * @deprecated As of 2.0, you should use the returnsBag + * method from the super-interface Expression. + * + * @throws ProcessingException if the return type couldn't be resolved + */ + public boolean evaluatesToBag() { + return returnsBag(); + } + + /** + * Always returns an empty list since references never have children in + * the policy tree. Note that the referenced definition may still have + * children, so tools may want to treat these as children of this + * reference, but must take care since circular references could create + * a tree of infinite depth. + * + * @return an empty List + */ + public List getChildren() { + return Expression.EMPTY_LIST; + } + + /** + * Encodes this class into its XML representation and writes this + * encoding to the given OutputStream 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 class into its XML representation and writes this + * encoding to the given OutputStream 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 + ""); + } + + public RuntimeInfo getRuntimeInfo() { + return this.src; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/AbsFunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/AbsFunctionCluster.java new file mode 100644 index 0000000..4634cad --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/AbsFunctionCluster.java @@ -0,0 +1,67 @@ + +/* + * @(#)AbsFunctionCluster.java + * + * Copyright 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.cond.cluster; + +import com.sun.xacml.cond.AbsFunction; +import com.sun.xacml.cond.Function; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Clusters all the functions supported by AbsFunction. + * + * @since 1.2 + * @author Seth Proctor + */ +public class AbsFunctionCluster implements FunctionCluster +{ + + public Set getSupportedFunctions() { + Set set = new HashSet(); + Iterator it = AbsFunction.getSupportedIdentifiers().iterator(); + + while (it.hasNext()) { + set.add(new AbsFunction(it.next())); + } + + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/AddFunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/AddFunctionCluster.java new file mode 100644 index 0000000..770d53a --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/AddFunctionCluster.java @@ -0,0 +1,66 @@ + +/* + * @(#)AddFunctionCluster.java + * + * Copyright 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.cond.cluster; + +import com.sun.xacml.cond.AddFunction; +import com.sun.xacml.cond.Function; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Clusters all the functions supported by AddFunction. + * + * @since 1.2 + * @author Seth Proctor + */ +public class AddFunctionCluster implements FunctionCluster +{ + + public Set getSupportedFunctions() { + Set set = new HashSet(); + Iterator it = AddFunction.getSupportedIdentifiers().iterator(); + + while (it.hasNext()) { + set.add(new AddFunction(it.next())); + } + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/ComparisonFunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/ComparisonFunctionCluster.java new file mode 100644 index 0000000..8c539a8 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/ComparisonFunctionCluster.java @@ -0,0 +1,66 @@ + +/* + * @(#)ComparisonFunctionCluster.java + * + * Copyright 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.cond.cluster; + +import com.sun.xacml.cond.ComparisonFunction; +import com.sun.xacml.cond.Function; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Clusters all the functions supported by ComparisonFunction. + * + * @since 1.2 + * @author Seth Proctor + */ +public class ComparisonFunctionCluster implements FunctionCluster +{ + + public Set getSupportedFunctions() { + Set set = new HashSet(); + Iterator it = ComparisonFunction.getSupportedIdentifiers().iterator(); + + while (it.hasNext()) { + set.add(new ComparisonFunction(it.next())); + } + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/ConditionBagFunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/ConditionBagFunctionCluster.java new file mode 100644 index 0000000..4efa778 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/ConditionBagFunctionCluster.java @@ -0,0 +1,67 @@ + +/* + * @(#)ConditionBagFunctionCluster.java + * + * Copyright 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.cond.cluster; + +import com.sun.xacml.cond.ConditionBagFunction; +import com.sun.xacml.cond.Function; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Clusters all the functions supported by ConditionBagFunction. + * + * @since 1.2 + * @author Seth Proctor + */ +public class ConditionBagFunctionCluster implements FunctionCluster +{ + + public Set getSupportedFunctions() { + Set set = new HashSet(); + Iterator it = ConditionBagFunction.getSupportedIdentifiers(). + iterator(); + + while (it.hasNext()) { + set.add(new ConditionBagFunction(it.next())); + } + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/ConditionSetFunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/ConditionSetFunctionCluster.java new file mode 100644 index 0000000..7f192eb --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/ConditionSetFunctionCluster.java @@ -0,0 +1,67 @@ + +/* + * @(#)ConditionSetFunctionCluster.java + * + * Copyright 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.cond.cluster; + +import com.sun.xacml.cond.ConditionSetFunction; +import com.sun.xacml.cond.Function; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Clusters all the functions supported by ConditionSetFunction. + * + * @since 1.2 + * @author Seth Proctor + */ +public class ConditionSetFunctionCluster implements FunctionCluster +{ + + public Set getSupportedFunctions() { + Set set = new HashSet(); + Iterator it = ConditionSetFunction.getSupportedIdentifiers(). + iterator(); + + while (it.hasNext()) { + set.add(new ConditionSetFunction(it.next())); + } + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/DateMathFunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/DateMathFunctionCluster.java new file mode 100644 index 0000000..81a3235 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/DateMathFunctionCluster.java @@ -0,0 +1,68 @@ + +/* + * @(#)DateMathFunctionCluster.java + * + * Copyright 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.cond.cluster; + +import com.sun.xacml.cond.DateMathFunction; +import com.sun.xacml.cond.Function; +import com.sun.xacml.cond.TimeInRangeFunction; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Clusters all the functions supported by DateMathFunction. + * + * @since 1.2 + * @author Seth Proctor + */ +public class DateMathFunctionCluster implements FunctionCluster +{ + + public Set getSupportedFunctions() { + Set set = new HashSet(); + Iterator it = DateMathFunction.getSupportedIdentifiers().iterator(); + + while (it.hasNext()) { + set.add(new DateMathFunction(it.next())); + } + set.add(new TimeInRangeFunction()); + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/DivideFunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/DivideFunctionCluster.java new file mode 100644 index 0000000..71e61a7 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/DivideFunctionCluster.java @@ -0,0 +1,66 @@ + +/* + * @(#)DivideFunctionCluster.java + * + * Copyright 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.cond.cluster; + +import com.sun.xacml.cond.DivideFunction; +import com.sun.xacml.cond.Function; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Clusters all the functions supported by DivideFunction. + * + * @since 1.2 + * @author Seth Proctor + */ +public class DivideFunctionCluster implements FunctionCluster +{ + + public Set getSupportedFunctions() { + Set set = new HashSet(); + Iterator it = DivideFunction.getSupportedIdentifiers().iterator(); + + while (it.hasNext()) { + set.add(new DivideFunction(it.next())); + } + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/EqualFunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/EqualFunctionCluster.java new file mode 100644 index 0000000..0115227 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/EqualFunctionCluster.java @@ -0,0 +1,66 @@ + +/* + * @(#)EqualFunctionCluster.java + * + * Copyright 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.cond.cluster; + +import com.sun.xacml.cond.EqualFunction; +import com.sun.xacml.cond.Function; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Clusters all the functions supported by EqualFunction. + * + * @since 1.2 + * @author Seth Proctor + */ +public class EqualFunctionCluster implements FunctionCluster +{ + + public Set getSupportedFunctions() { + Set set = new HashSet(); + Iterator it = EqualFunction.getSupportedIdentifiers().iterator(); + + while (it.hasNext()) { + set.add(new EqualFunction( it.next())); + } + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/FloorFunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/FloorFunctionCluster.java new file mode 100644 index 0000000..cfc755e --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/FloorFunctionCluster.java @@ -0,0 +1,66 @@ + +/* + * @(#)FloorFunctionCluster.java + * + * Copyright 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.cond.cluster; + +import com.sun.xacml.cond.FloorFunction; +import com.sun.xacml.cond.Function; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Clusters all the functions supported by FloorFunction. + * + * @since 1.2 + * @author Seth Proctor + */ +public class FloorFunctionCluster implements FunctionCluster +{ + + public Set getSupportedFunctions() { + Set set = new HashSet(); + Iterator it = FloorFunction.getSupportedIdentifiers().iterator(); + + while (it.hasNext()) { + set.add(new FloorFunction(it.next())); + } + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/FunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/FunctionCluster.java new file mode 100644 index 0000000..c8c5fbe --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/FunctionCluster.java @@ -0,0 +1,72 @@ + +/* + * @(#)FunctionCluster.java + * + * Copyright 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.cond.cluster; + +import java.util.Set; + +import com.sun.xacml.cond.Function; + + +/** + * Interface used by classes that support more than one function. It's a + * common design model to have a single class support more than one XACML + * function. In those cases, you should provide a proxy that implements + * FunctionCluster in addition to the Function. + * This is particularly important for the run-time configuration system, + * which uses this interface to create "clusters" of functions and therefore + * can use a smaller configuration file. + * + * @since 1.2 + * @author Seth Proctor + */ +public interface FunctionCluster +{ + + /** + * Returns a single instance of each of the functions supported by + * some class. The Set must contain instances of + * Function, and it must be both non-null and non-empty. + * It may contain only a single Function. + *

+ * Note that this is only used to return concrete Functions. + * It may not be used to report abstract functions. + * + * @return the functions supported by this class + */ + public Set getSupportedFunctions(); + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/GeneralBagFunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/GeneralBagFunctionCluster.java new file mode 100644 index 0000000..a1cf2ff --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/GeneralBagFunctionCluster.java @@ -0,0 +1,66 @@ + +/* + * @(#)GeneralBagFunctionCluster.java + * + * Copyright 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.cond.cluster; + +import com.sun.xacml.cond.Function; +import com.sun.xacml.cond.GeneralBagFunction; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Clusters all the functions supported by GeneralBagFunction. + * + * @since 1.2 + * @author Seth Proctor + */ +public class GeneralBagFunctionCluster implements FunctionCluster +{ + + public Set getSupportedFunctions() { + Set set = new HashSet(); + Iterator it = GeneralBagFunction.getSupportedIdentifiers().iterator(); + + while (it.hasNext()) { + set.add(new GeneralBagFunction(it.next())); + } + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/GeneralSetFunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/GeneralSetFunctionCluster.java new file mode 100644 index 0000000..d0d6e5f --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/GeneralSetFunctionCluster.java @@ -0,0 +1,66 @@ + +/* + * @(#)GeneralSetFunctionCluster.java + * + * Copyright 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.cond.cluster; + +import com.sun.xacml.cond.Function; +import com.sun.xacml.cond.GeneralSetFunction; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Clusters all the functions supported by GeneralSetFunction. + * + * @since 1.2 + * @author Seth Proctor + */ +public class GeneralSetFunctionCluster implements FunctionCluster +{ + + public Set getSupportedFunctions() { + Set set = new HashSet(); + Iterator it = GeneralSetFunction.getSupportedIdentifiers().iterator(); + + while (it.hasNext()) { + set.add(new GeneralSetFunction(it.next())); + } + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/HigherOrderFunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/HigherOrderFunctionCluster.java new file mode 100644 index 0000000..c8a762e --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/HigherOrderFunctionCluster.java @@ -0,0 +1,66 @@ + +/* + * @(#)HigherOrderFunctionCluster.java + * + * Copyright 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.cond.cluster; + +import com.sun.xacml.cond.Function; +import com.sun.xacml.cond.HigherOrderFunction; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Clusters all the functions supported by HigherOrderFunction. + * + * @since 1.2 + * @author Seth Proctor + */ +public class HigherOrderFunctionCluster implements FunctionCluster +{ + + public Set getSupportedFunctions() { + Set set = new HashSet(); + Iterator it = HigherOrderFunction.getSupportedIdentifiers().iterator(); + + while (it.hasNext()) { + set.add(new HigherOrderFunction(it.next())); + } + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/LogicalFunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/LogicalFunctionCluster.java new file mode 100644 index 0000000..d1b3c50 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/LogicalFunctionCluster.java @@ -0,0 +1,66 @@ + +/* + * @(#)LogicalFunctionCluster.java + * + * Copyright 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.cond.cluster; + +import com.sun.xacml.cond.Function; +import com.sun.xacml.cond.LogicalFunction; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Clusters all the functions supported by LogicalFunction. + * + * @since 1.2 + * @author Seth Proctor + */ +public class LogicalFunctionCluster implements FunctionCluster +{ + + public Set getSupportedFunctions() { + Set set = new HashSet(); + Iterator it = LogicalFunction.getSupportedIdentifiers().iterator(); + + while (it.hasNext()) { + set.add(new LogicalFunction(it.next())); + } + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/MatchFunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/MatchFunctionCluster.java new file mode 100644 index 0000000..8ea05ff --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/MatchFunctionCluster.java @@ -0,0 +1,66 @@ + +/* + * @(#)MatchFunctionCluster.java + * + * Copyright 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.cond.cluster; + +import com.sun.xacml.cond.Function; +import com.sun.xacml.cond.MatchFunction; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Clusters all the functions supported by MatchFunction. + * + * @since 1.2 + * @author Seth Proctor + */ +public class MatchFunctionCluster implements FunctionCluster +{ + + public Set getSupportedFunctions() { + Set set = new HashSet(); + Iterator it = MatchFunction.getSupportedIdentifiers().iterator(); + + while (it.hasNext()) { + set.add(new MatchFunction(it.next())); + } + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/ModFunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/ModFunctionCluster.java new file mode 100644 index 0000000..6c02480 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/ModFunctionCluster.java @@ -0,0 +1,66 @@ + +/* + * @(#)ModFunctionCluster.java + * + * Copyright 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.cond.cluster; + +import com.sun.xacml.cond.Function; +import com.sun.xacml.cond.ModFunction; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Clusters all the functions supported by ModFunction. + * + * @since 1.2 + * @author Seth Proctor + */ +public class ModFunctionCluster implements FunctionCluster +{ + + public Set getSupportedFunctions() { + Set set = new HashSet(); + Iterator it = ModFunction.getSupportedIdentifiers().iterator(); + + while (it.hasNext()) { + set.add(new ModFunction(it.next())); + } + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/MultiplyFunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/MultiplyFunctionCluster.java new file mode 100644 index 0000000..cbad28a --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/MultiplyFunctionCluster.java @@ -0,0 +1,66 @@ + +/* + * @(#)MultiplyFunctionCluster.java + * + * Copyright 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.cond.cluster; + +import com.sun.xacml.cond.Function; +import com.sun.xacml.cond.MultiplyFunction; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Clusters all the functions supported by MultiplyFunction. + * + * @since 1.2 + * @author Seth Proctor + */ +public class MultiplyFunctionCluster implements FunctionCluster +{ + + public Set getSupportedFunctions() { + Set set = new HashSet(); + Iterator it = MultiplyFunction.getSupportedIdentifiers().iterator(); + + while (it.hasNext()) { + set.add(new MultiplyFunction(it.next())); + } + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/NOfFunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/NOfFunctionCluster.java new file mode 100644 index 0000000..df0b5ec --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/NOfFunctionCluster.java @@ -0,0 +1,66 @@ + +/* + * @(#)NOfFunctionCluster.java + * + * Copyright 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.cond.cluster; + +import com.sun.xacml.cond.Function; +import com.sun.xacml.cond.NOfFunction; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Clusters all the functions supported by NOfFunction. + * + * @since 1.2 + * @author Seth Proctor + */ +public class NOfFunctionCluster implements FunctionCluster +{ + + public Set getSupportedFunctions() { + Set set = new HashSet(); + Iterator it = NOfFunction.getSupportedIdentifiers().iterator(); + + while (it.hasNext()) { + set.add(new NOfFunction(it.next())); + } + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/NotFunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/NotFunctionCluster.java new file mode 100644 index 0000000..6fbf587 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/NotFunctionCluster.java @@ -0,0 +1,66 @@ + +/* + * @(#)NotFunctionCluster.java + * + * Copyright 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.cond.cluster; + +import com.sun.xacml.cond.Function; +import com.sun.xacml.cond.NotFunction; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Clusters all the functions supported by NotFunction. + * + * @since 1.2 + * @author Seth Proctor + */ +public class NotFunctionCluster implements FunctionCluster +{ + + public Set getSupportedFunctions() { + Set set = new HashSet(); + Iterator it = NotFunction.getSupportedIdentifiers().iterator(); + + while (it.hasNext()) { + set.add(new NotFunction(it.next())); + } + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/NumericConvertFunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/NumericConvertFunctionCluster.java new file mode 100644 index 0000000..edb2ec3 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/NumericConvertFunctionCluster.java @@ -0,0 +1,67 @@ + +/* + * @(#)NumericConvertFunctionCluster.java + * + * Copyright 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.cond.cluster; + +import com.sun.xacml.cond.Function; +import com.sun.xacml.cond.NumericConvertFunction; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Clusters all the functions supported by NumericConvertFunction. + * + * @since 1.2 + * @author Seth Proctor + */ +public class NumericConvertFunctionCluster implements FunctionCluster +{ + + public Set getSupportedFunctions() { + Set set = new HashSet(); + Iterator it = NumericConvertFunction.getSupportedIdentifiers(). + iterator(); + + while (it.hasNext()) { + set.add(new NumericConvertFunction(it.next())); + } + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/RoundFunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/RoundFunctionCluster.java new file mode 100644 index 0000000..1acc6c3 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/RoundFunctionCluster.java @@ -0,0 +1,66 @@ + +/* + * @(#)RoundFunctionCluster.java + * + * Copyright 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.cond.cluster; + +import com.sun.xacml.cond.Function; +import com.sun.xacml.cond.RoundFunction; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Clusters all the functions supported by RoundFunction. + * + * @since 1.2 + * @author Seth Proctor + */ +public class RoundFunctionCluster implements FunctionCluster +{ + + public Set getSupportedFunctions() { + Set set = new HashSet(); + Iterator it = RoundFunction.getSupportedIdentifiers().iterator(); + + while (it.hasNext()) { + set.add(new RoundFunction(it.next())); + } + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/StringFunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/StringFunctionCluster.java new file mode 100644 index 0000000..86c33b2 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/StringFunctionCluster.java @@ -0,0 +1,71 @@ + +/* + * @(#)StringFunctionCluster.java + * + * Copyright 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.cond.cluster; + +import com.sun.xacml.cond.Function; +import com.sun.xacml.cond.StringFunction; +import com.sun.xacml.cond.URIStringCatFunction; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Clusters all the functions supported by StringFunction + * and URIStringCatFunction. + * + * @since 2.0 + * @author Seth Proctor + */ +public class StringFunctionCluster implements FunctionCluster +{ + + public Set getSupportedFunctions() { + Set set = new HashSet(); + Iterator it = StringFunction.getSupportedIdentifiers(). + iterator(); + + while (it.hasNext()) { + set.add(new StringFunction(it.next())); + } + set.add(new URIStringCatFunction()); + + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/StringNormalizeFunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/StringNormalizeFunctionCluster.java new file mode 100644 index 0000000..18102d2 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/StringNormalizeFunctionCluster.java @@ -0,0 +1,67 @@ + +/* + * @(#)StringNormalizeFunctionCluster.java + * + * Copyright 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.cond.cluster; + +import com.sun.xacml.cond.Function; +import com.sun.xacml.cond.StringNormalizeFunction; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Clusters all the functions supported by + * StringNormalizeFunction. + * + * @since 1.2 + * @author Seth Proctor + */ +public class StringNormalizeFunctionCluster implements FunctionCluster +{ + + public Set getSupportedFunctions() { + Set set = new HashSet(); + Iterator it = StringNormalizeFunction.getSupportedIdentifiers().iterator(); + + while (it.hasNext()) { + set.add(new StringNormalizeFunction(it.next())); + } + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/SubtractFunctionCluster.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/SubtractFunctionCluster.java new file mode 100644 index 0000000..200264d --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/SubtractFunctionCluster.java @@ -0,0 +1,66 @@ + +/* + * @(#)SubtractFunctionCluster.java + * + * Copyright 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.cond.cluster; + +import com.sun.xacml.cond.Function; +import com.sun.xacml.cond.SubtractFunction; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + + +/** + * Clusters all the functions supported by SubtractFunction. + * + * @since 1.2 + * @author Seth Proctor + */ +public class SubtractFunctionCluster implements FunctionCluster +{ + + public Set getSupportedFunctions() { + Set set = new HashSet(); + Iterator it = SubtractFunction.getSupportedIdentifiers().iterator(); + + while (it.hasNext()) { + set.add(new SubtractFunction(it.next())); + } + return set; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/package.html b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/package.html new file mode 100644 index 0000000..b1ff3fa --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/cluster/package.html @@ -0,0 +1,7 @@ + + This package defines the FunctionCluster interface that + is used to define a cluster of functions that are all implemented by + some common class. Also included in this package, as a convenience, + are cluster classes for all the standard functions. These are used by + the standard factory and by the run-time configuration system. + diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/package.html b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/package.html new file mode 100644 index 0000000..314a93e --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/cond/package.html @@ -0,0 +1,19 @@ + + Support for Conditions is in this package. This contains all of the + function code, including base types, implementations of all of the + standard functions, and a factory for getting functions and adding new + ones to the system. There is also support for the Condition and Apply + XML types. +

+ Note that prior to the 1.2 release, most of the function + implementations in this package were package private, mostly because + there is no reason to interact with these classes directly. With the + 1.2 release all classes were exposed, in part to make all the standard + identifier strings easily available. If you need a function instance, + however, you should still use the factory interface. You should not + ever need to instantiate one of the standard function classes + directly. Note also that in the next major release some of the + function impementations may change their interfaces, which is another + reason to interact with the standard functions only through the + factory interface. + diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/Attribute.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/Attribute.java new file mode 100644 index 0000000..016805b --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/Attribute.java @@ -0,0 +1,449 @@ + +/* + * @(#)Attribute.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.ctx; + +import com.sun.xacml.Indenter; + +import com.sun.xacml.Constants; +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; +import com.sun.xacml.PolicyMetaData; + +import com.sun.xacml.attr.AttributeFactory; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.StandardAttributeFactory; + +import java.io.PrintStream; +import java.io.OutputStream; +import java.io.UnsupportedEncodingException; + +import java.net.URI; +import java.util.LinkedList; +import java.util.List; + +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + + +/** + * Represents the AttributeType XML type found in the context schema. + * + * @since 1.0 + * @author Seth Proctor + */ +public class Attribute implements Cloneable +{ + + /** + * The required attribute id, + */ + protected URI id; + + // optional issuer attribute + private String issuer = null; + + // the single value associated with this attribute + private AttributeValue value; + + // the XACML version of this attribute + private int xacmlVersion = Constants.XACML_DEFAULT_VERSION; + + // a switch indicatig whether to include this attribute in the + // result status. + private boolean includeInResult = false; + + /** + * Creates a new Attribute of the type specified in the + * given AttributeValue. + * + * @param id the id of the attribute + * @param issuer the attribute's issuer or null if there is none + * @param value the actual value associated with the attribute meta-data, + * ` must not be null. + */ + public Attribute(URI id, String issuer, AttributeValue value) { + this(id, issuer, value, Constants.XACML_DEFAULT_VERSION, false); + } + + /** + * Creates a new Attribute of the type specified in the + * given AttributeValue. + * + * @param id the id of the attribute + * @param issuer the attribute's issuer or null if there is none + * @param value the actual value associated with the attribute meta-data, + * must not be null. + * @param xacmlVersion The XACML version number for compatibility code. + */ + public Attribute(URI id, String issuer, + AttributeValue value, int xacmlVersion) { + this(id, issuer, value, xacmlVersion, false); + } + + /** + * Creates a new Attribute of the type specified in the + * given AttributeValue. + * + * @param id the id of the attribute + * @param issuer the attribute's issuer or null if there is none + * @param value the actual value associated with the attribute meta-data, + * must not be null. + * @param xacmlVersion The XACML version number for compatibility code. + * @param includeInResult A switch indicating that this attribute + * should be included in the result. + */ + public Attribute(URI id, String issuer, + AttributeValue value, int xacmlVersion, + boolean includeInResult) { + this.id = id; + this.issuer = issuer; + this.value = value; + this.xacmlVersion = xacmlVersion; + this.includeInResult = includeInResult; + } + + /** + * The clone method. + * + * @return a copy if this object. + */ + public Object clone() { + try { + Attribute clone = (Attribute)super.clone(); + clone.id = this.id; + clone.issuer = this.issuer; + + StandardAttributeFactory fac + = StandardAttributeFactory.getFactory(); + try { + clone.value = fac.createValue(this.value.getType(), + this.value.encode()); + } catch (UnknownIdentifierException e) { + throw new RuntimeException("Impossible exception"); + } catch (ParsingException e) { + throw new RuntimeException("Impossible exception"); + } + + clone.xacmlVersion = this.xacmlVersion; + clone.includeInResult = this.includeInResult; + return clone; + } catch (CloneNotSupportedException e1) {//this should never happen + throw new RuntimeException("Couldn't clone Attribute"); + } + } + + /** + * Creates an instances of Attributes based on the root DOM + * node of the XML data. This method returns a list of attributes since + * the XACML syntax allows multi valued attributes in a single + * AttributeType XML type. + * + * @param root the DOM root of the AttributeType XML type + * + * @return a list of attributes + * + *@throws ParsingException if the data is invalid + */ + public static List getInstances(Node root) + throws ParsingException { + // check if this really is an attribute + if (root.getNodeType() != Node.ELEMENT_NODE + || !root.getLocalName().equals("Attribute")) { + throw new ParsingException("Can't create an Attribute from a " + + root.getLocalName() + " element"); + } + URI id = null; + URI type = null; + String issuer = null; + boolean includeInResult = false; + List result = new LinkedList(); + + AttributeFactory attrFactory = AttributeFactory.getInstance(); + + // Now get the xacml version + PolicyMetaData metaData = new PolicyMetaData(root.getNamespaceURI(), + Constants.XPATH_1_0_IDENTIFIER); + + NamedNodeMap attrs = root.getAttributes(); + + try { + id = new URI(attrs.getNamedItem("AttributeId").getNodeValue()); + } catch (Exception e) { + throw new ParsingException("Error parsing required attribute " + + "AttributeId in AttributeType", e); + } + + if (metaData.getXACMLVersion() < Constants.XACML_VERSION_3_0) { + try { + type = new URI(attrs.getNamedItem("DataType").getNodeValue()); + } catch (Exception e) { + throw new ParsingException("Error parsing required attribute " + + "DataType in AttributeType", e); + } + } + + try { + Node issuerNode = attrs.getNamedItem("Issuer"); + if (issuerNode != null) { + issuer = issuerNode.getNodeValue(); + } + } catch (Exception e) { + // shouldn't happen, but just in case... + throw new ParsingException("Error parsing optional AttributeType" + + " attribute", e); + } + + Node includeNode = attrs.getNamedItem("includeInResult"); + if (includeNode != null) { + if (includeNode.getNodeValue().equals("true")) { + includeInResult = true; + } else if (includeNode.getNodeValue().equals("false")){ + includeInResult = false; + } else { + throw new ParsingException("Error parsing boolean value" + + " includeInResult: " + + includeNode.getNodeValue()); + } + } + + // now we get the attribute value + 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("AttributeValue")) { + // get the type + if (metaData.getXACMLVersion() > + Constants.XACML_VERSION_2_0) { + Node typeNode = node.getAttributes() + .getNamedItem("DataType"); + if (typeNode == null) { + throw new ParsingException("No DataType xml-attribute " + + "found in AttributeValue"); + } + String typeStr = typeNode.getNodeValue(); + try { + type = new URI(typeStr); + } catch (Exception e) { + throw new ParsingException("Error parsing required " + + "attribute DataType in AttributeValue", e); + } + } + + // now get the value + try { + AttributeValue value = attrFactory.createValue(node, type); + Attribute attr = new Attribute(id, issuer, value, + metaData.getXACMLVersion(), includeInResult); + result.add(attr); + } catch (UnknownIdentifierException uie) { + throw new ParsingException("Unknown DataType", uie); + } + } + } + if(result.isEmpty()) + throw new ParsingException("Attribute must contain a value"); + + return result; + } + + /** + * Returns the id of this attribute + * + * @return the attribute id + */ + public URI getId() { + return this.id; + } + + /** + * Returns the issuer of this attribute, or null if no issuer was named + * + * @return the issuer or null + */ + public String getIssuer() { + return this.issuer; + } + + /** + * The value of this attribute, or null if no value was included + * + * @return the attribute's value or null + */ + public AttributeValue getValue() { + return this.value; + } + + /** + * Returns the xacml version number for this attribute. + * + * @return The xacml version number as defined in + * PolicyMetaData. + */ + public int getVersion() { + return this.xacmlVersion; + } + + /** + * @return True if this attribute should be included in the result. + */ + public boolean includeInResult() { + return this.includeInResult; + } + + /** + * Encodes this attribute into its XML representation and writes + * this encoding to the given OutputStream 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 attribute into its XML representation and writes + * this encoding to the given OutputStream 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 { + // setup the formatting & outstream stuff + PrintStream out; + if(charsetName == null) { + out = new PrintStream(output); + } else { + out = new PrintStream(output, false, charsetName); + } + + // write out the encoded form + out.println(encode(indenter)); + } + + /** + * Encoding method that returns the text-encoded version of + * this attribute with formatting. + * + * @return the text-encoded XML + */ + public String encode(Indenter indenter) { + String indent = indenter.makeString(); + indenter.in(); + String innerIndent = indenter.makeString(); + indenter.out(); + String encoded = indent + + "= Constants.XACML_VERSION_3_0 + && this.includeInResult == true) { + encoded += " includeInResult=\"true\""; + } + encoded += ">" + Constants.nl; + + if (this.xacmlVersion < Constants.XACML_VERSION_3_0) { + encoded += innerIndent + + this.value.encodeWithTags(false) + Constants.nl + + indent + ""; + + } else { + encoded += innerIndent + + this.value.encodeWithTags(true) + Constants.nl + + indent + ""; + } + + return encoded; + } + + + /** + * Simple encoding method that returns the text-encoded version of + * this attribute with no formatting. + * + * @return the text-encoded XML + */ + public String encode() { + String encoded = "= Constants.XACML_VERSION_3_0 + && this.includeInResult == true) { + encoded += " includeInResult=\"true\""; + } + encoded += ">"; + + if (this.xacmlVersion < Constants.XACML_VERSION_3_0) { + encoded += this.value.encodeWithTags(false) + ""; + } else { + encoded += this.value.encodeWithTags(true) + ""; + } + + return encoded; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/InputParser.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/InputParser.java new file mode 100644 index 0000000..a6f1a3d --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/InputParser.java @@ -0,0 +1,212 @@ + +/* + * @(#)InputParser.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.ctx; + +import com.sun.xacml.ParsingException; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +import org.apache.log4j.Logger; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + + +/** + * A package-private helper that provides a single static routine for + * parsing input based on the context schema. + * + * @since 1.0 + * @author Seth Proctor + */ +class InputParser implements ErrorHandler +{ + + // the schema file, if provided + private File schemaFile; + + // the single reference, which is null unless a schema file is provided + private static InputParser ipReference = null; + + // the property string to set to turn on validation + private static final String CONTEXT_SCHEMA_PROPERTY = + "com.sun.xacml.ContextSchema"; + + // the logger we'll use for all messages + private static final Logger logger = + Logger.getLogger(InputParser.class.getName()); + + // standard strings for setting validation + + private static final String JAXP_SCHEMA_LANGUAGE = + "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; + + private static final String W3C_XML_SCHEMA = + "http://www.w3.org/2001/XMLSchema"; + + private static final String JAXP_SCHEMA_SOURCE = + "http://java.sun.com/xml/jaxp/properties/schemaSource"; + + /** + * Look for the property that names the schema, and if it exists get + * the file name and create a single InputParser instance + */ + static { + String schemaName = System.getProperty(CONTEXT_SCHEMA_PROPERTY); + + if (schemaName != null) { + ipReference = new InputParser(new File(schemaName)); + } + } + + /** + * Constructor that takes the schema file. + */ + private InputParser(File schemaFile) { + this.schemaFile = schemaFile; + } + + /** + * Tries to Parse the given output as a Context document. + * + * @param input the stream to parse + * @param rootTag either "Request" or "Response" + * + * @return the root node of the request/response + * + * @throws ParsingException if a problem occurred parsing the document + */ + static Node parseInput(InputStream input, String rootTag) + throws ParsingException + { + NodeList nodes = null; + + try { + DocumentBuilderFactory factory = + DocumentBuilderFactory.newInstance(); + factory.setIgnoringComments(true); + + DocumentBuilder builder = null; + + // as of 1.2, we always are namespace aware + factory.setNamespaceAware(true); + + if (ipReference == null) { + // we're not validating + factory.setValidating(false); + + builder = factory.newDocumentBuilder(); + } else { + // we are validating + factory.setValidating(true); + + factory.setAttribute(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA); + factory.setAttribute(JAXP_SCHEMA_SOURCE, + ipReference.schemaFile); + + builder = factory.newDocumentBuilder(); + builder.setErrorHandler(ipReference); + } + + Document doc = builder.parse(input); + nodes = doc.getElementsByTagName(rootTag); + } catch (ParserConfigurationException e) { + throw new ParsingException("Error tring to parse " + rootTag + + "Type", e); + } catch (SAXException e) { + throw new ParsingException("Error tring to parse " + rootTag + + "Type", e); + } catch (IOException e) { + throw new ParsingException("Error tring to parse " + rootTag + + "Type", e); + } + + if (nodes.getLength() != 1) { + throw new ParsingException("Only one " + rootTag + "Type allowed " + + "at the root of a Context doc"); + } + return nodes.item(0); + } + + /** + * Standard handler routine for the XML parsing. + * + * @param exception information on what caused the problem + */ + public void warning(SAXParseException exception) { + logger.warn("Warning on line " + exception.getLineNumber() + + ": " + exception.getMessage()); + } + + /** + * Standard handler routine for the XML parsing. + * + * @param exception information on what caused the problem + * + * @throws SAXException always to halt parsing on errors + */ + public void error(SAXParseException exception) throws SAXException { + logger.warn("Error on line " + exception.getLineNumber() + + ": " + exception.getMessage()); + throw new SAXException("invalid context document"); + } + + /** + * Standard handler routine for the XML parsing. + * + * @param exception information on what caused the problem + * + * @throws SAXException always to halt parsing on errors + */ + public void fatalError(SAXParseException exception) throws SAXException { + logger.warn("FatalError on line " + exception.getLineNumber() + + ": " + exception.getMessage()); + throw new SAXException("invalid context document"); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/PolicyIssuer.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/PolicyIssuer.java new file mode 100644 index 0000000..02f9680 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/PolicyIssuer.java @@ -0,0 +1,118 @@ +/* + * @(#)PolicyIssuer.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.ctx; + +import java.net.URI; +import java.util.Date; +import java.util.Set; + + +/** + * Represents a policy issuer in the list of indirect delegates of an administrative + * request made to the PDP. This is the class contains a set of attributes for the + * policy issuer and an issue date, that specifies when the policy was issued. + * The date is used for request evaluation in a historic attribute model. + * + * @since 3.0 + * @author Ludwig Seitz + */ +public class PolicyIssuer extends RequestElement { + + /** + * the issue instant member variable, can be null + */ + private Date issueDate = null; + + /** + * Constructor. Creates a policy issuer out of the components. + * + * @param attributes must be a Sets of + * Attributes + */ + public PolicyIssuer(Set attributes) { + super(URI.create("PolicyIssuer"), attributes); + this.issueDate = null; + } + + /** + * Constructor. Creates a policy issuer out of it's attributes and the + * policy issue date + * + * @param attributes must be a set of Attribute objects + * @param issueDate the issue date of the policy. May be null. + */ + public PolicyIssuer(Set attributes, Date issueDate) { + super(URI.create("PolicyIssuer"), attributes); + if (issueDate != null) { + this.issueDate = (Date)issueDate.clone(); + } + } + + /** + * The clone method. + * + * @return a copy of this object. + */ + public Object clone() { + PolicyIssuer clone = (PolicyIssuer)super.clone(); + if (this.issueDate != null) { + this.issueDate = (Date)this.issueDate.clone(); + } + return clone; + } + + /** + * Get the issue date as a Date object + * of this indirect delegate. + * + * @return the issue date, may be null + */ + public Date getIssueDate() { + if (this.issueDate != null) { + return (Date)this.issueDate.clone(); + } + return null; + } + + /** + * Set the issueDate from a Date object. + * @param issueDate the issueDate to be set + */ + public void setDate(Date issueDate) { + this.issueDate = (Date)issueDate.clone(); + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/RequestCtx.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/RequestCtx.java new file mode 100644 index 0000000..741cbb3 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/RequestCtx.java @@ -0,0 +1,412 @@ +/* + * @(#)RequestCtx.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.ctx; + +import com.sun.xacml.Constants; +import com.sun.xacml.Indenter; +import com.sun.xacml.ParsingException; +import com.sun.xacml.PolicyMetaData; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + + +/** + * Represents a request made to the PDP. This is the class that contains all + * the data used to start a policy evaluation. + * + * @since 1.0 + * @author Seth Proctor + * @author Marco Barreno + * @author Ludwig Seitz + */ +public class RequestCtx +{ + + /** + * This contains the requestElements. + */ + private Set requestElements = null; + + /** + * Hold onto the root of the document for XPath searches + */ + private Node documentRoot = null; + + /** + * The XACML version. + */ + private int xacmlVersion = Constants.XACML_DEFAULT_VERSION; + + /** + * Constructor that creates a RequestCtx from + * RequestElements. + * + * @param requestElements the elements of the request. E.g. subject, + * resource, action. A Set of + * RequestElements. + * Must not be null, or empty. + * @param documentRoot the root node of the DOM tree for this request. + * Can be null. + * + * @throws IllegalArgumentException if the inputs are not well formed + */ + public RequestCtx(Set requestElements, Node documentRoot, + Node content) throws IllegalArgumentException { + this(requestElements, documentRoot, Constants.XACML_DEFAULT_VERSION); + } + + /** + * Constructor that creates a RequestCtx from + * RequestElements. + * + * @param requestElements the elements of the request. E.g. subject, + * resource, action. A Set of + * RequestElements. + * Must not be null, or empty. + * @param documentRoot the root node of the DOM tree for this request. + * Can be null. + * @param xacmlVersion The version number of the XACML used (see + * PolicyMetaData for details). + * + * @throws IllegalArgumentException if the inputs are not well formed + */ + public RequestCtx(Set requestElements, Node documentRoot, + int xacmlVersion) throws IllegalArgumentException { + + //Control type of the requestElements + Iterator elements = requestElements.iterator(); + while (elements.hasNext()){ + Object element = elements.next(); + if (!(element instanceof RequestElement)) { + throw new IllegalArgumentException("First parameter in request" + + " must be a Set of RequestElement objects"); + } + } + this.requestElements = new HashSet(requestElements); + + // save document root node for AttributeSelectors. + this.documentRoot = documentRoot; + + this.xacmlVersion = xacmlVersion; + } + + /** + * Create a new RequestCtx by parsing a node. This + * node should be created by schema-verified parsing of an + * XML document. + * + * @param root the node to parse for the RequestCtx + * + * @return a new RequestCtx constructed by parsing + * + * @throws ParsingException if the DOM node is invalid + */ + public static RequestCtx getInstance(Node root) throws ParsingException { + Set newRequestElements = new HashSet(); + // get XACML version + PolicyMetaData metaData = new PolicyMetaData( + root.getNamespaceURI(), Constants.XPATH_1_0_IDENTIFIER); + int xacmlVersion = metaData.getXACMLVersion(); + + // First check to be sure the node passed is indeed a Request node. + String tagName = root.getLocalName(); + if (root.getNodeType() != Node.ELEMENT_NODE + || ! tagName.equals("Request")) { + throw new ParsingException("Request cannot be constructed using " + + "type: " + root.getLocalName()); + } + + // Now go through its child nodes, finding the Attributes in the + // different categories. This may reset the XACML version if the + // namespace had it wrong. + NodeList children = root.getChildNodes(); + + for (int i = 0; i < children.getLength(); i++) { + Node node = children.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE) { + String name = node.getLocalName(); + if (name.equals("Attributes")) { + xacmlVersion = Constants.XACML_VERSION_3_0; + RequestElement re + = RequestElement.getInstance((Element)node, metaData); + if (re != null) { + newRequestElements.add(re); + } + } else if (name.equals("Subject") || + name.equals("Resource") || + name.equals("Action") || + name.equals("Environment")) { + //compatibility code for XACML 2.0 + xacmlVersion = Constants.XACML_VERSION_2_0; + RequestElement re + = RequestElement.getInstance((Element)node, metaData); + if (re != null) { + newRequestElements.add(re); + } + } else { + throw new ParsingException("Illegal element: " + + name + " where only Attributes and Content elements" + + " expected"); + } + } + } + + // Now create and return the RequestCtx from the information + // gathered + return new RequestCtx(newRequestElements, root, xacmlVersion); + } + + /** + * Creates a new RequestCtx by parsing XML from an + * input stream. Note that this a convenience method, and it will + * not do schema validation by default. You should be parsing the data + * yourself, and then providing the root node to the other + * getInstance method. If you use this convenience + * method, you probably want to turn on validation by setting the + * context schema file (see the programmer guide for more information + * on this). + * + * @param input a stream providing the XML data + * + * @return a new RequestCtx + * + * @throws ParsingException if there is an error parsing the input + */ + public static RequestCtx getInstance(InputStream input) + throws ParsingException + { + return getInstance(InputParser.parseInput(input, "Request")); + } + + /** + * Returns a Set containing the RequestElements. + * + * @return the request's RequestElements + */ + public Set getRequestElements() { + return Collections.unmodifiableSet(this.requestElements); + } + + /** + * @return The xacml version of this request + */ + public int getXACMLVersion() { + return this.xacmlVersion; + } + + /** + * Returns the root DOM node of the document used to create this + * object, or null if this object was created by hand (ie, not through + * the getInstance method) or if the root node was not + * provided to the constructor. + * + * @return the root DOM node or null + */ + public Node getDocumentRoot() { + return this.documentRoot; + } + + /** + * Encodes this context into its XML representation and writes this + * encoding to the given OutputStream. No + * indentation is used. + * + * @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 context into its XML representation and writes + * this encoding to the given OutputStream 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 { + + // Make a PrintStream for a nicer printing interface + PrintStream out; + if(charsetName == null) { + out = new PrintStream(output); + } else { + out = new PrintStream(output, false, charsetName); + } + + // Prepare the indentation string + String topIndent = indenter.makeString(); + out.print(topIndent + ""); + + HashSet subjects = new HashSet(); + HashSet resources = new HashSet(); + RequestElement action = null; + Iterator iter = this.requestElements.iterator(); + while (iter.hasNext()) { + RequestElement rE = iter.next(); + if (rE.getCategory().equals(Constants.RESOURCE_CAT)) { + resources.add(rE); + } else if (rE.getCategory().equals(Constants.ACTION_CAT)) { + action = rE; + } else { + //For backwards compatibility we cast all other categories + //to subject categories. + subjects.add(rE); + } + } + + //encode subjects + Iterator subjectIter = subjects.iterator(); + while(subjectIter.hasNext()) { + RequestElement subject = subjectIter.next(); + subject.encode(output, charsetName, indenter); + } + + //encode resources + Iterator resourceIter = resources.iterator(); + while(resourceIter.hasNext()) { + RequestElement resource = resourceIter.next(); + resource.encode(output, charsetName, indenter); + } + + //encode action + if (action != null) { + action.encode(output, charsetName, indenter); + } + break; + case Constants.XACML_VERSION_2_0: + out.println(Constants.XACML_2_0_CTX_ID + "\">"); + + subjects = new HashSet(); + resources = new HashSet(); + action = null; + RequestElement environment = null; + iter = this.requestElements.iterator(); + while (iter.hasNext()) { + RequestElement rE = (RequestElement)iter.next(); + if (rE.getCategory().equals(Constants.RESOURCE_CAT)) { + resources.add(rE); + } else if (rE.getCategory().equals(Constants.ACTION_CAT)) { + action = rE; + } else if (rE.getCategory().equals( + Constants.ENVIRONMENT_CAT)) { + environment = rE; + } else { + //For backwards compatibility we cast all other categories + //to subject categories. + subjects.add(rE); + } + } + + //encode subjects + subjectIter = subjects.iterator(); + while(subjectIter.hasNext()) { + RequestElement subject = (RequestElement)subjectIter.next(); + subject.encode(output, charsetName, indenter); + } + + //encode resources + resourceIter = resources.iterator(); + while(resourceIter.hasNext()) { + RequestElement resource = (RequestElement)resourceIter.next(); + resource.encode(output, charsetName, indenter); + } + + //encode action + if (action != null) { + action.encode(output, charsetName, indenter); + } + + //encode environment + if (environment != null) { + environment.encode(output, charsetName, indenter); + } + + break; + case Constants.XACML_VERSION_3_0: + /* falls through */ + default: + out.println(Constants.XACML_3_0_IDENTIFIER + "\">"); + + Iterator elements = this.requestElements.iterator(); + while (elements.hasNext()) { + RequestElement rEl = (RequestElement)elements.next(); + rEl.encode(output, charsetName, indenter); + } + break; + } + + indenter.out(); + + out.println(topIndent + ""); + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/RequestElement.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/RequestElement.java new file mode 100644 index 0000000..755663f --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/RequestElement.java @@ -0,0 +1,626 @@ +/* + * @(#)RequestElement.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.ctx; + +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; + +import java.net.URI; +import java.net.URISyntaxException; + +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 javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import javax.xml.transform.OutputKeys; + +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.sun.xacml.Constants; +import com.sun.xacml.Indenter; +import com.sun.xacml.ParsingException; +import com.sun.xacml.PolicyMetaData; + +/** + * Represents an element of a request made to the PDP. This is the class contains + * for example the subject, resource, action, delegate and one of the indirect + * delegate objects. Its purpose is to serve as an extension point for generic + * request elements. + * + * @since 3.0 + * @author Ludwig Seitz + */ +public class RequestElement implements Cloneable { + + /** + * The map of attributes characterizing this request element + * keyed by attribute-id. Maps to Sets of + * Attributes with the same id. + */ + private Map> attributes = null; + + /** + * The set of attributes with the includeInResult flag. + */ + private Set includeAttributes = null; + + /** + * This holds the optional Content/ResourceContent element, + * or null if there is no content. + */ + private Node content = null; + + /** + * The category of the request element + */ + private URI category = null; + + /** + * The XACML version. + */ + private int xacmlVersion = Constants.XACML_DEFAULT_VERSION; + + /** + * Remember if this was a pre 3.0 request with the SubjectCategory + * attribute (for encoding). + */ + private boolean withSubjectCategory = false; + + + public static final Set EMPTY_SET = Collections.emptySet(); + + /** + * Creates a request element out of it's category and attributes + * + * @param category the cateogry, must not be null + * @param attributes must be a Set containing + * Attribute objects. + * Must not be null or empty. + */ + public RequestElement(URI category, Set attributes) { + this(category, attributes, null, + Constants.XACML_DEFAULT_VERSION, false); + } + + /** + * Creates a request element without content. + * + * @param category the cateogry, must not be null + * @param attributes must be a Set containing + * Attribute objects. + * Must not be null or empty. + * @param xacmlVersion The version number of the XACML used (see + * PolicyMetaData for details). + * @param withSubjectCategory Remember if this was a pre 3.0 + * request with attribute category. + */ + public RequestElement(URI category, Set attributes, int xacmlVersion, + boolean withSubjectCategory) { + this(category, attributes, null, xacmlVersion, withSubjectCategory); + } + + /** + * Creates a request element out of it's category and attributes + * + * @param category the cateogry, must not be null + * @param attributes must be a Set containing + * Attribute objects. + * Must not be null or empty. + * @param content the content element, or null if there is no content. + * @param xacmlVersion The version number of the XACML used (see + * PolicyMetaData for details). + * @param withSubjectCategory Remember if this was a pre 3.0 + * request with attribute category. + */ + public RequestElement(URI category, Set attributes, + Node content, int xacmlVersion, + boolean withSubjectCategory) { + + this.attributes = new HashMap>(); + this.includeAttributes = new HashSet(); + // convert the set to a map for request optimization and + // make sure the contents are of correct type. + Iterator attrs = attributes.iterator(); + while (attrs.hasNext()){ +// Object thing = attrs.next(); +// if (!(thing instanceof Attribute)) { +// throw new IllegalArgumentException(category.toString() +// + " input is not well formed (should be an attribute " +// + "but is a " + thing.getClass().getName() + ")"); +// +// } + Attribute attr = attrs.next(); + URI id = attr.getId(); + if (this.attributes.containsKey(id)) { + Set set = this.attributes.get(id); + set.add(attr); + } else { + Set set = new HashSet(); + set.add(attr); + this.attributes.put(id, set); + } + if (attr.includeInResult()) { + this.includeAttributes.add(attr); + } + } + + if (content != null) { + if (xacmlVersion < Constants.XACML_VERSION_3_0 + && !category.equals(Constants.RESOURCE_CAT)) { + throw new IllegalArgumentException("Can't have Content" + + " in this category for this XACML version"); + } + this.content = content.cloneNode(true); + } + + if (category == null) { + throw new IllegalArgumentException("Request elements " + + "require a category"); + } + this.category = category; + this.xacmlVersion = xacmlVersion; + this.withSubjectCategory = withSubjectCategory; + } + + /** + * Constructor. Creates a request element out of it's name and attributes + * (already in Map), without content. + * + * @param category the cateogry, must not be null + * @param attributes must be a Map of Sets + * containing Attribute objects, keyed + * by the attribute ids. Must not be null or empty. + */ + public RequestElement(URI category, Map> attributes) { + this(category, attributes, null); + + } + + /** + * Constructor. Creates a request element out of it's name and attributes + * (already in Map), with content. + * + * @param category the cateogry, must not be null + * @param attributes must be a Map of Sets + * containing Attribute objects, keyed + * by the attribute ids. Must not be null or empty. + * @param content the content element, or null if there is no content. + */ + public RequestElement(URI category, Map> attributes, Node content) { + this.includeAttributes = new HashSet(); + if (attributes == null || attributes.isEmpty()) { + throw new IllegalArgumentException("Can't create RequestElement" + + " with empty or null attributes map."); + } + Iterator>> entries = attributes.entrySet().iterator(); + while(entries.hasNext()) { + Map.Entry> foo = entries.next(); +// if (!(foo.getKey() instanceof URI)) { +// throw new IllegalArgumentException("Can't create a Request" +// + "Element with non URI keys in the attributes" +// + " Map"); +// } +// Object bar = foo.getValue(); +// if (!(bar instanceof Set)) { +// throw new IllegalArgumentException("Can't create a Request" +// + "Element with non-Set objects in the attributes" +// + " Map"); +// } +// Set attrSet = (Set)bar; + Set attrSet = foo.getValue(); + Iterator iter = attrSet.iterator(); + while(iter.hasNext()) { + Object foobar = iter.next(); + if (!(foobar instanceof Attribute)) { + throw new IllegalArgumentException("Can't create a" + + " RequestElement with non-Attribute objects in" + + " the sets in the attributes Map"); + } + Attribute attr = (Attribute)foobar; + if (!attr.getId().equals(foo.getKey())) { + throw new IllegalArgumentException("Key mapped" + + " to the wrong attribute in attributes map"); + } + if (attr.includeInResult()) { + this.includeAttributes.add(attr); + } + } + + } + this.attributes = new HashMap>(attributes); + if (content != null) { + this.content = content.cloneNode(true); + } + this.category = category; + } + + /** + * The clone method. + * + * @return a copy of this object. + */ + public Object clone() { + try { + RequestElement clone = (RequestElement)super.clone(); + // deep copy of the attributes + clone.attributes = new HashMap>(); + clone.includeAttributes = new HashSet(); + Iterator iter = this.attributes.keySet().iterator(); + while(iter.hasNext()) { + URI key = URI.create(iter.next().toString()); + Set attrs = new HashSet(); + Iterator iter2 = this.attributes.get(key).iterator(); + while(iter2.hasNext()) { + attrs.add( (Attribute) iter2.next().clone()); + } + clone.attributes.put(key, attrs); + } + Iterator iter3 = this.includeAttributes.iterator(); + while(iter3.hasNext()) { + clone.includeAttributes.add( (Attribute) iter3.next().clone()); + } + if (this.content != null) { + clone.content = this.content.cloneNode(true); + } + clone.category = this.category; + clone.xacmlVersion = this.xacmlVersion; + clone.withSubjectCategory = this.withSubjectCategory; + return clone; + } catch (CloneNotSupportedException e) {//this should never happen + throw new RuntimeException("Couldn't clone RequestElement"); + } + } + + /** + * Create a new RequestElement by parsing a node in a + * request. This node should be created by schema-verified parsing of an + * XML document. + * + * @param root the node to parse for the RequestElement + * @param metaData the meta-data associated with the containing request. + * + * @return a new RequestElement constructed by parsing + * + * @throws ParsingException if the DOM node is invalid + */ + public static RequestElement getInstance(Element root, + PolicyMetaData metaData) throws ParsingException { + URI category = null; + boolean withSubjectCategory = false; + if (metaData.getXACMLVersion() == Constants.XACML_VERSION_3_0) { + NamedNodeMap xmlAttrs = root.getAttributes(); + if (xmlAttrs == null) { + throw new ParsingException("No XML attributes found," + + " where Category attribute was expected"); + } + Node catNode = xmlAttrs.getNamedItem("Category"); + if (catNode == null) { + throw new ParsingException("'Category' XML attribute " + + "not found"); + } + + String categoryStr = catNode.getNodeValue(); + try { + category = new URI(categoryStr); + } catch (URISyntaxException e) { + throw new ParsingException("Error while parsing " + + "category: " + categoryStr, e); + } + } else if (metaData.getXACMLVersion() + < Constants.XACML_VERSION_3_0) { + if (root.getLocalName().equals("Subject")) { + NamedNodeMap xmlAttrs = root.getAttributes(); + if (xmlAttrs == null) { + category = Constants.SUBJECT_CAT; + } else { + Node catNode = xmlAttrs.getNamedItem("SubjectCategory"); + if (catNode == null) { + category = Constants.SUBJECT_CAT; + } else { + withSubjectCategory = true; + String categoryStr = catNode.getNodeValue(); + try { + category = new URI(categoryStr); + } catch (URISyntaxException e) { + throw new ParsingException("Error while parsing " + + "category: " + categoryStr, e); + } + } + } + } else if (root.getLocalName().equals("Resource")) { + category = Constants.RESOURCE_CAT; + } else if (root.getLocalName().equals("Action")) { + category = Constants.ACTION_CAT; + } else if (metaData.getXACMLVersion() + == Constants.XACML_VERSION_2_0 + && root.getLocalName().equals("Environment")) { + category = Constants.ENVIRONMENT_CAT; + } else { + throw new ParsingException("Invalid node: " + + root.getLocalName() + " in XACML " + + metaData.getXACMLVersion() + " request"); + } + } else { + throw new ParsingException("Invalid/Unsupported XACML version"); + } + + // Find the content element if there is one + Node content = null; + NodeList children = root.getChildNodes(); + for(int i = 0; i < children.getLength(); i++) { + Node node = children.item(i); + if (node != null && node.getNodeType() == Node.ELEMENT_NODE) { + if (node.getLocalName().equals("Content")) { + if (metaData.getXACMLVersion() + < Constants.XACML_VERSION_3_0) { + throw new ParsingException("Content element not"+ + " supported for XACML version " + + metaData.getXACMLVersion()); + } + content = node.cloneNode(true); + break; + } else if (node.getLocalName().equals("ResourceContent")) { + if (metaData.getXACMLVersion() + > Constants.XACML_VERSION_2_0) { + throw new ParsingException("ResourceContent element not" + + " supported for XACML version " + + metaData.getXACMLVersion()); + } + content = node.cloneNode(true); + break; + } + } + } + + Set attributes = parseAttributes(root); + + return new RequestElement(category, attributes, content, + metaData.getXACMLVersion(), withSubjectCategory); + } + + /** + * Helper method that parses a set of Attribute types. + * @param root the root Node containing the set of + * Attributes and Contents + * @return A Set Attributes. + */ + private static Set parseAttributes(Node root) throws ParsingException { + Set set = new HashSet(); + 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("Attribute")) { + List attrs = Attribute.getInstances(node); + set.addAll(attrs); + } + } + return set; + } + + /** + * Get the category of this request element. + * + * @return the category of the request element + */ + public URI getCategory() { + return this.category; + } + + /** + * Get the attributes of the request element as a Map + * The keys of the Map are the attribute ids. + * + * @return the Map of Sets of + * Attributes of the request element. + */ + public Map> getAttributes() { + return Collections.unmodifiableMap(this.attributes); + } + + /** + * Get the content node of the request element if there is one. + * + * @return a Node or null. + * + */ + public Node getContent() { + if (this.content == null) { + return null; + } + return this.content.cloneNode(true); + } + + /** + * @return The Set of attributes with the includeInResult + * flag. + */ + public Set getIncludeInResultSet() { + return Collections.unmodifiableSet(this.includeAttributes); + } + + + /** + * Encodes this request element into its XML representation and writes + * this encoding to the given OutputStream without + * 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 request element into its XML representation and writes + * this encoding to the given OutputStream 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 { + // setup the formatting & outstream stuff + String indent = indenter.makeString(); + PrintStream out; + if(charsetName == null) { + out = new PrintStream(output); + } else { + out = new PrintStream(output, false, charsetName); + } + + // write out the encoded form + String endTag = null; + if (this.xacmlVersion > Constants.XACML_VERSION_2_0) { + out.println(indent + ""); + endTag = indent + ""; + } else { + if (this.category.equals(Constants.RESOURCE_CAT)) { + out.println(indent + ""); + endTag = indent + ""; + } else if (this.category.equals(Constants.ACTION_CAT)) { + out.println(indent + ""); + endTag = indent + ""; + } else if (this.xacmlVersion == Constants.XACML_VERSION_2_0 + && this.category.equals(Constants.ENVIRONMENT_CAT)) { + out.println(indent + ""); + endTag = indent + ""; + } else { + if (this.withSubjectCategory) { + out.println(indent + ""); + endTag = indent + ""; + } else { + out.println(indent + ""); + endTag = indent + ""; + } + } + } + + // go in one more for next-level elements... + indenter.in(); + + if (this.content != null) { + out.println(indenter.makeString() + ""); + encodeContent(this.content, output, charsetName, indenter); + out.println(indenter.makeString() + ""); + } + encodeAttributes(this.attributes, output, charsetName, indenter); + + indenter.out(); + + //Notice: the indent was already included previously + out.println(endTag); + } + + /** + * Private helper function to encode the content node. + * @throws UnsupportedEncodingException + */ + private void encodeContent(Node content, OutputStream output, + String charsetName, Indenter indenter) + throws UnsupportedEncodingException { + indenter.in(); + String indent = indenter.makeString(); + PrintStream out; + if(charsetName == null) { + out = new PrintStream(output); + } else { + out = new PrintStream(output, false, charsetName); + } + StringWriter sw = new StringWriter(); + try { + Transformer serializer + = TransformerFactory.newInstance().newTransformer(); + serializer.setOutputProperty( + OutputKeys.OMIT_XML_DECLARATION, "yes"); + serializer.transform(new DOMSource(content), new StreamResult(sw)); + } catch (TransformerException e) { + throw new RuntimeException( + "'This never happens' error happened"); + } + out.println(indent + sw.toString()); + indenter.out(); + } + + /** + * Private helper function to encode the attribute sets + * @throws UnsupportedEncodingException + */ + private void encodeAttributes(Map> attributes, OutputStream output, + String charsetName, Indenter indenter) + throws UnsupportedEncodingException { + Iterator>> it = attributes.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry> entry = it.next(); + Set set = entry.getValue(); + Iterator it2 = set.iterator(); + while (it2.hasNext()) { + Attribute attr = (Attribute) it2.next(); + attr.encode(output, charsetName, indenter); + } + } + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/ResponseCtx.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/ResponseCtx.java new file mode 100644 index 0000000..e6cbb39 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/ResponseCtx.java @@ -0,0 +1,224 @@ + +/* + * @(#)ResponseCtx.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.ctx; + +import com.sun.xacml.Constants; +import com.sun.xacml.Indenter; +import com.sun.xacml.ParsingException; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + + +/** + * Represents the response to a request made to the XACML PDP. + * + * @since 1.0 + * @author Seth Proctor + * @author Marco Barreno + */ +public class ResponseCtx +{ + + // The set of Result objects returned by the PDP + private Set results = null; + + /** + * Constructor that creates a new ResponseCtx with only a + * single Result (a common case). + * + * @param result the single result in the response + */ + public ResponseCtx(Result result) { + this.results = new HashSet(); + this.results.add(result); + } + + /** + * Constructor that creates a new ResponseCtx with a + * Set of Results. The Set must + * be non-empty. + * + * @param results a Set of Result objects + */ + public ResponseCtx(Set results) { + this.results = Collections.unmodifiableSet(new HashSet(results)); + } + + /** + * Creates a new instance of ResponseCtx based on the given + * DOM root node. A ParsingException is thrown if the DOM + * root doesn't represent a valid ResponseType. + * + * @param root the DOM root of a ResponseType + * + * @return a new ResponseCtx + * + * @throws ParsingException if the node is invalid + */ + public static ResponseCtx getInstance(Node root) throws ParsingException { + // check if this really is a response + if (root.getNodeType() != Node.ELEMENT_NODE + || !root.getLocalName().equals("Response")) { + throw new ParsingException("Can't create a Response from a " + + root.getLocalName() + " element"); + } + Set results = new HashSet(); + + 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("Result")) { + results.add(Result.getInstance(node)); + } + } + + if (results.size() == 0) { + throw new ParsingException("must have at least one Result"); + } + return new ResponseCtx(results); + } + + /** + * Creates a new ResponseCtx by parsing XML from an + * input stream. Note that this is a convenience method, and it will + * not do schema validation by default. You should be parsing the data + * yourself, and then providing the root node to the other + * getInstance method. If you use this convenience + * method, you probably want to turn on validation by setting the + * context schema file (see the programmer guide for more information + * on this). + * + * @param input a stream providing the XML data + * + * @return a new ResponseCtx + * + * @throws ParsingException if there is an error parsing the input + */ + public static ResponseCtx getInstance(InputStream input) + throws ParsingException + { + return getInstance(InputParser.parseInput(input, "Response")); + } + + /** + * Get the set of Results from this response. + * + * @return a Set of results + */ + public Set getResults() { + return this.results; + } + + /** + * Encodes this context into its XML representation and writes this + * encoding to the given OutputStream 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 context into its XML representation and writes + * this encoding to the given OutputStream 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 { + + // Make a PrintStream for a nicer printing interface + PrintStream out; + if(charsetName == null) { + out = new PrintStream(output); + } else { + out = new PrintStream(output, false, charsetName); + } + + // Prepare the indentation string + String indent = indenter.makeString(); + + // Now write the XML... + + out.println(indent + ""); + + // Go through all results + Iterator it = this.results.iterator(); + indenter.in(); + + while (it.hasNext()) { + Result result = it.next(); + result.encode(out, charsetName, indenter); + } + + indenter.out(); + + // Finish the XML for a response + out.println(indent + ""); + + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/Result.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/Result.java new file mode 100644 index 0000000..6a81436 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/Result.java @@ -0,0 +1,723 @@ +/* + * @(#)Result.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.ctx; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.Indenter; +import com.sun.xacml.Obligation; +import com.sun.xacml.ParsingException; +import com.sun.xacml.PolicyMetaData; + +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + + +/** + * Represents the ResultType XML object from the Context schema. Any number + * of these may included in a ResponseCtx. This class encodes the + * decision effect, as well as an optional resource identifier and optional + * status data. Any number of obligations may also be included. + * + * @since 1.0 + * @author Seth Proctor + * @author Marco Barreno + */ +public class Result implements Cloneable +{ + +// public enum DECISION { +// DECISION_PERMIT, +// DECISION_DENY, +// DECISION_INDETERMINATE, +// DECISION_NOT_APPLICABLE, +// INVALID_DECISION; +// +// private String[] messages = { PERMIT, DENY, +// INDETERMINATE, +// NOT_APPLICABLE, "Invalid" }; +// +// public String getMessage() { +// return messages[this.ordinal()]; +// } +// +// public static DECISION getFromInt(int decision) { +// switch (decision) { +// case Result.DECISION_PERMIT: +// return DECISION_PERMIT; +// case Result.DECISION_DENY: +// return DECISION_DENY; +// case Result.DECISION_INDETERMINATE: +// return DECISION_INDETERMINATE; +// case Result.DECISION_NOT_APPLICABLE: +// return DECISION_NOT_APPLICABLE; +// case Result.INVALID_DECISION: +// return INVALID_DECISION; +// } +// return null; +// } +// } + + /** + * The decision to permit the request + */ + public static final int DECISION_PERMIT = 0; + + /** + * The decision to deny the request + */ + public static final int DECISION_DENY = 1; + + /** + * The decision that a decision about the request cannot be made + */ + public static final int DECISION_INDETERMINATE = 2; + + /** + * The decision that nothing applied to us + */ + public static final int DECISION_NOT_APPLICABLE = 3; + + /** + * An uninitialized decision value + */ + public static final int INVALID_DECISION = 5; + + + public static final String PERMIT = "Permit"; + + public static final String DENY = "Deny"; + + public static final String INDETERMINATE = "Indeterminate"; + + public static final String NOT_APPLICABLE = "NotApplicable"; + + + + /** + * string versions of the 4 Decision types used for encoding + */ + private static final String [] PRIVATE_DECISIONS = { PERMIT, DENY, + INDETERMINATE, + NOT_APPLICABLE}; + + /** + * unmodifiable list of the previous + */ + public static final List DECISIONS = + Collections.unmodifiableList(Arrays.asList(PRIVATE_DECISIONS)); + + + + /** + * Null string for disambiguation. + */ + public static final String nullString = null; + + /** + * the decision effect + */ + private int decision = -1; + + /** + * the status data + */ + private Status status = null; + + /** + * the resource identifier or null if there is none + */ + private String resource = null; + + /** + * the Set of RequestElements describing + * the attributes included in the result. May be empty. + */ + private Set includedAttributes; + + /** + * the set of obligations which may be empty + */ + private Set obligations; + + /** + * Constructs a Result object with default status data (OK). + * + * @param decision the decision effect to include in this result. This + * must be one of the four fields in this class. + * + * @throws IllegalArgumentException if decision is not valid + */ + public Result(int decision) throws IllegalArgumentException { + this(decision, null, nullString, null); + } + + /** + * Constructs a Result object with default status data (OK), + * and obligations, but no resource identifier. + * + * @param decision the decision effect to include in this result. This + * must be one of the four fields in this class. + * @param obligations the obligations the PEP must handle + * + * @throws IllegalArgumentException if decision is not valid + */ + public Result(int decision, Set obligations) + throws IllegalArgumentException + { + this(decision, null, nullString, obligations); + } + + /** + * Constructs a Result object with status data but without a + * resource identifier. Typically the decision is DECISION_INDETERMINATE + * in this case, though that's not always true. + * + * @param decision the decision effect to include in this result. This + * must be one of the four fields in this class. + * @param status the Status to include in this result + * + * @throws IllegalArgumentException if decision is not valid + */ + public Result(int decision, Status status) throws IllegalArgumentException { + this(decision, status, nullString, null); + } + + /** + * Constructs a Result object with status data and obligations + * but without a resource identifier. Typically the decision is + * DECISION_INDETERMINATE in this case, though that's not always true. + * + * @param decision the decision effect to include in this result. This + * must be one of the four fields in this class. + * @param status the Status to include in this result + * @param obligations the obligations the PEP must handle + * + * @throws IllegalArgumentException if decision is not valid + */ + public Result(int decision, Status status, Set obligations) + throws IllegalArgumentException + { + this(decision, status, nullString, obligations); + } + + /** + * Constructs a Result object with a resource identifier, + * but default status data (OK). The resource being named must match + * the resource (or a descendent of the resource in the case of a + * hierarchical resource) from the associated request. + * + * @param decision the decision effect to include in this result. This + * must be one of the four fields in this class. + * @param context the evaluation context to determine the ResourceId + * or the included attributes. + * + * @throws IllegalArgumentException if decision is not valid + */ + public Result(int decision, EvaluationCtx context) + throws IllegalArgumentException + { + this(decision, null, context, null); + } + + /** + * Constructs a Result object with a resource identifier, + * and obligations, but default status data (OK). The resource being named + * must match the resource (or a descendent of the resource in the case of + * a hierarchical resource) from the associated request. + * + * @param decision the decision effect to include in this result. This + * must be one of the four fields in this class. + * @param context the evaluation context to determine the ResourceId + * or the included attributes. + * @param obligations the obligations the PEP must handle + * + * @throws IllegalArgumentException if decision is not valid + */ + public Result(int decision, EvaluationCtx context, Set obligations) + throws IllegalArgumentException + { + this(decision, null, context, obligations); + } + + /** + * Constructs a Result object with status data and a + * resource identifier. + * + * @param decision the decision effect to include in this result. This + * must be one of the four fields in this class. + * @param status the Status to include in this result + * @param context the evaluation context to determine the ResourceId + * or the included attributes. + * + * @throws IllegalArgumentException if decision is not valid + */ + public Result(int decision, Status status, EvaluationCtx context) + throws IllegalArgumentException + { + this(decision, status, context, null); + } + + /** + * Constructs a Result object with status data, a + * resource identifier, and obligations. + * + * @param decision the decision effect to include in this result. This + * must be one of the four fields in this class. + * @param status the Status to include in this result + * @param context the evaluation context to determine the ResourceId + * or the included attributes. + * @param obligations the obligations the PEP must handle + * + * @throws IllegalArgumentException if decision is not valid + */ + public Result(int decision, Status status, EvaluationCtx context, + Set obligations) + throws IllegalArgumentException { + // check that decision is valid + if ((decision != DECISION_PERMIT) && (decision != DECISION_DENY) && + (decision != DECISION_INDETERMINATE) && + (decision != DECISION_NOT_APPLICABLE) ) { + throw new IllegalArgumentException("invalid decision value"); + } + this.decision = decision; + + if (status == null) { + this.status = Status.getOkInstance(); + } else { + this.status = status; + } + if (obligations == null) { + this.obligations = new HashSet(); + } else { + this.obligations = obligations; + } + + this.includedAttributes = new HashSet(); + if (!context.getIncludedAttributes().isEmpty()) { + this.includedAttributes = new HashSet(context.getIncludedAttributes()); + Iterator iter = this.includedAttributes.iterator(); + while (iter.hasNext()) { + if (!(iter.next() instanceof RequestElement)) { + throw new IllegalArgumentException("included attributes" + + " must be RequestElement objects"); + } + } + } else if (context.getResourceId() != null) { + this.resource = context.getResourceId().encode(); + } + } + + /** + * Constructs a Result object with status data, a + * resource identifier, and obligations. + * + * @param decision the decision effect to include in this result. This + * must be one of the four fields in this class. + * @param status the Status to include in this result + * @param resource the ResourceId this result refers to. + * @param obligations the obligations the PEP must handle + * + * @throws IllegalArgumentException if decision is not valid + */ + public Result(int decision, Status status, String resource, + Set obligations) throws IllegalArgumentException { + // check that decision is valid + if ((decision != DECISION_PERMIT) && (decision != DECISION_DENY) && + (decision != DECISION_INDETERMINATE) && + (decision != DECISION_NOT_APPLICABLE)) { + throw new IllegalArgumentException("invalid decision value"); + } + this.decision = decision; + + if (status == null) { + this.status = Status.getOkInstance(); + } else { + this.status = status; + } + if (obligations == null) { + this.obligations = new HashSet(); + } else { + this.obligations = obligations; + } + + // not used by this constructor + this.includedAttributes = new HashSet(); + + this.resource = resource; + } + + /** + * Constructs a Result object with status data, a + * resource identifier, obligations and included attributes. + * + * @param decision the decision effect to include in this result. This + * must be one of the four fields in this class. + * @param status the Status to include in this result + * @param includedAttributes the Set of + * RequestElements describing + * the attributes included in the result. + * Can be null. + * @param obligations the obligations the PEP must handle@param decision + * + * @throws IllegalArgumentException + */ + public Result(int decision, Status status, Set includedAttributes, + Set obligations) throws IllegalArgumentException { + // check that decision is valid + if ((decision != DECISION_PERMIT) && (decision != DECISION_DENY) && + (decision != DECISION_INDETERMINATE) && + (decision != DECISION_NOT_APPLICABLE)) { + throw new IllegalArgumentException("invalid decision value"); + } + this.decision = decision; + + if (status == null) { + this.status = Status.getOkInstance(); + } else { + this.status = status; + } + if (obligations == null) { + this.obligations = new HashSet(); + } else { + this.obligations = obligations; + } + + this.includedAttributes = new HashSet(); + if (includedAttributes != null && !includedAttributes.isEmpty()) { + this.includedAttributes = includedAttributes; + Iterator iter = this.includedAttributes.iterator(); + while (iter.hasNext()) { + if (!(iter.next() instanceof RequestElement)) { + throw new IllegalArgumentException("included attributes" + + " must be RequestElement objects"); + } + } + } + } + + /** + * The clone method. + * + * @return a copy of this object. + */ + public Object clone() { + try { + Result clone = (Result)super.clone(); + clone.decision = this.decision; + clone.status = this.status; + clone.resource = this.resource; + clone.includedAttributes = this.includedAttributes; + clone.obligations = this.obligations; + return clone; + } catch (CloneNotSupportedException e) {//this should never happen + throw new RuntimeException("Couldn't clone Result"); + } + } + + + /** + * Creates a new instance of a Result based on the given + * DOM root node. A ParsingException is thrown if the DOM + * root doesn't represent a valid ResultType. + * + * @param root the DOM root of a ResultType + * + * @return a new Result + * + * @throws ParsingException if the node is invalid + */ + public static Result getInstance(Node root) throws ParsingException { + //check if this really is a result + if (root.getNodeType() != Node.ELEMENT_NODE + || !root.getLocalName().equals("Result")) { + throw new ParsingException("Can't create a Result from a " + + root.getLocalName() + " element"); + } + int decision = -1; + Status status = null; + String resource = null; + Set obligations = null; + Set includedAttributes = new HashSet(); + + NamedNodeMap attrs = root.getAttributes(); + Node resourceAttr = attrs.getNamedItem("ResourceId"); + if (resourceAttr != null) { + resource = resourceAttr.getNodeValue(); + } + NodeList nodes = root.getChildNodes(); + for (int i = 0; i < nodes.getLength(); i++) { + Node node = nodes.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE) { + String name = node.getLocalName(); + + if (name.equals("Decision")) { + String type = node.getFirstChild().getNodeValue(); + for (int j = 0; j < DECISIONS.size(); j++) { + if (DECISIONS.get(j).equals(type)) { + decision = j; + break; + } + } + + if (decision == -1) { + throw new ParsingException("Unknown Decision: " + + type); + } + } else if (name.equals("Status")) { + status = Status.getInstance(node); + } else if (name.equals("Obligations")) { + obligations = parseObligations(node); + } else if (name.equals("Attributes")) { + if (resource != null) { + throw new ParsingException("Can not mix ResourceId" + + " and included attributes"); + } + //parse RequestElement with default 3.0 metaData + includedAttributes.add(RequestElement.getInstance( + (Element)node, new PolicyMetaData())); + } + } + } + + if (resource != null) { + return new Result(decision, status, resource, obligations); + } + return new Result(decision, status, includedAttributes, + obligations); + } + + /** + * Helper method that handles the obligations + */ + private static Set parseObligations(Node root) throws ParsingException { + Set set = new HashSet(); + + 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")) { + set.add(Obligation.getInstance(node)); + } + } + + if (set.size() == 0) { + throw new ParsingException("ObligationsType must not be empty"); + } + return set; + } + + /** + * Returns the decision associated with this Result. This + * will be one of the four DECISION_* fields in this class. + * + * @return the decision effect + */ + public int getDecision() { + return this.decision; + } + + /** + * Returns the status data included in this Result. + * Typically this will be STATUS_OK except when the decision + * is INDETERMINATE. + * + * @return status associated with this Result + */ + public Status getStatus() { + return this.status; + } + + /** + * Returns the resource to which this Result applies, or null if none + * is specified. + * + * @return a resource identifier or null + */ + public String getResource() { + return this.resource; + } + + /** + * @return Returns the included attributes as a Set of + * Attributes. This may be empty. + */ + public Set getIncludedAttributes() { + return this.includedAttributes; + } + + /** + * Sets the resource identifier if it has not already been set before. + * The core code does not set the resource identifier, so this is useful + * if you want to write wrapper code that needs this information. + * + * @param resource the resource identifier + * + * @return true if the resource identifier was set, false if it already + * had a value + */ + public boolean setResource(String resource) { + if (this.resource != null) { + return false; + } + this.resource = resource; + + return true; + } + + /** + * Returns the set of obligations that the PEP must fulfill, which may + * be empty. + * + * @return the set of obligations + */ + public Set getObligations() { + return this.obligations; + } + + /** + * Adds an obligation to the set of obligations that the PEP must fulfill + * + * @param obligation the Obligation to add + */ + public void addObligation(Obligation obligation) { + if (obligation != null) { + this.obligations.add(obligation); + } + } + + /** + * Encodes this Result into its XML form and writes this + * out to the provided OutputStream 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 Result into its XML form and writes this + * out to the provided OutputStream 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(); + + indenter.in(); + String indentNext = indenter.makeString(); + + // encode the starting tag + if (this.resource == null || + !this.includedAttributes.isEmpty()) { + out.println(indent + ""); + } else { + out.println(indent + ""); + } + + // encode the decision + out.println(indentNext + "" + DECISIONS.get(this.decision) + + ""); + // encode the included attributes + if (!this.includedAttributes.isEmpty()) { + Iterator it = this.includedAttributes.iterator(); + while (it.hasNext()) { + RequestElement element = (RequestElement)(it.next()); + element.encode(output, charsetName, indenter); + } + } + + // encode the status + if (this.status != null) { + this.status.encode(output, charsetName, indenter); + } + + // encode the obligations + if (this.obligations.size() != 0) { + out.println(indentNext + ""); + + Iterator it = this.obligations.iterator(); + indenter.in(); + + while (it.hasNext()) { + Obligation obligation = (Obligation)(it.next()); + obligation.encode(output, charsetName, indenter); + } + + indenter.out(); + out.println(indentNext + ""); + } + + indenter.out(); + + // finish it off + out.println(indent + ""); + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/Status.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/Status.java new file mode 100644 index 0000000..56f2b73 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/Status.java @@ -0,0 +1,404 @@ + +/* + * @(#)Status.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.ctx; + +import com.sun.xacml.Constants; +import com.sun.xacml.Indenter; +import com.sun.xacml.ParsingException; + +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.UnsupportedEncodingException; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + + +/** + * Represents the status data that is included in a ResultType. By default, + * the status is OK. + * + * @since 1.0 + * @author Seth Proctor + */ +public class Status +{ + + /** + * Standard identifier for the OK status + */ + public static final String STATUS_OK = + "urn:oasis:names:tc:xacml:1.0:status:ok"; + + /** + * Standard identifier for the MissingAttribute status + */ + public static final String STATUS_MISSING_ATTRIBUTE = + "urn:oasis:names:tc:xacml:1.0:status:missing-attribute"; + + /** + * Standard identifier for the SyntaxError status + */ + public static final String STATUS_SYNTAX_ERROR = + "urn:oasis:names:tc:xacml:1.0:status:syntax-error"; + + /** + * Standard identifier for the ProcessingError status + */ + public static final String STATUS_PROCESSING_ERROR = + "urn:oasis:names:tc:xacml:1.0:status:processing-error"; + + // the status code + private List code; + + // the message + private String message; + + // the detail + private StatusDetail detail; + + // a single OK object we'll use most of the time + private static Status okStatus; + + // initialize the OK Status object + static { + List code = new ArrayList(); + code.add(STATUS_OK); + okStatus = new Status(code); + } + + /** + * Constructor that takes only the status code. + * + * @param code a List of String codes, typically + * just one code, but this may contain any number of minor + * codes after the first item in the list, which is the major + * code + */ + public Status(List code) { + this(code, null, null); + } + + /** + * Constructor that takes both the status code and a message to include + * with the status. + * + * @param code a List of String codes, typically + * just one code, but this may contain any number of minor + * codes after the first item in the list, which is the major + * code + * @param message a message to include with the code + */ + public Status(List code, String message) { + this(code, message, null); + } + + /** + * Constructor that takes the status code, an optional message, and some + * detail to include with the status. Note that the specification + * explicitly says that a status code of OK, SyntaxError or + * ProcessingError may not appear with status detail, so an exception is + * thrown if one of these status codes is used and detail is included. + * + * @param code a List of String codes, typically + * just one code, but this may contain any number of minor + * codes after the first item in the list, which is the major + * code + * @param message a message to include with the code, or null if there + * should be no message + * @param detail the status detail to include, or null if there is no + * detail + * + * @throws IllegalArgumentException if detail is included for a status + * code that doesn't allow detail + */ + public Status(List code, String message, StatusDetail detail) + throws IllegalArgumentException + { + // if the code is ok, syntax error or processing error, there + // must not be any detail included + if (detail != null) { + String c = (String)(code.iterator().next()); + if (c.equals(STATUS_OK) || c.equals(STATUS_SYNTAX_ERROR) || + c.equals(STATUS_PROCESSING_ERROR)) { + throw new IllegalArgumentException("status detail cannot be " + + "included with " + c); + } + } + + this.code = Collections.unmodifiableList(new ArrayList(code)); + this.message = message; + this.detail = detail; + } + + /** + * Returns the status code. + * + * @return the status code + */ + public List getCode() { + return this.code; + } + + /** + * Returns the status message or null if there is none. + * + * @return the status message or null + */ + public String getMessage() { + return this.message; + } + + /** + * Returns the status detail or null if there is none. + * + * @return a StatusDetail or null + */ + public StatusDetail getDetail() { + return this.detail; + } + + /** + * Gets a Status instance that has the OK status and no + * other information. This is the default status data for all responses + * except Indeterminate ones. + * + * @return an instance with STATUS_OK + */ + public static Status getOkInstance() { + return okStatus; + } + + /** + * Creates a new instance of Status based on the given + * DOM root node. A ParsingException is thrown if the DOM + * root doesn't represent a valid StatusType. + * + * @param root the DOM root of a StatusType + * + * @return a new Status + * + * @throws ParsingException if the node is invalid + */ + public static Status getInstance(Node root) throws ParsingException { + if (root.getNodeType() != Node.ELEMENT_NODE + || !root.getLocalName().equals("Status")) { + throw new ParsingException("Can't create a Status from a " + + root.getLocalName() + " element"); + } + List code = null; + String message = null; + StatusDetail detail = null; + + NodeList nodes = root.getChildNodes(); + for (int i = 0; i < nodes.getLength(); i++) { + Node node = nodes.item(i); + if (node.getNodeType() == Node.ELEMENT_NODE) { + String name = node.getLocalName(); + if (name.equals("StatusCode")) { + code = parseStatusCode(node); + } else if (name.equals("StatusMessage")) { + message = node.getFirstChild().getNodeValue(); + } else if (name.equals("StatusDetail")) { + detail = StatusDetail.getInstance(node); + } + } + } + + return new Status(code, message, detail); + } + + /** + * Private helper that parses the status code + */ + private static List parseStatusCode(Node root) { + // get the top-level code + String val = root.getAttributes().getNamedItem("Value").getNodeValue(); + List code = new ArrayList(); + code.add(val); + + // now get the list of all sub-codes, and work through them + NodeList list = ((Element)root).getElementsByTagName("StatusCode"); + for (int i = 0; i < list.getLength(); i++) { + Node node = list.item(i); + code.add(node.getAttributes().getNamedItem("Value"). + getNodeValue()); + } + + return code; + } + + /** + * Encodes this status data into its XML representation and writes + * this encoding to the given OutputStream 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 status data into its XML representation and writes + * this encoding to the given OutputStream 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 + ""); + + indenter.in(); + + encodeStatusCode(out, indenter, this.code.iterator()); + + if (this.message != null) { + out.println(indenter.makeString() + "" + + this.message + ""); + } + + if (this.detail != null) { + out.println(this.detail.getEncoded()); + } + + indenter.out(); + + out.println(indent + ""); + } + + /** + * Encodes the object in XML + */ + private void encodeStatusCode(PrintStream out, Indenter indenter, + Iterator iterator) { + String in = indenter.makeString(); + String code = iterator.next(); + + if (iterator.hasNext()) { + indenter.in(); + out.println(in + ""); + encodeStatusCode(out, indenter, iterator); + out.println(in + ""); + indenter.out(); + } else { + out.println(in + ""); + } + } + + + /** + * @param indenter + * @return the string representation of this status message + * encoded in XML + */ + public String toString(Indenter indenter) { + String indent = indenter.makeString(); + + String result = indent + "" + Constants.nl; + + indenter.in(); + + result += statusCode2String(indenter, this.code.iterator()); + + if (this.message != null) { + result += indenter.makeString() + "" + + this.message + "" + Constants.nl; + } + if (this.detail != null) { + result += indenter.makeString() + this.detail.getEncoded(); + } + indenter.out(); + + result += indent + "" + Constants.nl; + + return result; + } + + private String statusCode2String(Indenter indenter, Iterator it) { + String in = indenter.makeString(); + String code = it.next(); + String result; + + if (it.hasNext()) { + indenter.in(); + result = in + "" + Constants.nl; + result += statusCode2String(indenter, it); + result += in + "" + Constants.nl; + indenter.out(); + } else { + result = in + "" + + Constants.nl; + } + return result; + } + + public static Status createStatus(String code, String message) { + List codes = new ArrayList(); + codes.add(code); + return new Status(codes, message); + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/StatusDetail.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/StatusDetail.java new file mode 100644 index 0000000..ab17224 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/StatusDetail.java @@ -0,0 +1,209 @@ + +/* + * @(#)StatusDetail.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.ctx; + +import com.sun.xacml.Constants; +import com.sun.xacml.ParsingException; + +import java.io.ByteArrayInputStream; +import java.io.IOException; + +import java.util.Collection; +import java.util.Iterator; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.xml.sax.SAXException; + + +/** + * This class represents the StatusDetailType in the context schema. Because + * status detail is defined as a sequence of xs:any XML type, the data in + * this class must be generic, and it is up to the application developer to + * interpret the data appropriately. + * + * @since 1.0 + * @author Seth Proctor + */ +public class StatusDetail +{ + + // the root node + private Node detailRoot; + + // the text version, if it's avilable already + private String detailText = null; + + /** + * Constructor that uses a List of Attributes + * to define the status detail. This is a common form of detail data, + * and can be used for things like providing the information included + * with the missing-attribute status code. + * + * @param attributes a List of Attributes + * + * @throws IllegalArgumentException if there is a problem encoding the + * Attributes + */ + public StatusDetail(Collection attributes) throws IllegalArgumentException { + this.detailText = "" + Constants.nl; + Iterator it = attributes.iterator(); + + while (it.hasNext()) { + Attribute attr = it.next(); + this.detailText += attr.encode() + Constants.nl; + } + + this.detailText += ""; + + try { + this.detailRoot = textToNode(this.detailText); + } catch (ParsingException pe) { + // really, this should never happen, since we just made sure that + // we're working with valid text, but it's possible that encoding + // the attribute could have caused problems... + throw new IllegalArgumentException("invalid Attribute data"); + } + } + + /** + * Constructor that takes the text-encoded form of the XML to use as + * the status data. The encoded text will be wrapped with the + * StatusDetail XML tag, and the resulting text must + * be valid XML or a ParsingException will be thrown. + * + * @param encoded a non-null String that encodes the + * status detail + * + * @throws ParsingException if the encoded text is invalid XML + */ + public StatusDetail(String encoded) throws ParsingException { + this.detailText = "" + Constants.nl + encoded + + Constants.nl + ""; + this.detailRoot = textToNode(this.detailText); + } + + /** + * Private constructor that just sets the root node. This interface + * is provided publically through the getInstance method. + */ + private StatusDetail(Node root) { + this.detailRoot = root; + } + + /** + * Private helper routine that converts text into a node + */ + private Node textToNode(String encoded) throws ParsingException { + try { + String text = "" + Constants.nl; + byte [] bytes = (text + encoded).getBytes(); + + DocumentBuilderFactory factory = + DocumentBuilderFactory.newInstance(); + DocumentBuilder db = factory.newDocumentBuilder(); + Document doc = db.parse(new ByteArrayInputStream(bytes)); + + return doc.getDocumentElement(); + } catch (ParserConfigurationException e) { + throw new ParsingException("invalid XML for status detail"); + } catch (SAXException e) { + throw new ParsingException("invalid XML for status detail"); + } catch (IOException e) { + throw new ParsingException("invalid XML for status detail"); + } + } + + /** + * Creates an instance of a StatusDetail object based on + * the given DOM root node. The node must be a valid StatusDetailType + * root, or else a ParsingException is thrown. + * + * @param root the DOM root of the StatusDetailType XML type + * + * @return a new StatusDetail object + * + * @throws ParsingException if the root node is invalid + */ + public static StatusDetail getInstance(Node root) throws ParsingException { + // check that it's really a StatusDetailType root + if (root.getNodeType() != Node.ELEMENT_NODE || + ! root.getLocalName().equals("StatusDetail")) { + throw new ParsingException("not a StatusDetail node"); + } + + return new StatusDetail(root); + } + + /** + * Returns the StatusDetailType DOM root node. This may contain within + * it any type of valid XML data, and it is up to the application writer + * to handle the data accordingly. One common use of status data is to + * include Attributes, which can be created from their + * root DOM nodes using their getInstance method. + * + * @return the DOM root for the StatusDetailType XML type + */ + public Node getDetail() { + return this.detailRoot; + } + + /** + * Returns the text-encoded version of this data, if possible. If the + * String form constructor was used, this will just be the + * original text wrapped with the StatusData tag. If the List + * form constructor was used, it will be the encoded attribute data. + * If this was created using the getInstance method, then + * getEncoded will throw an exception. + * + * @return the encoded form of this data + * + * @throws IllegalStateException if this object was created using the + * getInstance method + */ + public String getEncoded() throws IllegalStateException { + if (this.detailText == null) { + throw new IllegalStateException("no encoded form available"); + } + return this.detailText; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/package.html b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/package.html new file mode 100644 index 0000000..9db9284 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/ctx/package.html @@ -0,0 +1,8 @@ + + All of the classes that support the context schema are in this + package. The context schema contains the request and response formats, + and so there are classes to handle everything that goes into these + exchange formats. All of the classes in this package, and all the + related classes used by this package are parsable and encodable, so + it's easy to build a PEP and a PDP using these routines. + diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/debug/IndirectLocatable.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/debug/IndirectLocatable.java new file mode 100644 index 0000000..7db62d5 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/debug/IndirectLocatable.java @@ -0,0 +1,36 @@ +package com.sun.xacml.debug; + + +/** + * + * Some elements, i.e., mainly functions, are only referenced + * and do not have a separate java object for every referenced + * function. Thus, such functions are executed within a specific + * context which has to be set before they are called. + *
+ * Note:setting and unsetting the context (i.e., the + * SourceLocator of the encapsulating element) is NOT + * thread safe, thus, this feature should not be used when + * multiple evaluations are executed in parallel + * + * + * + */ +public interface IndirectLocatable extends Locatable { + + /** + * Sets the SourceLocator of the encapsulating element. This + * object should be retrieved from SourceLocator.getExpressionSourceLocator + * @param src + */ + void setRuntimeInfo(RuntimeInfo src); + + /** + * For the unset method, the same object should be used + * as for the set method. The unset is mainly done for detecting + * errors in the implementation. + * + * @param src + */ + void unsetRuntimeInfo(RuntimeInfo src); +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/debug/Locatable.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/debug/Locatable.java new file mode 100644 index 0000000..a4ed5e3 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/debug/Locatable.java @@ -0,0 +1,28 @@ +package com.sun.xacml.debug; + + +/** + * + * This interface is used for all elements which are locatable, + * i.e., elements which + *

    + *
  • have a representation in the source code of the policy, i.e., + * are constructed from a dom node
  • + *
  • should be traceable at runtime, i.e., before/after events can + * be subsribed at evaluation runtime
  • + *
+ * + * + */ +public interface Locatable { + + /** + * + * @return a valid RuntimeInfo or null, if no information is available, + * either, during the parsing of the policies the line tracking feature + * was not activated, or, the element does not have a representation within + * the source policy, e.g., it was retrieved from a AttributeDesignator from + * or is the result of a function. + */ + RuntimeInfo getRuntimeInfo(); +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/debug/RuntimeInfo.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/debug/RuntimeInfo.java new file mode 100644 index 0000000..90eb512 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/debug/RuntimeInfo.java @@ -0,0 +1,306 @@ +package com.sun.xacml.debug; + +import org.apache.log4j.Logger; +import org.w3c.dom.Node; + +import com.sun.xacml.Constants; + + +/** + * This class has two purposes: + *
    + *
  • Manage the information captured at PDP startup, i.e., the parsing + * information (for now: fileName and lineNumber; may change with + * new/other PolicyLoaders)
  • + *
  • Manage the call stack information at Runtime
  • + *
+ * + * + * At runtime, this class is responsible for managing the Runtime Information + * within the XACML Engine. This class itself is NOT able to capture all + * required information at runtime. Instead, it has to be called from the outside and + * provided with the required information. + *
+ * This may be implemented by external code, e.g., by using aspectJ, capturing + * all relevant events and provide the according information to + *
    + *
  • setCalledFrom(Object calledFrom), when an object is called, whereas + * calledFrom is the calling (XACML) object
  • + *
  • unsetCalledFrom(Object calledFrom), when a call returns, i.e., the + * evaluation is finished. This function is mainly to detect bugs in + * the implementation and may be removed in productive environments
  • + *
+ *
+ * To capture all required events, the following functions have to be monitored: + *
    + *
  • PolicyTreeElement.evaluate(EvaluationCtx), which includes + * Policy, PolicySet, PolicyReference, Rule
  • + *
  • Evaluatable.evaluate(EvaluationCtx), which includes AttributeDesignator, + * AttributeSelector, AttributeValue, VariableReference, Condition, Apply
  • + *
  • MatchElement.match(EvaluationCtx ), which includes Target, TargetMatch, + * TargetMatchGroup, TargetSection
  • + *
  • Function.evaluate(List, EvaluationCtx) which includes all + * Functions
  • + *
  • CombiningAlgorithm.combine(EvaluationCtx, List, List) + * which includes all Combing Algorithms
  • + *
+ * + * + * + */ +public class RuntimeInfo { + + /** + * line number, -1 if undefined + */ + private int lineNumber = -1; + /** + * File name, null if undefined + */ + private String fileName = null; + + /** + * Defines the element type this RuntimeInfo object is assigned to + */ + private ELEMENT_TYPE eleType; + + private boolean indirectLocateable = false; + + /** + * needed to create the call stack + */ + private RuntimeInfo calledFrom; + + /** + * + */ + private Locatable xacmlObject; + + private static Logger logger = Logger.getLogger(RuntimeInfo.class); + + public enum SOURCE_TYPE { + FILE + } + + public enum ELEMENT_TYPE { + POLICY_SET ("Policy Set"), //Locatable + POLICY ("Policy"), //Locatable + POLICY_REFERENCE ("Policy Reference"), //Locatable + TARGET ("Target"), //Locatable + TARGET_SECTION ("Target Section"), //Locatable + TARGET_MATCH_GROUP ("Target Match Group"), //Locatable + TARGET_MATCH ("Target Match"), //Locatable + RULE ("Rule"), //Locatable + ATTRIBUTE_VALUE ("Attribute Value"), //Locatable + ATTRIBUTE_DESIGNATOR ("Attribute Designator"), //Locatable + ATTRIBUTE_SELECTOR ("Attribtue Selector"), //Locatable + VARIABLE_REFERENCE ("Variable Reference"), //Locatable + VARIABLE_DEFINITION ("Variable Definition"), //Locatable + CONDITION ("Condition"), //Locatable + APPLY ("Apply"), //Locatable + FUNCTION ("Function"), //IndirectLocatable + COMBINING_ALG ("Combining Algorithm"), //IndirectLocatable + OBLIGATION ("Obligation"), //Locatable + COMBINER_PARAMETER ("Combiner Parameter"); //Locatable + //COMBINER_ELEMENT ("Cimbiner Element"); //Locatable + + + private String name; + + ELEMENT_TYPE(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + } + + protected RuntimeInfo(Locatable xacmlElement, Node node, ELEMENT_TYPE type) { + this.xacmlObject = xacmlElement; + Object tmp = node.getUserData(Constants.LINE_NUMBER); + if (tmp instanceof Integer ) { + lineNumber = ((Integer) tmp).intValue(); + } + + tmp = node.getUserData(Constants.SOURCE_FILE); + if ( tmp instanceof String ) { + fileName = (String) tmp; + } + this.eleType = type; + } + + /** + * returns the line number of the object within the + * XACML source file + * @return + */ + public int getLineNumber() { + return this.lineNumber; + } + + /** + * returns the source file name + * @return + */ + public String getFileName() { + return this.fileName; + } + + public ELEMENT_TYPE getElementType() { + return this.eleType; + } + + /** + * create a new Runtime Information object or null, if no source locations are available within + * the node + * @param node + * @return + */ + public static RuntimeInfo getRuntimeInfo(Node node, ELEMENT_TYPE type ) { + if ( node.getUserData(Constants.LINE_NUMBER) != null || + node.getUserData(Constants.SOURCE_FILE) != null ) { + return new RuntimeInfo(null, node, type); + } else { + return null; + } + } + + /** + * create a new Runtime Information object or null, if no source locations are available within + * the node + * @param node + * @return + */ + public static RuntimeInfo getRuntimeInfo(Locatable xacmlObject, Node node, ELEMENT_TYPE type ) { + if ( node.getUserData(Constants.LINE_NUMBER) != null || + node.getUserData(Constants.SOURCE_FILE) != null ) { + return new RuntimeInfo(xacmlObject, node, type); + } else { + return null; + } + } + + //public void setXACMLObject(Object xacmlObject) { + public void setXACMLObject(Locatable xacmlObject) { + this.xacmlObject = xacmlObject; + } + + + public Object getXACMLObject() { + return xacmlObject; + } + + private RuntimeInfo() { + //empty constructor + } + + /** + * This function provides a new SourceLocator object which is used to set and unset + * the SourceLocator objects of IndirectLoatable elements, (i.e., used as parameter + * for setSourceLocator and unsetSourceLocator methods). + *
+ * Note: it is mainly a copy constructor which sets the new element type, thus, allow + * to differentiate + * + * @param contextSrcLocator + * @return + */ + public RuntimeInfo getIndirectRuntimeInfo(IndirectLocatable xacmlObject, ELEMENT_TYPE type) { + RuntimeInfo src = new RuntimeInfo(); + src.fileName = this.fileName; + src.lineNumber = this.lineNumber; + src.indirectLocateable = true; + src.calledFrom = this; + src.xacmlObject = xacmlObject; + src.eleType = type; + return src; + } + + /** + * This function provides a new SourceLocator object with the same location + * information as it is based on. + *
This function should be used at parsing time and not at runtime, + * as the calledFrom information is not set (this is done at runtime). + * Currently, the only case where it is used is for XACML1.0 when an apply + * element is created to wrap a function defined by the FunctionId of the + * Condition element. + * @param xacmlObject + * @param type + * @return + */ + public RuntimeInfo getSourceLocator(Locatable xacmlObject, ELEMENT_TYPE type) { + RuntimeInfo src = new RuntimeInfo(); + src.fileName = this.fileName; + src.lineNumber = this.lineNumber; + src.xacmlObject = xacmlObject; + src.eleType = type; + return src; + } + + public boolean isIndirectLocateable() { + return indirectLocateable; + } + + public String getLocationMsgForError() { + return " near line " + ( lineNumber == -1 ? "unkown" : lineNumber ) + + " from file " + ( fileName == null ? "unkown" : fileName ); + //+ ( eleType == null ? "" : " (" + eleType.getName() + ")"); + } + + public String getLocationMsgShort() { + return " (line " + ( lineNumber == -1 ? "unkown" : lineNumber ) + + "@" + ( fileName == null ? "unkown" : fileName ) + ")"; + //+ ( eleType == null ? "" : " (" + eleType.getName() + ")"); + // + (this.calledFrom != null ? " from " + calledFrom.getClass().getSimpleName() : "") + } + + public String getLocationMsgRuntime() { + if ( calledFrom != null && calledFrom.xacmlObject != null ) { + return getLocationMsgShort() + + " called from " + calledFrom.xacmlObject.getClass().getSimpleName() + + ( calledFrom instanceof Locatable && ((Locatable) calledFrom).getRuntimeInfo() != null ? + ((Locatable) calledFrom).getRuntimeInfo().getLocationMsgShort() : "" ) ; + } else { + return getLocationMsgShort(); + } + } + + public String getElementDescr() { + return xacmlObject.getClass().getSimpleName() + getLocationMsgForError(); + } + + public void setCalledFrom(RuntimeInfo calledFrom) { + if ( indirectLocateable ) { + if ( calledFrom != this.calledFrom ) { + logger.warn("For indirect locateable RuntimeInfo objects, calledFrom provided to this" + + "function should be the same als already stored"); + } + } else if ( this.calledFrom != null ) { + logger.warn("Overwriting calledFrom object: " + this.calledFrom.getElementDescr() + " overwritten with " + calledFrom.getElementDescr()); + if (logger.isDebugEnabled()) { + try { + throw new RuntimeException("getStackTrace for Overwriting calledFrom object"); + } catch(RuntimeException e) { + e.printStackTrace(); + } + } + } + this.calledFrom = calledFrom; + } + + public void unsetCalledFrom(RuntimeInfo calledFrom) { + if ( this.calledFrom == null ) { + logger.warn("calledFrom is already unset!"); + } else if ( this.calledFrom != calledFrom) { + logger.warn("Unsetting different object (" + calledFrom.getClass().getSimpleName() + + ") than was set (" + this.calledFrom.getClass().getSimpleName() + ")!"); + } + this.calledFrom = null; + } + + public RuntimeInfo getCalledFrom() { + return calledFrom; + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/AttributeFinder.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/AttributeFinder.java new file mode 100644 index 0000000..afcd360 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/AttributeFinder.java @@ -0,0 +1,300 @@ + +/* + * @(#)AttributeFinder.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.finder; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.BagAttribute; + +import com.sun.xacml.cond.EvaluationResult; + +import java.net.URI; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Node; + + +/** + * This class is used by the PDP to find attribute values that weren't + * originally supplied in the request. It can be called with the data supplied + * in AttributeDesignators or AttributeSelectors. + * Because the modules in this finder may themselves need attribute data + * to search for attribute data, it's possible that the modules will look + * for values in the EvaluationCtx, which may in turn result + * in the invocation of this finder again, so module writers need to be + * careful about how they build their modules. + *

+ * Note that unlike the PolicyFinder, this class doesn't always need to + * use every module it has to find a value. The ordering is maintained, + * however, so it will always start with the first module, and proceed + * in order until it finds a value or runs out of modules. + * + * @since 1.0 + * @author Seth Proctor + * @author Ludwig Seitz + */ +public class AttributeFinder implements Cloneable +{ + + // the list of all modules + private List allModules; + + // + private List designatorModules; + + // + private List selectorModules; + + // the logger we'll use for all messages + private static final Logger logger = + Logger.getLogger(AttributeFinder.class.getName()); + + /** + * Default constructor. + */ + public AttributeFinder() { + this.allModules = new ArrayList(); + this.designatorModules = new ArrayList(); + this.selectorModules = new ArrayList(); + } + + + /** + * The clone method. + * FIXME: this does no deep copy on the Lists. + * + * @return a copy of this object. + */ + public Object clone() { + try { + AttributeFinder clone = (AttributeFinder)super.clone(); + clone.allModules = new ArrayList(this.allModules); + clone.designatorModules = new ArrayList(this.designatorModules); + clone.selectorModules = new ArrayList(this.selectorModules); + return clone; + } catch (CloneNotSupportedException e) {//this should never happen + throw new RuntimeException("Couldn't clone AttributeFinder"); + } + } + + /** + * copy constructor + * @param attrFinder + */ + protected AttributeFinder(AttributeFinder attrFinder) { + this.allModules = attrFinder.allModules; + this.designatorModules = attrFinder.designatorModules; + this.selectorModules = attrFinder.selectorModules; + } + + /** + * Returns the ordered List of + * AttributeFinderModules used by this class to find + * attribute values. + * + * @return a List of AttributeFinderModules + */ + public List getModules() { + return new ArrayList(this.allModules); + } + + /** + * Sets the ordered List of + * AttributeFinderModules used by this class to find + * attribute values. The ordering will be maintained. + * + * @param modules a List of + * AttributeFinderModules + */ + public void setModules(List modules) { + Iterator it = modules.iterator(); + + this.allModules = new ArrayList(modules); + this.designatorModules = new ArrayList(); + this.selectorModules = new ArrayList(); + + while (it.hasNext()) { + AttributeFinderModule module = it.next(); + + if (module.isDesignatorSupported()) { + this.designatorModules.add(module); + } + if (module.isSelectorSupported()) { + this.selectorModules.add(module); + } + } + } + + /** + * Sets only the designatorModules + * @param modules + */ + public void setDesignatorModules(List modules) { + + for ( AttributeFinderModule mod : modules) { + if ( mod.isDesignatorSupported() ) { + logger.warn(mod + " does not support designator selection!"); + } + } + + this.designatorModules = modules; + } + + /** + * Tries to find attribute values based on the given designator data. + * The result, if successful, will always contain a + * BagAttribute, even if only one value was found. If no + * values were found, but no other error occurred, an empty bag is + * returned. + * + * @param category the category of the attribute + * @param attributeType the datatype of the attributes to find or null + * @param attributeId the identifier of the attributes to find or null + * @param issuer the issuer of the attributes, or null if unspecified + * @param context the representation of the request data + * + * @return the result of attribute retrieval, which will be a bag of + * attributes or an error + */ + public EvaluationResult findAttribute(URI category, URI attributeType, + URI attributeId, URI issuer, + EvaluationCtx context) { + Iterator it = this.designatorModules.iterator(); + + // go through each module in order + while (it.hasNext()) { + AttributeFinderModule module = it.next(); + + // see if the module can find an attribute value + EvaluationResult result = + module.findAttribute(category, attributeType, attributeId, + issuer, context); + + // if there was an error, we stop right away + if (result.indeterminate()) { + if (logger.isInfoEnabled()) { + logger.info("Error while trying to resolve values: " + + result.getStatus().getMessage()); + } + + return result; + } + + // if the result wasn't empty, then return the result + BagAttribute bag = (BagAttribute)(result.getAttributeValue()); + if (! bag.isEmpty()) { + return result; + } + } + + // if we got here then there were no errors but there were also no + // matches, so we have to return an empty bag + if (logger.isDebugEnabled()) { + logger.debug("Failed to resolve any values for " + + attributeId.toString()); + + } + + return new EvaluationResult(BagAttribute. + createEmptyBag(attributeType)); + } + + /** + * Tries to find attribute values based on the given selector data. + * The result, if successful, must always contain a + * BagAttribute, even if only one value was found. If no + * values were found, but no other error occurred, an empty bag is + * returned. + * + * @param contextPath the XPath expression to search against + * @param namespaceNode the DOM node defining namespace mappings to use, + * or null if mappings come from the context root + * @param attributeType the datatype of the attributes to find + * @param context the representation of the request data + * @param xpathVersion the XPath version to use + * + * @return the result of attribute retrieval, which will be a bag of + * attributes or an error + */ + public EvaluationResult findAttribute(String contextPath, + Node namespaceNode, + URI attributeType, + EvaluationCtx context, + String xpathVersion) { + Iterator it = this.selectorModules.iterator(); + + // go through each module in order + while (it.hasNext()) { + AttributeFinderModule module = it.next(); + + // see if the module can find an attribute value + EvaluationResult result = + module.findAttribute(contextPath, namespaceNode, attributeType, + context, xpathVersion); + + // if there was an error, we stop right away + if (result.indeterminate()) { + if (logger.isInfoEnabled()) { + logger.info("Error while trying to resolve values: " + + result.getStatus().getMessage()); + } + return result; + } + + // if the result wasn't empty, then return the result + BagAttribute bag = (BagAttribute)(result.getAttributeValue()); + if (! bag.isEmpty()) { + return result; + } + } + + // if we got here then there were no errors but there were also no + // matches, so we have to return an empty bag + if (logger.isInfoEnabled()) { + logger.info("Failed to resolve any values for " + contextPath); + } + + return new EvaluationResult(BagAttribute. + createEmptyBag(attributeType)); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/AttributeFinderModule.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/AttributeFinderModule.java new file mode 100644 index 0000000..4e3ab5b --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/AttributeFinderModule.java @@ -0,0 +1,201 @@ + +/* + * @(#)AttributeFinderModule.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.finder; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.BagAttribute; + +import com.sun.xacml.cond.EvaluationResult; +import java.net.URI; + +import java.util.Set; + +import org.w3c.dom.Node; + + +/** + * This is the abstract class that all AttributeFinder modules + * extend. All methods have default values to represent that the given + * feature isn't supported by this module, so module writers needs only + * implement the methods for the features they're supporting. + * + * @since 1.0 + * @author Seth Proctor + * @author Ludwig Seitz + */ +public abstract class AttributeFinderModule +{ + + /** + * Returns this module's identifier. A module does not need to provide + * a unique identifier, but it is a good idea, especially in support of + * management software. Common identifiers would be the full package + * and class name (the default if this method isn't overridden), just the + * class name, or some other well-known string that identifies this class. + * + * @return this module's identifier + */ + public String getIdentifier() { + return getClass().getName(); + } + + /** + * Returns true if this module supports retrieving attributes based on the + * data provided in an AttributeDesignatorType. By default this method + * returns false. + * + * @return true if retrieval based on designator data is supported + */ + public boolean isDesignatorSupported() { + return false; + } + + /** + * Returns true if this module supports retrieving attributes based on the + * data provided in an AttributeSelectorType. By default this method + * returns false. + * + * @return true if retrieval based on selector data is supported + */ + public boolean isSelectorSupported() { + return false; + } + + /** + * Returns a Set of Integers that represent + * which AttributeDesignator types are supported (eg, Subject, Resource, + * etc.), or null meaning that no particular types are supported. A + * return value of null can mean that this module doesn't support + * designator retrieval, or that it supports designators of all types. + * If the set is non-null, it should contain the values specified in + * the AttributeDesignator *_TARGET fields. + * + * @return a Set of Integers, or null + */ + public Set getSupportedDesignatorTypes() { + return null; + } + + /** + * Returns a Set of URIs that represent the + * attributeIds handled by this module, or null if this module doesn't + * handle any specific attributeIds. A return value of null means that + * this module will try to resolve attributes of any id. + * + * @return a Set of URIs, or null + */ + public Set getSupportedIds() { + return null; + } + + /** + * This is an experimental method that asks the module to invalidate any + * cache values it may contain. This is not used by any of the core + * processing code, but it may be used by management software that wants + * to have some control over these modules. Since a module is free to + * decide how or if it caches values, and whether it is capable of + * updating values once in a cache, a module is free to intrepret this + * message in any way it sees fit (including igoring the message). It + * is preferable, however, for a module to make every effort to clear + * any dynamically cached values it contains. + *

+ * This method has been introduced to see what people think of this + * functionality, and how they would like to use it. It may be removed + * in future versions, or it may be changed to a more general + * message-passing system (if other useful messages are identified). + * + * @since 1.2 + */ + public void invalidateCache() { + //not defined yet, for future extensions + } + + /** + * Tries to find attribute values based on the given designator data. + * The result, if successful, must always contain a + * BagAttribute, even if only one value was found. If no + * values were found, but no other error occurred, an empty bag is + * returned. This method may need to invoke the context data to look + * for other attribute values, so a module writer must take care not + * to create a scenario that loops forever. + * + * @param category the category of the attribute + * @param attributeType the datatype of the attributes to find + * @param attributeId the identifier of the attributes to find + * @param issuer the issuer of the attributes, or null if unspecified + * @param context the representation of the request data + * + * @return the result of attribute retrieval, which will be a bag of + * attributes or an error + */ + public EvaluationResult findAttribute(URI category, URI attributeType, + URI attributeId, URI issuer, + EvaluationCtx context) { + return new EvaluationResult(BagAttribute. + createEmptyBag(attributeType)); + } + + /** + * Tries to find attribute values based on the given selector data. + * The result, if successful, must always contain a + * BagAttribute, even if only one value was found. If no + * values were found, but no other error occurred, an empty bag is + * returned. This method may need to invoke the context data to look + * for other attribute values, so a module writer must take care not + * to create a scenario that loops forever. + * + * @param contextPath the XPath expression to search against + * @param namespaceNode the DOM node defining namespace mappings to use, + * or null if mappings come from the context root + * @param attributeType the datatype of the attributes to find + * @param context the representation of the request data + * @param xpathVersion the XPath version to use + * + * @return the result of attribute retrieval, which will be a bag of + * attributes or an error + */ + public EvaluationResult findAttribute(String contextPath, + Node namespaceNode, + URI attributeType, + EvaluationCtx context, + String xpathVersion) { + return new EvaluationResult(BagAttribute. + createEmptyBag(attributeType)); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/PolicyFinder.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/PolicyFinder.java new file mode 100644 index 0000000..4d7c1c8 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/PolicyFinder.java @@ -0,0 +1,314 @@ + +/* + * @(#)PolicyFinder.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.finder; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.PDPConfig; +import com.sun.xacml.PolicyMetaData; +import com.sun.xacml.PolicyReference; +import com.sun.xacml.VersionConstraints; + +import com.sun.xacml.ctx.Status; + +import java.net.URI; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.apache.log4j.Logger; + +/** + * This class is used by the PDP to find all policies used in evaluation. A + * PDP is given a pre-configured PolicyFinder on construction. + * The PolicyFinder provides the functionality both to find + * policies based on a request (ie, retrieve policies and match against the + * target) and based on an idReference (as can be included in a PolicySet). + *

+ * While this class is typically used by the PDP, it is intentionally + * designed to support stand-alone use, so it could be the base for a + * distributed service, or for some application that needs just this + * functionality. There is nothing in the PolicyFinder + * Note that it is an error to have more than one top-level policy (as + * explained in the OnlyOneApplicable combining algorithm), so any module + * that is added to this finder will be evaluated each time a policy is + * requested. This means that you should think carefully about how many + * modules you include, and how they can cache policy data. + * + * @since 1.0 + * @author Seth Proctor + */ +public class PolicyFinder +{ + + private PDPConfig config; + + // all modules in this finder + private Set allModules = new HashSet(); + + // all the request modules + private Set requestModules = new HashSet(); + + // all the reference modules + private Set referenceModules = new HashSet(); + + // the logger we'll use for all messages + private static final Logger logger = + Logger.getLogger(PolicyFinder.class.getName()); + + /** + * Returns the unordered Set of + * PolicyFinderModules used by this class to find policies. + * + * @return a Set of PolicyFinderModules + */ + public Set getModules() { + return new HashSet(this.allModules); + } + + + /** + * Sets the unordered Set of PolicyFinderModules + * used by this class to find policies. + * + * @param modules a Set of PolicyFinderModules + */ + public void setModules(Set modules) { + Iterator it = modules.iterator(); + + this.allModules = new HashSet(modules); + this.requestModules = new HashSet(); + this.referenceModules = new HashSet(); + + while (it.hasNext()) { + storeModule( (PolicyFinderModule)(it.next())); + } + } + + /** + * private helper function, whichs stores modules to + * the correct internal store. + * @param module + */ + private void storeModule(PolicyFinderModule module) { + if (module.isRequestSupported()) { + this.requestModules.add(module); + } + if (module.isIdReferenceSupported()) { + this.referenceModules.add(module); + } + } + + /** + * adds a new PolicyFinderModule to the existing ones (at runtime) + * @param policyFinder + */ + public void addPolicyFinderModule(PolicyFinderModule policyFinder) { + this.allModules.add(policyFinder); + storeModule(policyFinder); + policyFinder.init(this); + } + + /** + * Initializes all modules in this finder. + */ + public void init(PDPConfig config) { + logger.debug("Initializing PolicyFinder"); + + this.config = config; + + Iterator it = this.allModules.iterator(); + + while (it.hasNext()) { + PolicyFinderModule module = it.next(); + module.init(this); + } + } + + + + /** + * Finds a policy based on a request's context. This may involve using + * the request data as indexing data to lookup a policy. This will always + * do a Target match to make sure that the given policy applies. If more + * than one applicable policy is found, this will return an error. + * + * @param context the representation of the request data + * + * @return the result of trying to find an applicable policy + */ + public PolicyFinderResult findPolicy(EvaluationCtx context) { + PolicyFinderResult result = null; + Iterator it = this.requestModules.iterator(); + + // look through all of the modules + while (it.hasNext()) { + PolicyFinderModule module = it.next(); + PolicyFinderResult newResult = module.findPolicy(context); + + // if there was an error, we stop right away + if (newResult.indeterminate()) { + if (logger.isInfoEnabled()) { + logger.info("An error occured while trying to find a " + + "single applicable policy for a request: " + + newResult.getStatus().getMessage()); + } + + return newResult; + } + + // if we found a policy... + if (! newResult.notApplicable()) { + // ...if we already had found a policy, this is an error... + if (result != null) { + logger.info("More than one top-level applicable policy " + + "for the request"); + + ArrayList code = new ArrayList(); + code.add(Status.STATUS_PROCESSING_ERROR); + Status status = new Status(code, "too many applicable " + + "top-level policies"); + return new PolicyFinderResult(status); + } + + // ...otherwise we remember the result + result = newResult; + } + } + + // if we got here then we didn't have any errors, so the only + // question is whether or not we found anything + if (result != null) { + return result; + } + +// logger.info("No applicable policies were found for the request"); + return new PolicyFinderResult(); + } + + /** + * Finds a policy based on an id reference. This may involve using + * the reference as indexing data to lookup a policy. This will always + * do a Target match to make sure that the given policy applies. If more + * than one applicable policy is found, this will return an error. + * + * @param idReference the identifier used to resolve a policy + * @param type type of reference (policy or policySet) as identified by + * the fields in PolicyReference + * @param constraints any optional constraints on the version of the + * referenced policy + * @param parentMetaData the meta-data from the parent policy, which + * provides XACML version, factories, etc. + * + * @return the result of trying to find an applicable policy + * + * @throws IllegalArgumentException if type is invalid + */ + public PolicyFinderResult findPolicy(EvaluationCtx context, URI idReference, int type, + VersionConstraints constraints, + PolicyMetaData parentMetaData) + throws IllegalArgumentException + { + PolicyFinderResult result = null; + Iterator it = this.referenceModules.iterator(); + + if ((type != PolicyReference.POLICY_REFERENCE) && + (type != PolicyReference.POLICYSET_REFERENCE)) { + throw new IllegalArgumentException("Unknown reference type"); + } + // look through all of the modules + while (it.hasNext()) { + PolicyFinderModule module = it.next(); + PolicyFinderResult newResult = + module.findPolicy(context, idReference, type, constraints, + parentMetaData); + + // if there was an error, we stop right away + if (newResult.indeterminate()) { + if (logger.isInfoEnabled()) { + logger.info("An error occured while trying to find the " + + "referenced policy " + idReference.toString() + + ": " + newResult.getStatus().getMessage()); + } + return newResult; + } + + // if we found a policy... + if (! newResult.notApplicable()) { + // ...if we already had found a policy, this is an error... + if (result != null) { + if (logger.isInfoEnabled()) { + logger.info("More than one policy applies for the " + + "reference: " + idReference.toString()); + } + ArrayList code = new ArrayList(); + code.add(Status.STATUS_PROCESSING_ERROR); + Status status = new Status(code, "too many applicable " + + "top-level policies"); + return new PolicyFinderResult(status); + } + + // ...otherwise we remember the result + result = newResult; + } + } + + // if we got here then we didn't have any errors, so the only + // question is whether or not we found anything + if (result != null) { + return result; + } + + if (logger.isInfoEnabled()) { + logger.info("No policies were resolved for the reference: " + + idReference.toString()); + } + return new PolicyFinderResult(); + } + + public PDPConfig getPDPConfiguration() { + return this.config; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/PolicyFinderModule.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/PolicyFinderModule.java new file mode 100644 index 0000000..4952f96 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/PolicyFinderModule.java @@ -0,0 +1,169 @@ + +/* + * @(#)PolicyFinderModule.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.finder; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.PolicyMetaData; +import com.sun.xacml.VersionConstraints; + +import java.net.URI; + + +/** + * This is the abstract class that all PolicyFinder modules + * extend. All methods have default values to represent that the given + * feature isn't supported by this module, so module writers needs only + * implement the methods for the features they're supporting. + * + * @since 1.0 + * @author Seth Proctor + */ +public abstract class PolicyFinderModule +{ + + /** + * Returns this module's identifier. A module does not need to provide + * a unique identifier, but it is a good idea, especially in support of + * management software. Common identifiers would be the full package + * and class name (the default if this method isn't overridden), just the + * class name, or some other well-known string that identifies this class. + * + * @return this module's identifier + */ + public String getIdentifier() { + return getClass().getName(); + } + + /** + * Returns true if the module supports finding policies based on a + * request (ie, target matching). By default this method returns false. + * + * @return true if request retrieval is supported + */ + public boolean isRequestSupported() { + return false; + } + + /** + * Returns true if the module supports finding policies based on an + * id reference (in a PolicySet). By default this method returns false. + * + * @return true if idReference retrieval is supported + */ + public boolean isIdReferenceSupported() { + return false; + } + + /** + * Initializes this module for use by the given finder. Typically this + * is called when a PDP is initialized with a + * PDPConfig containing the given PolicyFinder. + * Because PolicyFinderModules usually need to parse + * policies, and this requires knowing their PolicyFinder, + * parsing is usually done at or after this point in the lifetime + * of this module. This might also be a good time to reset any internal + * caches or temporary data. Note that this method may be called more + * than once in the lifetime of a module. + * + * @param finder the PolicyFinder using this module + */ + public abstract void init(PolicyFinder finder); + + /** + * This is an experimental method that asks the module to invalidate any + * cache values it may contain. This is not used by any of the core + * processing code, but it may be used by management software that wants + * to have some control over these modules. Since a module is free to + * decide how or if it caches values, and whether it is capable of + * updating values once in a cache, a module is free to intrepret this + * message in any way it sees fit (including igoring the message). It + * is preferable, however, for a module to make every effort to clear + * any dynamically cached values it contains. + *

+ * This method has been introduced to see what people think of this + * functionality, and how they would like to use it. It may be removed + * in future versions, or it may be changed to a more general + * message-passing system (if other useful messages are identified). + * + * @since 1.2 + */ + public void invalidateCache() { + //not defined yet, for future extensions + } + + /** + * Tries to find one and only one matching policy given the request + * represented by the context data. If more than one policy is found, + * this is an error and must be reported as such. If no policies are + * found, then an empty result must be returned. By default this + * method returns an empty result. This method should never return null. + * + * @param context the representation of the request + * + * @return the result of looking for a matching policy + */ + public PolicyFinderResult findPolicy(EvaluationCtx context) { + return new PolicyFinderResult(); + } + + /** + * Tries to find one and only one matching policy given the idReference + * If more than one policy is found, this is an error and must be reported + * as such. If no policies are found, then an empty result must be + * returned. By default this method returns an empty result. This method + * should never return null. + * + * @param idReference an identifier specifying some policy + * @param type type of reference (policy or policySet) as identified by + * the fields in PolicyReference + * @param constraints any optional constraints on the version of the + * referenced policy (this will never be null, but + * it may impose no constraints, and in fact will + * never impose constraints when used from a pre-2.0 + * XACML policy) + * @param parentMetaData the meta-data from the parent policy, which + * provides XACML version, factories, etc. + * + * @return the result of looking for a matching policy + */ + public PolicyFinderResult findPolicy(EvaluationCtx context, URI idReference, int type, + VersionConstraints constraints, + PolicyMetaData parentMetaData) { + return new PolicyFinderResult(); + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/PolicyFinderResult.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/PolicyFinderResult.java new file mode 100644 index 0000000..dcc9698 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/PolicyFinderResult.java @@ -0,0 +1,130 @@ + +/* + * @(#)PolicyFinderResult.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.finder; + +import com.sun.xacml.AbstractPolicy; + +import com.sun.xacml.ctx.Status; + + +/** + * This is used as the return value for the findPolicy() methods in the + * PolicyFinder. It communicates either a found policy that + * applied to the request (eg, the target matches), an Indeterminate state, + * or no applicable policies. + *

+ * The OnlyOneApplicable combining logic is used in looking for a policy, + * so the result from calling findPolicy can never be more than one policy. + * + * @since 1.0 + * @author Seth Proctor + */ +public class PolicyFinderResult +{ + + // the single policy being returned + private AbstractPolicy policy; + + // status that represents an error occurred + private Status status; + + /** + * Creates a result saying that no applicable policies were found. + */ + public PolicyFinderResult() { + this.policy = null; + this.status = null; + } + + /** + * Creates a result containing a single applicable policy. + * + * @param policy the applicable policy + */ + public PolicyFinderResult(AbstractPolicy policy) { + this.policy = policy; + this.status = null; + } + + /** + * Create a result of Indeterminate, including Status data. + * + * @param status the error information + */ + public PolicyFinderResult(Status status) { + this.policy = null; + this.status = status; + } + + /** + * Returns true if the result was NotApplicable. + * + * @return true if the result was NotApplicable + */ + public boolean notApplicable() { + return ((this.policy == null) && (this.status == null)); + } + + /** + * Returns true if the result was Indeterminate. + * + * @return true if there was an error + */ + public boolean indeterminate() { + return (this.status != null); + } + + /** + * Returns the found policy, or null if there was an error or no policy + * was found. + * + * @return the applicable policy or null + */ + public AbstractPolicy getPolicy() { + return this.policy; + } + + /** + * 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; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/RequiredAttributesModule.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/RequiredAttributesModule.java new file mode 100644 index 0000000..547e9f8 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/RequiredAttributesModule.java @@ -0,0 +1,13 @@ +package com.sun.xacml.finder; + +import java.util.Set; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.attr.AttributeDesignator; +import com.sun.xacml.ctx.Attribute; + +public abstract class RequiredAttributesModule { + + public abstract Set resolveRequiredAttributes(EvaluationCtx context, AttributeDesignator attrDesignator); + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/ResourceFinder.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/ResourceFinder.java new file mode 100644 index 0000000..7243d1a --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/ResourceFinder.java @@ -0,0 +1,301 @@ + +/* + * @(#)ResourceFinder.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.finder; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AttributeValue; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import org.apache.log4j.Logger; + + +/** + * This class is used by the PDP to handle resource scopes other than + * Immediate. In the case of a scope of Children, Descendants, + * XPath-expression or EntireHierarchy the PDP needs a list of Resource Ids + * to evaluate, each of which will get its own Result. Like the PolicyFinder, + * this is not tied in any way to the rest of the PDP code, and could be + * provided as a stand-alone resource. + *

+ * This class basically is a coordinator that asks each module in turn + * if it can handle the given identifier. Evaluation proceeds in order through + * the given modules, and once a module returns a non-empty response (whether + * or not it contains any errors or only errors), the evaluation is + * finished and the result is returned. One of the issues here is ordering, + * since a given resource may look to several modules like something that + * they can handle. So, you must be careful when assigning to ordering of + * the modules in this finder. + *

+ * + * @since 1.0 + * @author Seth Proctor + */ +public class ResourceFinder +{ + + /** + * the list of all modules + */ + private List allModules; + + /** + * the list of child modules + */ + private List childModules; + + /** + * the list of descendant modules + */ + private List descendantModules; + + /** + * the list of xpath modules + */ + private List xpathModules; + + /** + * the list of hierarchy modules + */ + private List hierarchyModules; + + // the logger we'll use for all messages + private static final Logger logger = + Logger.getLogger(ResourceFinder.class.getName()); + + /** + * Default constructor. + */ + public ResourceFinder() { + this.allModules = new ArrayList(); + this.childModules = new ArrayList(); + this.descendantModules = new ArrayList(); + this.xpathModules = new ArrayList(); + this.hierarchyModules = new ArrayList(); + } + + /** + * Returns the ordered List of + * ResourceFinderModules used by this class to find resources. + * + * @return a List of ResourceFinderModules + */ + public List getModules() { + return new ArrayList(this.allModules); + } + + /** + * Sets the ordered List of ResourceFinderModules + * used by this class to find resources. The ordering will be maintained. + * + * @param modules a code>List of ResourceFinderModules + */ + public void setModules(List modules) { + Iterator it = modules.iterator(); + + this.allModules = new ArrayList(modules); + this.childModules = new ArrayList(); + this.descendantModules = new ArrayList(); + + while (it.hasNext()) { + ResourceFinderModule module = it.next(); + + if (module.isChildSupported()) { + this.childModules.add(module); + } + if (module.isDescendantSupported()) { + this.descendantModules.add(module); + } + if (module.isXPathSupported()) { + this.xpathModules.add(module); + } + if (module.isHierarchySupported()) { + this.hierarchyModules.add(module); + } + } + } + + /** + * Finds Resource Ids using the Children scope, and returns all resolved + * identifiers as well as any errors that occurred. If no modules can + * handle the given Resource Id, then an empty result is returned. + * + * @param parentResourceId the root of the resources + * @param context the representation of the request data + * + * @return the result of looking for child resources + */ + public ResourceFinderResult findChildResources(AttributeValue + parentResourceId, + EvaluationCtx context) { + Iterator it = this.childModules.iterator(); + + while (it.hasNext()) { + ResourceFinderModule module = it.next(); + + // ask the module to find the resources + ResourceFinderResult result = + module.findChildResources(parentResourceId, context); + + // if we found something, then always return that result + if (! result.isEmpty()) { + return result; + } + } + + // no modules applied, so we return an empty result + if (logger.isInfoEnabled()) { + logger.info("No ResourceFinderModule existed to handle the " + + "children of " + parentResourceId.encode()); + } + + return new ResourceFinderResult(); + } + + /** + * Finds Resource Ids using the Descendants scope, and returns all resolved + * identifiers as well as any errors that occurred. If no modules can + * handle the given Resource Id, then an empty result is returned. + * + * @param parentResourceId the root of the resources + * @param context the representation of the request data + * + * @return the result of looking for descendant resources + */ + public ResourceFinderResult findDescendantResources(AttributeValue + parentResourceId, + EvaluationCtx + context) { + Iterator it = this.descendantModules.iterator(); + + while (it.hasNext()) { + ResourceFinderModule module = it.next(); + + // ask the module to find the resources + ResourceFinderResult result = + module.findDescendantResources(parentResourceId, context); + + // if we found something, then always return that result + if (! result.isEmpty()) { + return result; + } + } + + // no modules applied, so we return an empty result + if (logger.isInfoEnabled()) { + logger.info("No ResourceFinderModule existed to handle the " + + "descendants of " + parentResourceId.encode()); + } + return new ResourceFinderResult(); + } + + /** + * Finds Resource Ids using an XPath expression on the Content with the + * "urn:oasis:names:tc:xacml:3.0:attribute-category:resource" category + * and returns all matching nodes as identifiers as well as any errors + * that occurred. If no modules can handle the given Resource Id, then + * an empty result is returned. + * + * @param xpathResourceId the root of the resources + * @param context the representation of the request data + * + * @return the result of looking for descendant resources + */ + public ResourceFinderResult findXPathResources( + AttributeValue xpathResourceId, EvaluationCtx context) { + Iterator it = this.xpathModules.iterator(); + + while (it.hasNext()) { + ResourceFinderModule module = it.next(); + + // ask the module to find the resources + ResourceFinderResult result = + module.findXPathResources(xpathResourceId, context); + + // if we found something, then always return that result + if (! result.isEmpty()) { + return result; + } + } + + // no modules returned results, so we return an empty result + if (logger.isInfoEnabled()) { + logger.info("No ResourceFinderModule returned results for the " + + "xpath " + xpathResourceId.encode()); + } + return new ResourceFinderResult(); + } + + /** + * Finds Resource Ids using the EntireHierarchy scope and returns all + * matching nodes as identifiers as well as any errors that occurred. + * If no modules can handle the given Resource Id, then an empty result + * is returned. + * + * @param parentResourceId the root of the resources + * @param context the representation of the request data + * + * @return the result of looking for descendant resources + */ + public ResourceFinderResult findHierarchyResources( + AttributeValue parentResourceId, EvaluationCtx context) { + Iterator it = this.hierarchyModules.iterator(); + + while (it.hasNext()) { + ResourceFinderModule module = it.next(); + + // ask the module to find the resources + ResourceFinderResult result = + module.findHierarchicyResources(parentResourceId, context); + + // if we found something, then always return that result + if (! result.isEmpty()) { + return result; + } + } + + // no modules applied, so we return an empty result + if (logger.isInfoEnabled()) { + logger.info("No ResourceFinderModule existed to handle the " + + "hierarchy of " + parentResourceId.encode()); + } + return new ResourceFinderResult(); + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/ResourceFinderModule.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/ResourceFinderModule.java new file mode 100644 index 0000000..4095434 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/ResourceFinderModule.java @@ -0,0 +1,200 @@ + +/* + * @(#)ResourceFinderModule.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.finder; + +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AttributeValue; + + +/** + * This is the abstract class that all ResourceFinder modules + * extend. All methods have default values to represent that the given + * feature isn't supported by this module, so module writers needs only + * implement the methods for the features they're supporting. + * + * @since 1.0 + * @author Seth Proctor + */ +public abstract class ResourceFinderModule +{ + + /** + * Returns this module's identifier. A module does not need to provide + * a unique identifier, but it is a good idea, especially in support of + * management software. Common identifiers would be the full package + * and class name (the default if this method isn't overridden), just the + * class name, or some other well-known string that identifies this class. + * + * @return this module's identifier + */ + public String getIdentifier() { + return getClass().getName(); + } + + /** + * Returns true if this module supports finding resources with the + * "Children" scope. By default this method returns false. + * + * @return true if the module supports the Children scope + */ + public boolean isChildSupported() { + return false; + } + + /** + * Returns true if this module supports finding resources with the + * "Descendants" scope. By default this method returns false. + * + * @return true if the module supports the Descendants scope + */ + public boolean isDescendantSupported() { + return false; + } + + /** + * Returns true if this module supports finding resources with the + * "XPath-expression" scope. By default this method returns false. + * + * @return true if the module supports the XPath-expression scope + */ + public boolean isXPathSupported() { + return false; + } + + /** + * Returns true if this module supports finding resources with the + * "EntireHierarchy" scope. By default this method returns false. + * + * @return true if the module supports the EntireHierarchy scope + */ + public boolean isHierarchySupported() { + return false; + } + + /** + * This is an experimental method that asks the module to invalidate any + * cache values it may contain. This is not used by any of the core + * processing code, but it may be used by management software that wants + * to have some control over these modules. Since a module is free to + * decide how or if it caches values, and whether it is capable of + * updating values once in a cache, a module is free to intrepret this + * message in any way it sees fit (including igoring the message). It + * is preferable, however, for a module to make every effort to clear + * any dynamically cached values it contains. + *

+ * This method has been introduced to see what people think of this + * functionality, and how they would like to use it. It may be removed + * in future versions, or it may be changed to a more general + * message-passing system (if other useful messages are identified). + * + * @since 1.2 + */ + public void invalidateCache() { + //not defined yet, for future extensions + } + + /** + * Tries to find the child Resource Ids associated with the parent. If + * this module cannot handle the given identifier, then an empty result is + * returned, otherwise the result will always contain at least the + * parent Resource Id, either as a successfully resolved Resource Id or an + * error case, but never both. + * + * @param parentResourceId the parent resource identifier + * @param context the representation of the request data + * + * @return the result of finding child resources + */ + public ResourceFinderResult findChildResources(AttributeValue + parentResourceId, + EvaluationCtx context) { + return new ResourceFinderResult(); + } + + /** + * Tries to find the descendant Resource Ids associated with the parent. If + * this module cannot handle the given identifier, then an empty result is + * returned, otherwise the result will always contain at least the + * parent Resource Id, either as a successfuly resolved Resource Id or an + * error case, but never both. + * + * @param parentResourceId the parent resource identifier + * @param context the representation of the request data + * + * @return the result of finding descendant resources + */ + public ResourceFinderResult findDescendantResources(AttributeValue + parentResourceId, + EvaluationCtx + context) { + return new ResourceFinderResult(); + } + + /** + * Tries to find the Resource Ids identified by an XPath. If + * this module cannot handle the given identifier, then an empty result is + * returned, otherwise the result will contain the result of applying this + * XPath to the Content with id="Resource". This may be an empty result. + * + * @param xpathResourceId the parent resource identifier + * @param context the representation of the request data + * + * @return the result of finding descendant resources + */ + public ResourceFinderResult findXPathResources( + AttributeValue xpathResourceId, EvaluationCtx context) { + return new ResourceFinderResult(); + } + + /** + * Tries to find the hierarchy of Resource Ids associated with the parent. + * If this module cannot handle the given identifier, then an empty result + * is returned, otherwise the result will always contain at least the + * parent Resource Id, either as a successfuly resolved Resource Id or an + * error case, but never both. + * + * @param parentResourceId the parent resource identifier + * @param context the representation of the request data + * + * @return the result of finding descendant resources + */ + public ResourceFinderResult findHierarchicyResources( + AttributeValue parentResourceId, EvaluationCtx context) { + return new ResourceFinderResult(); + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/ResourceFinderResult.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/ResourceFinderResult.java new file mode 100644 index 0000000..43a4f82 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/ResourceFinderResult.java @@ -0,0 +1,159 @@ + +/* + * @(#)ResourceFinderResult.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.finder; + +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.ctx.Status; + + +/** + * This is used to return Resource Ids from the ResourceFinder. Unlike the + * PolicyFinder, this never returns an empty set, since it will always + * contain at least the original parent resource. This class will provide + * two sets of identifiers: those that were successfully resolved and those + * that had an error. + * + * @since 1.0 + * @author Seth Proctor + */ +public class ResourceFinderResult +{ + + // the set of resource identifiers + private Set resources; + + // the map of failed identifiers to their failure status data + private Map failures; + + // a flag specifying whether or not result contains resource listings + private boolean empty; + + /** + * Creates an empty result. + */ + public ResourceFinderResult() { + this.resources = Collections.unmodifiableSet(new HashSet()); + this.failures = Collections.unmodifiableMap(new HashMap()); + this.empty = true; + } + + /** + * Creates a result containing the given Set of resource + * identifiers. The Setmust not be null. The new + * ResourceFinderResult represents a resource retrieval that + * encountered no errors. + * + * @param resources a non-null Set of + * AttributeValues + */ + public ResourceFinderResult(Set resources) { + this(resources, new HashMap()); + } + + /** + * Creates a result containing only Resource Ids that caused errors. The + * Map must not be null. The keys in the Map + * are AttributeValues identifying the resources that could + * not be resolved, and they map to a Status object + * explaining the error. The new ResourceFinderResult + * represents a resource retrieval that did not succeed in finding any + * resource identifiers. + * + * @param failures a non-null Map mapping failed + * AttributeValue identifiers to their + * Status + */ + public ResourceFinderResult(HashMap failures) { + this(new HashSet(), failures); + } + + /** + * Creates a new result containing both successfully resolved Resource Ids + * and resources that caused errors. + * + * @param resources a non-null Set of + * AttributeValues + * @param failures a non-null Map mapping failed + * AttributeValue identifiers to their + * Status + */ + public ResourceFinderResult(Set resources, Map failures) { + this.resources = Collections.unmodifiableSet(new HashSet(resources)); + this.failures = Collections.unmodifiableMap(new HashMap(failures)); + this.empty = false; + } + + /** + * Returns whether or not this result contains any Resource Id listings. + * This will return false if either the set of successfully resolved + * resource identifiers or the map of failed resources is not empty. + * + * @return false if this result names any resources, otherwise true + */ + public boolean isEmpty() { + return this.empty; + } + + /** + * Returns the Set of successfully resolved Resource Id + * AttributeValues, which will be empty if no resources + * were successfully resolved. + * + * @return a Set of AttributeValues + */ + public Set getResources() { + return this.resources; + } + + /** + * Returns the Map of Resource Ids that caused an error on + * resolution, which will be empty if no resources caused any error. + * + * @return a Map of AttributeValues to + * Status + */ + public Map getFailures() { + return this.failures; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/RevocationFinder.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/RevocationFinder.java new file mode 100644 index 0000000..3b47a23 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/RevocationFinder.java @@ -0,0 +1,136 @@ + +/* + * @(#)RevocationFinder.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.finder; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.EvaluationCtx; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * This class is used by the PDP to find revocations of policies + * + * @since 3.0 + * @author Ludwig Seitz + */ +public class RevocationFinder implements Cloneable { + + // the list of all modules + private List allModules = null; + + /** + * Default constructor. + */ + public RevocationFinder() { + this.allModules = new ArrayList(); + } + + /** + * The clone method. + * + * @return a copy of this object + */ + public Object clone() { + try { + RevocationFinder clone = (RevocationFinder)super.clone(); + clone.allModules = new ArrayList(this.allModules); + return clone; + } catch (CloneNotSupportedException e) {//this should never happen + throw new RuntimeException("Couldn't clone RevocationFinder"); + } + } + + /** + * Returns the ordered List of modules used by this class + * to find policy revocations + * + * @return the list of modules used by this class + */ + public List getModules() { + return new ArrayList(this.allModules); + } + + /** + * Sets the ordered List of modules used by this class + * to find attribute values. The ordering will be maintained. + * + * @param modules the modules this class will use + */ + public void setModules(List modules) { + this.allModules = new ArrayList(modules); + } + + /** + * Checks whether a policy supports the revocation of a candidate policy. + * + * @param policy The policy that may support a revocation + * @param candidate The id of the policy or policy set that is candidate + * for revocation. + * @param context the context in which this policy may support revocations + * + * @return true if this policy supports a the revocation of the candidate, + * false otherwise. + */ + public boolean supportsRevocation(AbstractPolicy policy, URI candidate, + EvaluationCtx context) { + if (this.allModules != null) { + Iterator it = this.allModules.iterator(); + + // go through each module in order + while (it.hasNext()) { + RevocationFinderModule module = it.next(); + + // see if the module can find a revocation + boolean result = module.supportsRevocation(policy, + candidate, + context); + + if (result == true) { + // we found a revocation + return true; + } + } + } + // we found no revocation or there is no revocation finder module + return false; + + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/RevocationFinderModule.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/RevocationFinderModule.java new file mode 100644 index 0000000..c8f116d --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/RevocationFinderModule.java @@ -0,0 +1,86 @@ + +/* + * @(#)RevocationFinderModule.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.finder; + +import java.net.URI; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.EvaluationCtx; + +/** + * This is the abstract class that all RevocationFinder modules + * extend. All methods have default values to represent that the given + * feature isn't supported by this module, so module writers needs only + * implement the methods for the features they're supporting. + * + * @since 3.0 + * @author Ludwig Seitz + */ +public abstract class RevocationFinderModule +{ + + /** + * Returns this module's identifier. A module does not need to provide + * a unique identifier, but it is a good idea, especially in support of + * management software. Common identifiers would be the full package + * and class name (the default if this method isn't overridden), just the + * class name, or some other well-known string that identifies this class. + * + * @return this module's identifier + */ + public String getIdentifier() { + return getClass().getName(); + } + + /** + * Checks whether a policy supports the revocation of a candidate policy. + * + * @param policy The policy that may support a revocation + * @param candidate The id of the policy or policy set that is candidate + * for revocation. + * @param context the context in which this policy may support revocations + * + * @return true if this policy supports a the revocation of the candidate, + * false otherwise. + */ + public boolean supportsRevocation(AbstractPolicy policy, URI candidate, + EvaluationCtx context) { + return false; + } +} + diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/impl/CurrentEnvModule.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/impl/CurrentEnvModule.java new file mode 100644 index 0000000..bff421d --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/impl/CurrentEnvModule.java @@ -0,0 +1,208 @@ + +/* + * @(#)CurrentEnvModule.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.finder.impl; + +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.Constants; +import com.sun.xacml.EvaluationCtx; + +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BagAttribute; +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.finder.AttributeFinderModule; + +//import foo.xacml.finder.IRecordEvaluationContext; + +import java.net.URI; + +import java.util.HashSet; +import java.util.Set; + + +/** + * Supports the current date, time, and dateTime values. The XACML + * specification states that these three values must always be available to + * a PDP. They may be included in the request, but if they're not, a PDP + * must be able to recognize the attribute and generate a correct value. + *

+ * The XACML specification doesn't require that values be cached (ie, + * remain consistent within an evaluation), but does allow it. Any caching, + * as well as details of which time to use (time at the PEP, PDP, etc.) is + * taken care of by the EvaluationCtx which is used to supply + * the current values. + * + * @since 1.0 + * @author Seth Proctor + */ +public class CurrentEnvModule extends AttributeFinderModule +{ + + /** + * Standard environment variable that represents the current time + */ + public static final String ENVIRONMENT_CURRENT_TIME = + "urn:oasis:names:tc:xacml:1.0:environment:current-time"; + + /** + * Standard environment variable that represents the current date + */ + public static final String ENVIRONMENT_CURRENT_DATE = + "urn:oasis:names:tc:xacml:1.0:environment:current-date"; + + /** + * Standard environment variable that represents the current date and time + */ + public static final String ENVIRONMENT_CURRENT_DATETIME = + "urn:oasis:names:tc:xacml:1.0:environment:current-dateTime"; + + /** + * Returns true always because this module supports designators. + * + * @return true always + */ + public boolean isDesignatorSupported() { + return true; + } + + /** + * Used to get the current time, date, or dateTime. If one of those + * values isn't being asked for, or if the types are wrong, then an + * empty bag is returned. + * + * @param category the category of the attribute + * @param attributeType the datatype of the attributes to find, which + * must be time, date, or dateTime for this module + * to resolve a value + * @param attributeId the identifier of the attributes to find, which + * must be one of the three ENVIRONMENT_* fields for + * this module to resolve a value + * @param issuer the issuer of the attributes, or null if unspecified + * @param context the representation of the request data + * + * @return the result of attribute retrieval, which will be a bag with + * a single attribute, an empty bag, or an error + */ + public EvaluationResult findAttribute(URI category, URI attributeType, + URI attributeId, URI issuer, + EvaluationCtx context) { + // we only know about environment attributes + if (!category.equals(Constants.ENVIRONMENT_CAT)) { + return new EvaluationResult(BagAttribute. + createEmptyBag(attributeType)); + + } + + // figure out which attribute we're looking for + String attrName = attributeId.toString(); + + if (attrName.equals(ENVIRONMENT_CURRENT_TIME)) { + return handleTime(attributeType, issuer, context); + } else if (attrName.equals(ENVIRONMENT_CURRENT_DATE)) { + return handleDate(attributeType, issuer, context); + } else if (attrName.equals(ENVIRONMENT_CURRENT_DATETIME)) { + return handleDateTime(attributeType, issuer, context); + } + + // if we got here, then it's an attribute that we don't know + return new EvaluationResult(BagAttribute. + createEmptyBag(attributeType)); + } + + /** + * Handles requests for the current Time. + */ + private EvaluationResult handleTime(URI type, URI issuer, + EvaluationCtx context) { + // make sure they're asking for a time attribute + if (! type.toString().equals(TimeAttribute.identifier)) { + return new EvaluationResult(BagAttribute. + createEmptyBag(type)); + } + // get the value from the context + return makeBag(context.getCurrentTime()); + } + + /** + * Handles requests for the current Date. + */ + private EvaluationResult handleDate(URI type, URI issuer, + EvaluationCtx context) { + // make sure they're asking for a date attribute + if (! type.toString().equals(DateAttribute.identifier)) { + return new EvaluationResult(BagAttribute. + createEmptyBag(type)); + } + // get the value from the context + return makeBag(context.getCurrentDate()); + } + + /** + * Handles requests for the current DateTime. + */ + private EvaluationResult handleDateTime(URI type, URI issuer, + EvaluationCtx context) { + // make sure they're asking for a dateTime attribute + if (! type.toString().equals(DateTimeAttribute.identifier)) { + return new EvaluationResult(BagAttribute. + createEmptyBag(type)); + } + // get the value from the context + return makeBag(context.getCurrentDateTime()); + } + + /** + * Private helper that makes a bag containing only the given attribute. + */ + private EvaluationResult makeBag(AttributeValue attribute) { + Set set = new HashSet(); + set.add(attribute); + + BagAttribute bag = new BagAttribute(attribute.getType(), set); + + return new EvaluationResult(bag); + } + + public void setConfigurationStore(ConfigurationStore confStore) { + + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/impl/CurrentRequiredAttributeModule.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/impl/CurrentRequiredAttributeModule.java new file mode 100644 index 0000000..5ce4b35 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/impl/CurrentRequiredAttributeModule.java @@ -0,0 +1,44 @@ +package com.sun.xacml.finder.impl; + +import java.util.HashSet; +import java.util.Set; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; +import com.sun.xacml.attr.AttributeDesignator; +import com.sun.xacml.attr.StandardAttributeFactory; +import com.sun.xacml.ctx.Attribute; +import com.sun.xacml.finder.RequiredAttributesModule; + +/** + * + * Simple class / naiv implementation which does not do any prefetching + * and simply returns the currently required attribute + * + * + */ +public class CurrentRequiredAttributeModule extends RequiredAttributesModule { + + private static StandardAttributeFactory attrFactory = StandardAttributeFactory.getFactory(); + + @Override + public Set resolveRequiredAttributes(EvaluationCtx context, + AttributeDesignator attrDesignator) { + + Set attr = new HashSet(); + + try { + attr.add(new Attribute(attrDesignator.getId(), + attrDesignator.getIssuer() == null ? null : attrDesignator.getIssuer().toString(), + attrFactory.createValue(attrDesignator.getType(), null))); + } catch (UnknownIdentifierException e) { + e.printStackTrace(); + } catch (ParsingException e) { + e.printStackTrace(); + } + + return attr; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/impl/SelectorModule.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/impl/SelectorModule.java new file mode 100644 index 0000000..b721589 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/impl/SelectorModule.java @@ -0,0 +1,241 @@ + +/* + * @(#)SelectorModule.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.finder.impl; + +import com.sun.xacml.Constants; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; + +import com.sun.xacml.attr.AttributeFactory; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BagAttribute; + +import com.sun.xacml.cond.EvaluationResult; + +import com.sun.xacml.ctx.Status; + +import com.sun.xacml.finder.AttributeFinderModule; + +import java.net.URI; + +import java.util.ArrayList; + +import org.apache.xpath.XPathAPI; + +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + + +/** + * This module implements the basic behavior of the AttributeSelectorType, + * looking for attribute values in the physical request document using the + * given XPath expression. This is implemented as a separate module (instead + * of being implemented directly in AttributeSelector so that + * programmers can remove this functionality if they want (it's optional in + * the spec), so they can replace this code with more efficient, specific + * code as needed, and so they can easily swap in different XPath libraries. + *

+ * Note that if no matches are found, this module will return an empty bag + * (unless some error occurred). The AttributeSelector is still + * deciding what to return to the policy based on the MustBePresent + * attribute. + *

+ * This module uses the Xalan XPath implementation, and supports only version + * 1.0 of XPath. It is a fully functional, correct implementation of XACML's + * AttributeSelector functionality, but is not designed for environments + * that make significant use of XPath queries. Developers for any such + * environment should consider implementing their own module. + * + * @since 1.0 + * @author Seth Proctor + */ +public class SelectorModule extends AttributeFinderModule +{ + + /** + * Returns true since this module supports retrieving attributes based on + * the data provided in an AttributeSelectorType. + * + * @return true + */ + public boolean isSelectorSupported() { + return true; + } + + /** + * Private helper to create a new processing error status result + */ + private EvaluationResult createProcessingError(String msg) { + ArrayList code = new ArrayList(); + code.add(Status.STATUS_PROCESSING_ERROR); + return new EvaluationResult(new Status(code, msg)); + } + + /** + * Tries to find attribute values based on the given selector data. + * The result, if successful, always contains a BagAttribute, + * even if only one value was found. If no values were found, but no other + * error occurred, an empty bag is returned. + * + * @param path the XPath expression to search against + * @param namespaceNode the DOM node defining namespace mappings to use, + * or null if mappings come from the context root + * @param type the datatype of the attributes to find + * @param context the representation of the request data + * @param xpathVersion the XPath version to use + * + * @return the result of attribute retrieval, which will be a bag of + * attributes or an error + */ + public EvaluationResult findAttribute(String path, Node namespaceNode, + URI type, EvaluationCtx context, + String xpathVersion) { + // we only support 1.0 + if (! xpathVersion.equals(Constants.XPATH_1_0_IDENTIFIER)) { + return new EvaluationResult(BagAttribute.createEmptyBag(type)); + } + + // get the DOM root of the request document + Node root = context.getRequestRoot(); + + // if we were provided with a non-null namespace node, then use it + // to resolve namespaces, otherwise use the context root node + Node nsNode = (namespaceNode != null) ? namespaceNode : root; + + // setup the root path (pre-pended to the context path), which... + String rootPath = ""; + + // ...only has content if the context path is relative + if (path.charAt(0) != '/') { + String rootName = root.getLocalName(); + + // see if the request root is in a namespace + String namespace = root.getNamespaceURI(); + + if (namespace == null) { + // no namespacing, so we're done + rootPath = "/" + rootName + "/"; + } else { + // namespaces are used, so we need to lookup the correct + // prefix to use in the search string + NamedNodeMap nmap = namespaceNode.getAttributes(); + rootPath = null; + + for (int i = 0; i < nmap.getLength(); i++) { + Node n = nmap.item(i); + if (n.getNodeValue().equals(namespace)) { + // we found the matching namespace, so get the prefix + // and then break out + String name = n.getNodeName(); + int pos = name.indexOf(':'); + + if (pos == -1) { + // the namespace was the default namespace + rootPath = "/"; + } else { + // we found a prefixed namespace + rootPath = "/" + name.substring(pos + 1); + } + + // finish off the string + rootPath += ":" + rootName + "/"; + + break; + } + } + + // if the rootPath is still null, then we don't have any + // definitions for the namespace + if (rootPath == null) { + return createProcessingError("Failed to map a namespace" + + " in an XPath expression"); + } + } + } + + // now do the query, pre-pending the root path to the context path + NodeList matches = null; + try { + // NOTE: see comments in XALAN docs about why this is slow + matches = XPathAPI.selectNodeList(root, rootPath + path, nsNode); + } catch (Exception e) { + // in the case of any exception, we need to return an error + return createProcessingError("error in XPath: " + e.getMessage()); + } + + if (matches.getLength() == 0) { + // we didn't find anything, so we return an empty bag + return new EvaluationResult(BagAttribute.createEmptyBag(type)); + } + + // there was at least one match, so try to generate the values + try { + ArrayList list = new ArrayList(); + AttributeFactory attrFactory = AttributeFactory.getInstance(); + + for (int i = 0; i < matches.getLength(); i++) { + String text = null; + Node node = matches.item(i); + short nodeType = node.getNodeType(); + + // see if this is straight text, or a node with data under + // it and then get the values accordingly + if ((nodeType == Node.CDATA_SECTION_NODE) || + (nodeType == Node.COMMENT_NODE) || + (nodeType == Node.TEXT_NODE) || + (nodeType == Node.ATTRIBUTE_NODE)) { + // there is no child to this node + text = node.getNodeValue(); + } else { + // the data is in a child node + text = node.getFirstChild().getNodeValue(); + } + + list.add(attrFactory.createValue(type, text)); + } + + return new EvaluationResult(new BagAttribute(type, list)); + } catch (ParsingException pe) { + return createProcessingError(pe.getMessage()); + } catch (UnknownIdentifierException uie) { + return createProcessingError("unknown attribute type: " + type); + } + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/impl/package.html b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/impl/package.html new file mode 100644 index 0000000..c187560 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/impl/package.html @@ -0,0 +1,8 @@ + + The few included finder modules are provided in this package. These + provide some basic functionality to get an application started, but + should by no means be considered enterprise quality. They provide a + file-based access to a specific set of policies, a way of getting + current time/date/dateTime values, and simple XPath support for + selectors. + diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/package.html b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/package.html new file mode 100644 index 0000000..69212d8 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/finder/package.html @@ -0,0 +1,11 @@ + + The finder package supports all of the pieces of the + XACML specification that require custom implementation. Specifically, + there are classes here to manage looking for attributes outside of the + physical request document, finding policies, and resolving resource + identifiers. There are also base classes used to build new modules + that can perform different application specific tasks to support these + three kinds of operations. These managers are used directly by the + PDP, and the managers in turn use the modules, and return values using + the return-value classes in this package. + diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/package.html b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/package.html new file mode 100644 index 0000000..6de2999 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/package.html @@ -0,0 +1,9 @@ + + This is the root package, which contains the PDP class where most + people will want to start. This package also contains most of the + classes that represent the XML elements from the XACML policy schema, + like Target, Policy, Rule, and Obligation. Most of the classes here + are used when parsing or processing a policy, but a few (like + EvaluationCtx) are used throughout the code and by many + of the extension APIs. There are also some common Exceptions here. + diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/reduction/EdgeExplorer.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/reduction/EdgeExplorer.java new file mode 100644 index 0000000..dfd2061 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/reduction/EdgeExplorer.java @@ -0,0 +1,346 @@ +/* + * @(#)EdgeExplorer.java + * + * Copyright 2007 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.reduction; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.MatchResult; +import com.sun.xacml.PolicyReference; +import com.sun.xacml.PolicySet; +import com.sun.xacml.PolicyTreeElement; +import com.sun.xacml.ctx.Result; + +/** + * This class provides an iterator that goes through the support + * edges of a policy. + * + * @author Ludwig Seitz + * + */ +public class EdgeExplorer { + + /** + * The node we are exploring from. + */ + private ReductionGraphNode node; + + /** + * The type of edges we want to explore encoded as + * bitwise or of the codes in + * ReductionGraphEdge. + */ + private int allowedEdges; + + /** + * The context we want to explore in. + */ + private EvaluationCtx ctx; + + /** + * The List of neighboring nodes. + */ + private List neighbors; + + /** + * Iterator going through the neighbors. + */ + private Iterator neighborIter; + + /** + * Constructor. + * + * @param allowedEdges The type of edges we want to explore + * as bitwise or of the corresponding + * codes in ReductionGraphEdge. + * @param ctx The context we want to explore in. + * @param startPolicy The PolicyId we are exploring from. + */ + public EdgeExplorer(int allowedEdges, EvaluationCtx ctx, + URI startPolicy) { + this.node = ctx.getReductionGraph().getNode(startPolicy); + this.ctx = ctx; + this.allowedEdges = allowedEdges; + // first get the parent policy set from the stack in context + AbstractPolicy parentPolicySet = ctx.getParentPolicySet(); + if (parentPolicySet != null) { + this.neighbors = getActiveChilds(parentPolicySet.getChildren(), + ctx); + } else { + this.neighbors = new ArrayList(); + } + + this.neighborIter = this.neighbors.iterator(); + + } + + /** + * @return true if there are potential edges left to explore, + * false otherwise. + */ + public boolean hasNext() { + return this.neighborIter.hasNext(); + } + + /** + * @return The next node that is reachable by one of the allowed + * edge types, or null if there aren't any more. + */ + public URI next() { + if (!this.neighborIter.hasNext()) { + return null; + } + AbstractPolicy neighbor = (AbstractPolicy)this.neighborIter.next(); + // First check if there are already matching edges + Set fromEdges = this.ctx.getReductionGraph().getFromEdges( + this.node.getNodeId()); + Iterator edgeIt = fromEdges.iterator(); + while (edgeIt.hasNext()) { + ReductionGraphEdge edge = edgeIt.next(); + if (edge.getTo().equals(neighbor.getId())) { + // we use bitwise AND to see if the edge type is allowed + if ((this.allowedEdges & edge.getType()) + == edge.getType()) { + //report this event + this.ctx.newEvent(edge); + this.ctx.closeCurrentEvent(); + return neighbor.getId(); + } else if (edge.getType() + == ReductionGraphEdge.NOT_APPLICABLE) { + // we don't need to process this any further + // so we can go to the next element + this.ctx.newEvent(edge); + this.ctx.closeCurrentEvent(); + return next(); + } else if (((this.allowedEdges & ReductionGraphEdge.PP) + == ReductionGraphEdge.PP) + && edge.getType() == ReductionGraphEdge.PI) { + // we don't need to process this any further + // so we can go to the next element + this.ctx.newEvent(edge); + this.ctx.closeCurrentEvent(); + return next(); + } else if (((this.allowedEdges & ReductionGraphEdge.DP) + == ReductionGraphEdge.DP) + && edge.getType() == ReductionGraphEdge.DI) { + // we don't need to process this any further + // so we can go to the next element + this.ctx.newEvent(edge); + this.ctx.closeCurrentEvent(); + return next(); + } + } + } + //This edge hasn't been evaluated before, so we do it now + this.ctx.newEvent(neighbor); + MatchResult matchResult = neighbor.match(this.ctx); + switch (matchResult.getResult()) { + case MatchResult.NO_MATCH: + this.ctx.closeCurrentEvent( + new Result(Result.DECISION_NOT_APPLICABLE)); + this.ctx.getReductionGraph().setEdge(new ReductionGraphEdge( + this.node.getNodeId(), neighbor.getId(), + ReductionGraphEdge.NOT_APPLICABLE)); + return next(); + case MatchResult.INDETERMINATE: + this.ctx.closeCurrentEvent( + new Result(Result.DECISION_INDETERMINATE, this.ctx)); + if (this.ctx.getDecision() == Result.DECISION_PERMIT) { + this.ctx.getReductionGraph().setEdge(new ReductionGraphEdge( + this.node.getNodeId(), neighbor.getId(), + ReductionGraphEdge.PI, + matchResult.getStatus())); + if ((this.allowedEdges & ReductionGraphEdge.PI) + == ReductionGraphEdge.PI) { + return neighbor.getId(); + } + } else { // decision is DENY + this.ctx.getReductionGraph().setEdge(new ReductionGraphEdge( + this.node.getNodeId(), neighbor.getId(), + ReductionGraphEdge.DI, + matchResult.getStatus())); + if ((this.allowedEdges & ReductionGraphEdge.DI) + == ReductionGraphEdge.DI) { + return neighbor.getId(); + } + } + return next(); + case MatchResult.MATCH: + //evaluate policy + if (neighbor instanceof PolicySet) { + this.ctx.saveParentPolicySet(neighbor); + } else if (neighbor instanceof PolicyReference) { + PolicyReference ref = (PolicyReference)neighbor; + if (ref.getReferenceType() + == PolicyReference.POLICYSET_REFERENCE) { + this.ctx.saveParentPolicySet(neighbor); + } + } + + Result eval = neighbor.getCombiningAlg().combine(this.ctx, + neighbor.getCombiningParameters(), + neighbor.getChildElements()); + // check for maxDelegationDepth + if (this.ctx.getDelegationDepth() + > neighbor.getMaxDelegationDepth()) { + this.ctx.closeCurrentEvent("MaxDelegationDepth violated"); + this.ctx.getReductionGraph().setEdge(new ReductionGraphEdge( + this.node.getNodeId(), neighbor.getId(), + ReductionGraphEdge.NOT_APPLICABLE)); + return null; + } + // Check if it supports the revocation of + // a policy down the delegation chain + if (this.ctx.supportsRevocation(neighbor, this.node.getNodeId())) { + Result nullResult = null; + this.ctx.closeCurrentEvent(nullResult); + this.ctx.getReductionGraph().setEdge(new ReductionGraphEdge( + this.node.getNodeId(), neighbor.getId(), + ReductionGraphEdge.NOT_APPLICABLE)); + return null; + } + this.ctx.closeCurrentEvent(eval); + if (neighbor instanceof PolicySet) { + this.ctx.popParentPolicySet(); + this.ctx.popReductionGraph(); + } else if (neighbor instanceof PolicyReference) { + PolicyReference ref = (PolicyReference)neighbor; + if (ref.getReferenceType() + == PolicyReference.POLICYSET_REFERENCE) { + this.ctx.popParentPolicySet(); + this.ctx.popReductionGraph(); + } + } + switch (eval.getDecision()) { + case Result.DECISION_PERMIT : + if (this.ctx.getDecision() == Result.DECISION_PERMIT) { + this.ctx.getReductionGraph().setEdge( + new ReductionGraphEdge( + this.node.getNodeId(), neighbor.getId(), + ReductionGraphEdge.PP)); + if ((this.allowedEdges & ReductionGraphEdge.PP) + == ReductionGraphEdge.PP) { + return neighbor.getId(); + } + } else if (this.ctx.getDecision() == Result.DECISION_DENY) { + this.ctx.getReductionGraph().setEdge( + new ReductionGraphEdge( + this.node.getNodeId(), neighbor.getId(), + ReductionGraphEdge.DP)); + if ((this.allowedEdges & ReductionGraphEdge.DP) + == ReductionGraphEdge.DP) { + return neighbor.getId(); + } + } + return next(); + case Result.DECISION_INDETERMINATE : + if (this.ctx.getDecision() == Result.DECISION_PERMIT) { + this.ctx.getReductionGraph().setEdge( + new ReductionGraphEdge( + this.node.getNodeId(), neighbor.getId(), + ReductionGraphEdge.PI, + eval.getStatus())); + + if ((this.allowedEdges & ReductionGraphEdge.PI) + == ReductionGraphEdge.PI) { + return neighbor.getId(); + } + } else if (this.ctx.getDecision() == Result.DECISION_DENY) { + this.ctx.getReductionGraph().setEdge( + new ReductionGraphEdge( + this.node.getNodeId(), neighbor.getId(), + ReductionGraphEdge.DI, + eval.getStatus())); + if ((this.allowedEdges & ReductionGraphEdge.DI) + == ReductionGraphEdge.DI) { + return neighbor.getId(); + } + } + return next(); + default: + this.ctx.getReductionGraph().setEdge(new ReductionGraphEdge( + this.node.getNodeId(), neighbor.getId(), + ReductionGraphEdge.NOT_APPLICABLE)); + return next(); + } + } + return next(); + } + + /** + * Private helper that builds the list of active child policies/policy sets + * from the list of all childs and the list of deactivated childs. + * Used in reduction steps of a delegation chain. + * + * @param allChilds a List of CombinerElements. + * @param context the context containing the deactivated childs. + * + * @return A list of CombinerElemets. + */ + private List getActiveChilds(List allChilds, EvaluationCtx context) { + List activeChilds = new ArrayList(); + Iterator iter = allChilds.iterator(); + while (iter.hasNext()) { + AbstractPolicy policy = (AbstractPolicy)iter.next(); + URI elementId = null; + if (policy instanceof PolicyReference) { + //PolicyReferences get special treatment here. + //this is due to the fact that in certain cases we do not + // want to run the resolvePolicy() method of a policy + // reference here, which would be the case if we used getId(). + // An example for such cases can be found in the XACML 2.0 + // test cases, test group E, test 003. + PolicyReference pr = (PolicyReference)policy; + elementId = pr.getReference(); + } else { + elementId = policy.getId(); + } + if (!context.getInactivePolicyIds().contains(elementId)) { + activeChilds.add(policy); + } + } + return activeChilds; + } + + + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/reduction/ReductionGraph.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/reduction/ReductionGraph.java new file mode 100644 index 0000000..8562ebe --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/reduction/ReductionGraph.java @@ -0,0 +1,369 @@ +/* + * @(#)ReductionGraph.java + * + * Copyright 2007 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.reduction; + +import java.net.URI; + +import java.util.ArrayList; +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 com.sun.xacml.AbstractPolicy; +import com.sun.xacml.Constants; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.Obligation; +import com.sun.xacml.PolicyTreeElement; +import com.sun.xacml.ctx.RequestElement; +import com.sun.xacml.ctx.Result; +import com.sun.xacml.ctx.Status; + +/** + * This class saves a graph structure for reducing untrusted policies. + * + * @author Ludwig Seitz + * + */ +public class ReductionGraph implements Cloneable { + + /** + * Sets of ReductionGraphEdges of the graph + * keyed by the nodeIds (i.e. policyId URIs) they go out from. + */ + private Map> fromEdges; + + /** + * Sets of ReductionGraphEdges of the graph + * keyed by the nodeIds (i.e. policyId URIs) they go in to. + */ + private Map> toEdges; + + /** + * The ReductionGraphNodes keyed by the id. + */ + private Map nodes; + + /** + * Constructor, starts a new ReductionGraph. + * + * @param pps The parent policy set, from which we gather the nodes + * of the graph. + */ + public ReductionGraph(AbstractPolicy pps) { + this.fromEdges = new HashMap>(); + this.toEdges = new HashMap>(); + this.nodes = new HashMap(); + if (pps != null) { + Iterator iter = pps.getChildren().iterator(); + while(iter.hasNext()) { + AbstractPolicy policy = (AbstractPolicy)iter.next(); + this.nodes.put(policy.getId(), new ReductionGraphNode(policy)); + } + } + } + + /** + * The clone method. + * FIXME: this does no deep copy on the content of the Maps. + * + * @return a copy of this object. + */ + public Object clone() { + try { + ReductionGraph clone = (ReductionGraph) super.clone(); + clone.fromEdges = new HashMap>(this.fromEdges); + clone.toEdges = new HashMap>(this.toEdges); + clone.nodes = new HashMap(this.nodes); + return clone; + } catch (CloneNotSupportedException e) {//this should never happen + throw new RuntimeException("Couldn't clone ReductionGraph"); + } + } + + /** + * A private helper that does the reduction of an untrusted policy or + * policyset. + * + * @param ctx The evaluation context. + * @param result The evaluation result of this policy. + * @param policyId The id of the policy being reduced. + * + * @return The adapted evaluation result of this policy + * (see standard). + */ + public Result reduce(EvaluationCtx ctx, Result result, URI policyId) { + int allowedEdges = 0; + int extendedAllowedEdges = 0; + if (result.getDecision() == Result.DECISION_PERMIT) { + allowedEdges = ReductionGraphEdge.PP; + extendedAllowedEdges + = ReductionGraphEdge.PP | ReductionGraphEdge.PI; + } else if (result.getDecision() == Result.DECISION_DENY) { + allowedEdges = ReductionGraphEdge.DP; + extendedAllowedEdges + = ReductionGraphEdge.DP | ReductionGraphEdge.DI; + } else if (result.getDecision() == Result.DECISION_INDETERMINATE) { + allowedEdges + = ReductionGraphEdge.PP | ReductionGraphEdge.PI; + extendedAllowedEdges + = ReductionGraphEdge.DP | ReductionGraphEdge.DI; + } + + Result reductionResult = graphSearch(allowedEdges, ctx, policyId); + if(reductionResult == null) { + reductionResult = graphSearch(extendedAllowedEdges, ctx, policyId); + if (reductionResult == null) { + return null; + } + List codes = new ArrayList(); + codes.add(Status.STATUS_PROCESSING_ERROR); + return new Result(Result.DECISION_INDETERMINATE, + new Status(codes, "Error while reducing")); + } + return reductionResult; // Permit because reductionResult != null + } + + private Result graphSearch(int allowedEdges, EvaluationCtx ctx, + URI policyId) { + // Get the node. + ReductionGraphNode node = (ReductionGraphNode)this.nodes.get(policyId); + + // Prepare the 'discarded' result (see standard). + Result nullResult = null; + + // Check if there is a parent policy set + if (node == null) { + ctx.newEvent(Integer.valueOf(allowedEdges)); + ctx.closeCurrentEvent(nullResult); + return null; + } + + // Recursion end clause + if (node.isTrusted()) { + return new Result(Result.DECISION_PERMIT, node.getObligations()); + } + + // Signal the reduction event + ctx.newEvent(Integer.valueOf(allowedEdges)); + + Result result = node.previousReduction(allowedEdges); + if (result == null || result.getDecision() != Result.DECISION_DENY) { + //DENY means that the node has not yet been reduced. + //Its a fix so we can just transmit the result. + ctx.closeCurrentEvent(result); + return result; + } + + // create an administrative context + int newDecision = ctx.getDecision(); + //Figure out decision if necessary + if (newDecision == Result.INVALID_DECISION) { + if ((allowedEdges & ReductionGraphEdge.PP) + == ReductionGraphEdge.PP) { + newDecision = Result.DECISION_PERMIT; + } else if ((allowedEdges & ReductionGraphEdge.DP) + == ReductionGraphEdge.DP) { + newDecision = Result.DECISION_DENY; + } else { // this should never happen because decision should be + // permit or deny. + //close the reduction event + ctx.closeCurrentEvent(nullResult); + return null; + } + } + Set newDelegate = null; + // btw: we can safely assume that the policyIssuer is not + // null here otherwise this function would not have been called. + newDelegate = new HashSet(); + RequestElement delegate = new RequestElement(Constants.DELEGATE, + node.getIssuer().getAttributes()); + newDelegate.add(delegate); + EvaluationCtx admCtx = ctx.createAdminCtx(newDecision, + newDelegate); + + // deactivate this policy, we don't want to search it again. + admCtx.addInactivePolicyId(node.getNodeId()); + + // Create edgeExplorer to go through the graph edges from this node + EdgeExplorer potentialEdges = new EdgeExplorer(allowedEdges, admCtx, + node.getNodeId()); + while (potentialEdges.hasNext()) { + URI nextPolicyId = potentialEdges.next(); + if (nextPolicyId == null) { + ctx.closeCurrentEvent(nullResult); + node.setState(null, allowedEdges, + admCtx.getDelegationDepth()); + return null; + } + result = graphSearch(allowedEdges, admCtx, nextPolicyId); + if (result != null && + result.getDecision() == Result.DECISION_PERMIT) { + ctx.closeCurrentEvent(result); + Set obligations = new HashSet(node.getObligations()); + obligations.addAll(result.getObligations()); + node.setState(result, allowedEdges, + admCtx.getDelegationDepth()); + //now return the result + return new Result(Result.DECISION_PERMIT, obligations); + } + } + ctx.closeCurrentEvent(nullResult); + node.setState(nullResult, allowedEdges, admCtx.getDelegationDepth()); + return null; + } + + /** + * Return the type of edge there is for two policies identified + * by their PolicyId URIs. + * + * @param from The policy from which the edge originates. + * @param to The policy to which the edge goes. + * + * @return the type of edge as in the static list above. + */ + public int getEdge(URI from, URI to) { + Set rteSet = this.fromEdges.get(from); + if (rteSet == null) { + return ReductionGraphEdge.NOT_EVALUATED; + } + Iterator iter = rteSet.iterator(); + while (iter.hasNext()) { + ReductionGraphEdge rte = (ReductionGraphEdge)iter.next(); + if (rte.getTo().equals(to)) { + return rte.getType(); + } + } + //if we arrived here, no edges between the two policies where found + return ReductionGraphEdge.NOT_EVALUATED; + + } + + /** + * Set an edge in the ReductionGraph. + * + * @param edge The edge to be set. + */ + public void setEdge(ReductionGraphEdge edge) { + Set fromSet = this.fromEdges.get(edge.getFrom()); + if (fromSet == null) { + fromSet = new HashSet(); + this.fromEdges.put(edge.getFrom(), fromSet); + } + fromSet.add(edge); + Set toSet = this.toEdges.get(edge.getTo()); + if (toSet == null) { + toSet = new HashSet(); + this.toEdges.put(edge.getTo(), toSet); + } + toSet.add(edge); + } + + /** + * Returns the Set of ReductionGraphEdges + * that go out from a specific policy. + * + * @param from The policy identified its PolicyId URI. + * + * @return A Set of ReductionGraphEdges. + */ + public Set getFromEdges(URI from) { + Set result = this.fromEdges.get(from); + if (result == null) { + result = new HashSet(); + this.fromEdges.put(from, result); + } + return result; + } + + /** + * Returns the Set of ReductionGraphEdges + * that go to a specific policy. + * + * @param to The policy identified its PolicyId URI. + * + * @return A Set of ReductionGraphEdges. + */ + public Set getToEdges(URI to) { + Set result = this.fromEdges.get(to); + if (result == null) { + result = new HashSet(); + this.fromEdges.put(to, result); + } + return result; + } + + /** + * Get a node from the graph. + * + * @param nodeId The node's id. + * + * @return The node. + */ + public ReductionGraphNode getNode(URI nodeId) { + return (ReductionGraphNode)this.nodes.get(nodeId); + } + + /** + * Encode to string for debugging + * + * @return String representation of the graph. + */ + public String toString() { + String result = ""; + Iterator> iter = this.nodes.entrySet().iterator(); + while (iter.hasNext()) { + Map.Entry entry = iter.next(); + ReductionGraphNode node = (ReductionGraphNode) entry.getValue(); + result += node.toString(); + if (this.fromEdges.get(entry.getKey()) != null) { + Iterator iter2 = (this.fromEdges.get(entry.getKey())).iterator(); + while (iter2.hasNext()) { + ReductionGraphEdge edge = iter2.next(); + result += "[" + edge.toString() + "] "; + } + } + result += Constants.nl; + } + return result; + } +} + + + \ No newline at end of file diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/reduction/ReductionGraphEdge.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/reduction/ReductionGraphEdge.java new file mode 100644 index 0000000..8d0d553 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/reduction/ReductionGraphEdge.java @@ -0,0 +1,207 @@ +/* + * @(#)ReductionGraphEdge.java + * + * Copyright 2007 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.reduction; + +import java.net.URI; + +import com.sun.xacml.ctx.Status; + +/** + * This class stores an edge of the reduction graph. + * + * @author Ludwig Seitz + * + */ +public class ReductionGraphEdge { + + /** + * An edge that has not yet been evaluated. + * Binary encoding for bitwise manipulation. + * Only PP | PI and DP | DI are possible making + * the values 1, 2, 3, 4 and 12 reserved. Leaving + * 0 for NOT_EVALUATED and 13 for NOT_APPLICABLE + */ + public static final int NOT_EVALUATED = 0; + + /** + * An edge that reduces PERMIT to PERMIT. + */ + public static final int PP = 1; + + /** + * An edge that reductes PERMIT to INDETERMINATE + */ + public static final int PI = 2; + + + /** + * An edge that reductes DENY to PERMIT + */ + public static final int DP = 4; + + /** + * An edge that reductes DENY to INDETERMINATE + */ + public static final int DI = 8; + + /** + * An edge that reduces to NOT_APPLICABLE + */ + public static final int NOT_APPLICABLE = 16; + + /** + * The policyId URI this edge originates in. + */ + private URI from; + + /** + * The policyId URI this edge points to. + */ + private URI to; + + /** + * The type of edge this is from the types specified in + * ReductionGraph class. + */ + private int type; + + /** + * The status for a PI or DI edge. Null for all other types. + */ + private Status status; + + /** + * Constructor. + * + * @param from The policyId URI this edge originates in. + * @param to The policyId URI this edge points to. + * @param type The type of edge this is, from the types specified + * in ReductionGraph class. + */ + public ReductionGraphEdge(URI from, URI to, int type) { + this(from, to, type, null); + } + + /** + * Constructor. + * + * @param from The policyId URI this edge originates in. + * @param to The policyId URI this edge points to. + * @param type The type of edge this is, from the types specified + * in ReductionGraph class. + */ + public ReductionGraphEdge(URI from, URI to, Integer type) { + this(from, to, type, null); + } + + /** + * Constructor. + * + * @param from The policyId URI this edge originates in. + * @param to The policyId URI this edge points to. + * @param type The type of edge this is, from the types specified + * in ReductionGraph class. + * @param status The status for a PI or DI edge. + */ + public ReductionGraphEdge(URI from, URI to, int type, Status status) { + this.from = from; + this.to = to; + this.type = type; + this.status = status; + } + + /** + * Constructor. + * + * @param from The policyId URI this edge originates in. + * @param to The policyId URI this edge points to. + * @param type The type of edge this is, from the types specified + * in ReductionGraph class. + * @param status The status for a PI or DI edge. + */ + public ReductionGraphEdge(URI from, URI to, Integer type, Status status) { + this.from = from; + this.to = to; + this.type = type.intValue(); + this.status = status; + } + + + /** + * @return The policyId URI this edge originates in. + */ + public URI getFrom() { + return this.from; + } + + /** + * @return The policyId URI this edge points to. + */ + public URI getTo() { + return this.to; + } + + /** + * @return The type of edge this is from the types specified in + * ReductionGraph class. + */ + public int getType() { + return this.type; + } + + /** + * @return The Status or null if there isn't one. + */ + public Status getStatus() { + return this.status; + } + + /** + * Encode edge to string for debugging. + * + * @return String representation of the graph edge. + */ + public String toString() { + //Values for the reduction graph edges. + //Currently only the values NE, PP, (PP,PI), DP, (DP,DI) and NA + //are legal + String [] values = {"NE", "PP", "PI", "PP,PI", "DP", "PP,DP", + "PI,DP", "PP,PI,DP", "DI", "PP,DI", "PI,DI", "PP,PI,DI", + "DP,DI", "PP,DP,DI", "PP,PI,DI", "PP,PI,DP,DI", "NA"}; + return values[this.type] + "->" + this.to.toString(); + } +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/reduction/ReductionGraphNode.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/reduction/ReductionGraphNode.java new file mode 100644 index 0000000..af367e2 --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/main/java/com/sun/xacml/reduction/ReductionGraphNode.java @@ -0,0 +1,387 @@ +/* + * @(#)ReductionGraphNode.java + * + * Copyright 2007 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.reduction; + +import java.net.URI; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.Obligation; +import com.sun.xacml.ctx.PolicyIssuer; +import com.sun.xacml.ctx.Result; + +public class ReductionGraphNode { + + /** + * Static value for the reducable* members. + */ + public static final int UNKNOWN = -1; + + /** + * Static value for the reducable* members. + */ + public static final int NO = 0; + + /** + * Static value for the reducable* members. + */ + public static final int YES = 1; + + /** + * Describes if this node can be reduced to a trusted + * node by PP edges. + */ + private int reducablePP; + + /** + * Describes if this node can be reduced to a trusted + * node by PP and PI edges. + */ + private int reducablePI; + + /** + * Describes if this node can be reduced to a trusted + * node by DP edges. + */ + private int reducableDP; + + /** + * Describes if this node can be reduced to a trusted + * node by DP and DI edges. + */ + private int reducableDI; + + /** + * Saves the length of the shortest path for a reducable node. + */ + private int reductionPathLength; + + /** + * Describes if this is a trusted node. + */ + private boolean trusted; + + /** + * Node id. + */ + private URI nodeId; + + /** + * The obligations related to this nodes reduction path. + */ + private Set obligations; + + /** + * The policy issuer of the policy represented by this node. + */ + private PolicyIssuer issuer; + + /** + * Creates a new untrusted node. + * + * @param policy The policy which is represented by the node. + */ + public ReductionGraphNode(AbstractPolicy policy) { + this.trusted = policy.hasTrustedIssuer(); + this.nodeId = policy.getId(); + if (this.trusted) { + this.reducablePP = YES; + this.reducablePI = YES; + this.reducableDP = YES; + this.reducableDI = YES; + this.reductionPathLength = 0; + } else { + this.reducablePP = UNKNOWN; + this.reducablePI = UNKNOWN; + this.reducableDP = UNKNOWN; + this.reducableDI = UNKNOWN; + this.reductionPathLength = UNKNOWN; + } + this.obligations = new HashSet(); + this.obligations.addAll(policy.getObligations()); + this.issuer = policy.getPolicyIssuer(); + + } + + /** + * @return Can this node be reduced to a trusted node by DP and DI edges. + * Meaning of the return values as in the static declarations of + * this class. + */ + public int getReducableDI() { + return this.reducableDI; + } + + /** + * Set new value for reducableDI. Meaning of the values as in the static + * declarations of this class. You also need to set the length of + * the reduction path. + * + * @param reducableDI + * @param reductionPathLength + */ + public void setReducableDI(int reducableDI, int reductionPathLength) { + this.reducableDI = reducableDI; + this.reductionPathLength = reductionPathLength; + } + + /** + * @return Can this node be reduced to a trusted node by DP edges. + * Meaning of the return values as in the static declarations of + * this class. + */ + public int getReducableDP() { + return this.reducableDP; + } + + /** + * Set new value for reducableDP. Meaning of the values as in the static + * declarations of this class. You also need to set the length of + * the reduction path. + * + * @param reducableDP + * @param reductionPathLength + */ + public void setReducableDP(int reducableDP, int reductionPathLength) { + this.reducableDP = reducableDP; + this.reductionPathLength = reductionPathLength; + } + + /** + * @return Can this node be reduced to a trusted node by PP and PI edges. + * Meaning of the return values as in the static declarations of + * this class. + */ + public int getReducablePI() { + return this.reducablePI; + } + + /** + * Set new value for reducablePI. Meaning of the values as in the static + * declarations of this class. You also need to set the length of + * the reduction path. + * + * @param reducablePI + * @param reductionPathLength + */ + public void setReducablePI(int reducablePI, int reductionPathLength) { + this.reducablePI = reducablePI; + this.reductionPathLength = reductionPathLength; + } + + /** + * @return Can this node be reduced to a trusted node by PP. + * Meaning of the return values as in the static declarations of + * this class. + */ + public int getReducablePP() { + return this.reducablePP; + } + + /** + * Set new value for reducablePP. Meaning of the values as in the static + * declarations of this class. You also need to set the length of + * the reduction path. + * + * @param reducablePP + * @param reductionPathLength + */ + public void setReducablePP(int reducablePP, int reductionPathLength) { + this.reducablePP = reducablePP; + this.reductionPathLength = reductionPathLength; + } + + /** + * Set the state of the reducable variables based on a reduction result + * and the type of reduction (i.e. PP, PP-PI, DP, DP-DI). + * + * @param result The reduction result (PERMIT or null) + * @param reductionType The int code determining the allowed edges + * for this type of reduction. A bitwise or + * of the codes from + * ReductionGraphEdge. + * @param delegationDepth The length of the reduction path. + */ + public void setState(Result result, int reductionType, + int delegationDepth) { + if (reductionType + == (ReductionGraphEdge.PP | ReductionGraphEdge.PI)) { + if (result == null) { + this.reducablePP = ReductionGraphNode.NO; + this.reducablePI = ReductionGraphNode.NO; + } else { + this.reducablePI = ReductionGraphNode.YES; + this.reductionPathLength = delegationDepth; + } + } else if (reductionType == ReductionGraphEdge.PP) { + if (result == null) { + this.reducablePP = ReductionGraphNode.NO; + } else { + this.reducablePP = ReductionGraphNode.YES; + this.reducablePI = ReductionGraphNode.YES; + this.reductionPathLength = delegationDepth; + } + } else if (reductionType + == (ReductionGraphEdge.DP | ReductionGraphEdge.DI)) { + if (result == null) { + this.reducableDP = ReductionGraphNode.NO; + this.reducableDI = ReductionGraphNode.NO; + } else { + this.reducableDI = ReductionGraphNode.YES; + this.reductionPathLength = delegationDepth; + } + } else if (reductionType == ReductionGraphEdge.DP){ + if (result == null) { + this.reducableDP = ReductionGraphNode.NO; + } else { + this.reducableDP = ReductionGraphNode.YES; + this.reducableDI = ReductionGraphNode.YES; + this.reductionPathLength = delegationDepth; + } + } else { + throw new RuntimeException("invalid reductionType ==" + + reductionType); + } + + } + + /** + * Determines if the node is already reduced for this type + * of reduction (i.e. PP, PP-PI, DP, DP-DI). + * + * @param reductionType The int code determining the allowed edges + * for this type of reduction. A bitwise or + * of the codes from + * ReductionGraphEdge. + * @return The result of the previous reduction. + */ + public Result previousReduction(int reductionType) { + if ((reductionType & ReductionGraphEdge.PP) + == ReductionGraphEdge.PP) { + if (this.reducablePP == ReductionGraphNode.YES) { + return new Result(Result.DECISION_PERMIT, this.obligations); + } else if ((reductionType & ReductionGraphEdge.PI) + == ReductionGraphEdge.PI) { + if (this.reducablePI == ReductionGraphNode.YES) { + return new Result(Result.DECISION_INDETERMINATE); + } else if (this.reducablePI == ReductionGraphNode.NO) { + return null; + } + } else if (this.reducablePP == ReductionGraphNode.NO) { + return null; + } + } else if ((reductionType & ReductionGraphEdge.DP) + == ReductionGraphEdge.DP) { + if (this.reducableDP == ReductionGraphNode.YES) { + return new Result(Result.DECISION_PERMIT, this.obligations); + } else if ((reductionType & ReductionGraphEdge.DI) + == ReductionGraphEdge.DI) { + if (this.reducableDI == ReductionGraphNode.YES) { + return new Result(Result.DECISION_INDETERMINATE); + } else if (this.reducableDI == ReductionGraphNode.NO) { + return null; + } + } else if (this.reducableDP == ReductionGraphNode.NO) { + return null; + } + } + //means this node has not yet been reduced + return new Result(Result.DECISION_DENY); + } + + /** + * @return True if this node is trusted. + */ + public boolean isTrusted() { + return this.trusted; + } + + /** + * @return The node id. + */ + public URI getNodeId() { + return this.nodeId; + } + + /** + * @return The policy issuer. + */ + public PolicyIssuer getIssuer() { + return (PolicyIssuer)this.issuer.clone(); + } + + /** + * @return A Set of Obligations related + * to this nodes reduction path. + */ + public Set getObligations() { + return Collections.unmodifiableSet(this.obligations); + } + + /** + * @return the reductionPathLength. + */ + public int getReductionPathLength() { + return this.reductionPathLength; + } + + /** + * Add new obligations to this nodes set of obligations. + * + * @param obligations the new obligations, a Set + * of Obligations. + */ + public void addObligations(Set obligations) { + this.obligations.addAll(obligations); + } + + /** + * Encode this node to string for debugging. + * + * @return String representation of the graph. + */ + public String toString() { + String [] values = {"Unknown", "NO", "YES"}; + return this.nodeId.toString() + "{PP=" + values[this.reducablePP+1] + + ", PI=" + values[this.reducablePI+1] + ", DP=" + + values[this.reducableDP+1] + ", DI=" + + values[this.reducableDI+1] + "}"; + } + +} diff --git a/GenericBreakGlass-XACML/src/com.sun.xacml/src/test/java/com/sun/xacml/AppTest.java b/GenericBreakGlass-XACML/src/com.sun.xacml/src/test/java/com/sun/xacml/AppTest.java new file mode 100644 index 0000000..74a91ec --- /dev/null +++ b/GenericBreakGlass-XACML/src/com.sun.xacml/src/test/java/com/sun/xacml/AppTest.java @@ -0,0 +1,66 @@ +package com.sun.xacml; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Properties; + +import org.apache.log4j.PropertyConfigurator; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } + + public static void main(String[] args) throws IOException, ParsingException, UnknownIdentifierException { + Properties log4jProps = new Properties(); + log4jProps.load(new BufferedInputStream(new FileInputStream(new File("../pdp/src/test/log4j.properties")))); + PropertyConfigurator.configure(log4jProps); + // //AppTest test = new AppTest("pdpServer test"); + //test.testApp(); + foo(); + } + + private static void foo() throws FileNotFoundException, ParsingException, UnknownIdentifierException { + + ConfigurationStore config = new ConfigurationStore(new FileInputStream(new File("src/main/resources/policy-config.xml")), "src/main/resources/"); + + //PDP pdp = + new PDP(config.getDefaultPDPConfig()); + + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/pom.xml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/pom.xml new file mode 100644 index 0000000..e64f04c --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/pom.xml @@ -0,0 +1,76 @@ + + + 4.0.0 + + eu.aniketos.securebpmn.xacml + eu.aniketos.securebpmn.xacml.parent + 1.0 + ../eu.aniketos.securebpmn.xacml.parent/pom.xml + + eu.aniketos.securebpmn.xacml.api + 0.1 + jar + SecureBPMN XACML - Core API + http://maven.apache.org + + 2.5.1 + UTF-8 + + + ${artifactId} + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.5 + 1.5 + + + + + org.apache.cxf + cxf-java2ws-plugin + + ${cxf-version} + + + org.apache.cxf + cxf-rt-frontend-jaxws + + ${cxf-version} + + + org.apache.cxf + cxf-rt-frontend-simple + + ${cxf-version} + + + + + process-classes + process-classes + + eu.aniketos.securebpmn.xacml.api.autho.IPDP + true + true + + + java2ws + + + + + + + + + junit + junit + [4.8,) + test + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/pom_pdpwsdl_gen.xml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/pom_pdpwsdl_gen.xml new file mode 100644 index 0000000..6ec1462 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/pom_pdpwsdl_gen.xml @@ -0,0 +1,61 @@ + + + 4.0.0 + + eu.aniketos.securebpmn.xacml + eu.aniketos.securebpmn.xacml.parent + 1.0 + ../eu.aniketos.securebpmn.xacml.parent/pom.xml + + pdp-wsdlclient + jar + 0.1 + pdp + http://maven.apache.org + + ${artifactId} + target/generated/cxf/src + target/generated/cxf/bin + + + + org.apache.maven.plugins + maven-compiler-plugin + + 1.5 + 1.5 + + + + + org.apache.cxf + cxf-codegen-plugin + + + generate-sources + generate-sources + + ${project.build.directory}/generated/cxf/src + + + ${project.build.directory}/generated/wsdl/IPDP.wsdl + + + + + wsdl2java + + + + + + + + + junit + junit + 3.8.1 + test + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/ErrorType.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/ErrorType.java new file mode 100644 index 0000000..e90be22 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/ErrorType.java @@ -0,0 +1,29 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api; + +import javax.xml.bind.annotation.XmlType; + +/** + * + * Defines the main type of the SecurityError + */ +@XmlType(namespace="http://aniketos.eu/") +public enum ErrorType { + AUTHENTICATION_FAILED, + AUTHORIZATION_FAILED, + CONFIGURATION_ERROR +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/ReasonType.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/ReasonType.java new file mode 100644 index 0000000..91572e8 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/ReasonType.java @@ -0,0 +1,39 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api; + +import javax.xml.bind.annotation.XmlType; + +/** + * Defines a more detailed reason for the error + * + */ +@XmlType(namespace="http://aniketos.eu/") +public enum ReasonType { + SSO_ENGINE_ERROR, + MISSING_CAS_TICKET, + MISSING_USER, + INVALID_CAS_TICKET, + INVALID_USERNAME_PASSWORD, + CAS_TICKET_WRONG_SERVICE, + + INVALID_PARAMETERS, + PDE_ENGINE_ERROR, + BREAK_GLASS, + UNDEFINED_POLICY, + INVALID_XACML, + DENY +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/SecurityError.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/SecurityError.java new file mode 100644 index 0000000..6fece8d --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/SecurityError.java @@ -0,0 +1,199 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api; + +import javax.xml.ws.WebFault; + + +@WebFault(targetNamespace="aniketos.eu/") //, name="SecurityError" name="eu.aniketos.SecurityError", faultBean="eu.aniketos.SecurityError +public class SecurityError extends Exception { + + private static final long serialVersionUID = 1031874369988364332L; + + protected ErrorType error; + protected ReasonType reason; + + protected String message; + + protected long evaluationId; + + private static final String[] error_messages = { + "Authentication failed", + "Authorization failed", + "Configuration error" + }; + + + private static final String[] reason_messages = { + "SSO Engine error", + "Missing Security Token", + "Missing authenticated user", + "Invalid Security Token", + "Invalid Username or Password", + "Security Token not valid for requested service", + + "Invalid parameters", + "PDE Engine error", + "Access requires break-glass", + "No policy defined for requested resource", + "Invalid XACML Defintion", + "User is not permitted to access the requested resource" + }; + + /** + * Creating a new SecurityError, message is generated from error and reason + * + * @param error + * @param reason + */ + public SecurityError(ErrorType error, ReasonType reason) { + super(generateMessage(error, reason)); + this.message = super.getMessage(); + this.error = error; + this.reason = reason; + } + + /** + * Creating a new SecurityError, message is generated from error and reason, enhanced with additionalMessage + * + * @param error + * @param reason + * @param additionalMessage + */ + public SecurityError(ErrorType error, ReasonType reason, String additionalMessage) { + super(generateMessage(error, reason, additionalMessage)); + this.message = super.getMessage(); + this.error = error; + this.reason = reason; + } + + /** + * Creating a new SecurityError, message is generated from error and reason + * + * @param error + * @param reason + * @param exception + */ + public SecurityError(ErrorType error, ReasonType reason, Throwable exception) { + super(generateMessage(error, reason), exception); + this.message = super.getMessage(); + this.error = error; + this.reason = reason; + } + /** + * Creating a new SecurityError, message is generated from error and reason, enhanced with additionalMessage + * + * @param error + * @param reason + * @param additionalMessage + * @param exception + */ + public SecurityError(ErrorType error, ReasonType reason, String additionalMessage, Throwable exception) { + super(generateMessage(error, reason, additionalMessage), exception); + this.message = super.getMessage(); + this.error = error; + this.reason = reason; + } + + /** + * Creating a new Security Error with a free defined message. Should only be used to create a new SecurityError in Proxies, wrapping a received error + * @param message + * @param error + * @param reason + */ + public SecurityError(String message, ErrorType error, ReasonType reason) { + super(message); + this.message = super.getMessage(); + this.error = error; + this.reason = reason; + } + + /** + * returns the main error type for this SecurityError + * + * @return + */ + public ErrorType getError() { + return error; + } + /** + * should not be used to create a new message; is required for web service interfaces + * @param error + */ + public void setError(ErrorType error) { + this.error = error; + } + + /** + * returns the more detailed reason for this SecurityError + * + * @return + */ + public ReasonType getReason() { + return reason; + } + + /** + * should not be used to create a new message; is required for web service interfaces + * @param reason + */ + public void setReason(ReasonType reason) { + this.reason = reason; + } + + @Override + public String getMessage() { + return this.message; + } + + /** + * DO NOT USE! Required for SCA + * @param message + */ + public void setMessage(String message) { + //required for SCA? i.e., finding "message" as attribute with getters and setters + this.message = message; + } + + public long getEvaluationId() { + return evaluationId; + } + + public void setEvaluationId(long evaluationId) { + this.evaluationId = evaluationId; + } + + +// /** +// * DO NOT USE! Required for SCA +// * +// */ +// public SecurityError() { +// +// } + + + + private static String generateMessage(ErrorType error, ReasonType reason) { + return error_messages[error.ordinal()] + ": " + reason_messages[reason.ordinal()]; + + } + + private static String generateMessage(ErrorType error, ReasonType reason, String additionalMessage) { + return generateMessage(error, reason) + " (" + additionalMessage + ")"; + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/AttributeIdentifier.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/AttributeIdentifier.java new file mode 100644 index 0000000..43eabb3 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/AttributeIdentifier.java @@ -0,0 +1,99 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.autho; + +import java.net.URI; + + +/** + * + * Allows to identify attributes by its defining URIs, e.g., as key for hash tables + *
+ * As attributes within xacml cannot be uniquely identified using their java objects, this + * class can be used as such a unique identification + * + */ +public class AttributeIdentifier { + + protected URI category, attributeType, attributeId, issuer; + + public AttributeIdentifier(URI category, URI attributeType, URI attributeId, URI issuer) { + if ( category == null || attributeId == null || attributeType == null ) { + throw new RuntimeException("category, type and ID must not be null!"); + } + this.category = category; + this.attributeType = attributeType; + this.attributeId = attributeId; + this.issuer = issuer; + } + + + public AttributeIdentifier() { + //needed for web service stuff.. should not be used otherwise + } + + + @Override + public int hashCode() { + if ( issuer == null ) { + return category.hashCode() + attributeId.hashCode() + attributeType.hashCode(); + } else { + return category.hashCode() + attributeId.hashCode() + attributeType.hashCode() + issuer.hashCode(); + } + + } + + @Override + public boolean equals(Object o) { + if ( o instanceof AttributeIdentifier) { + AttributeIdentifier a = (AttributeIdentifier) o; + if ( this.category.equals(a.category) && + this.attributeType.equals(a.attributeType) && + this.attributeId.equals(a.attributeId) && + ((this.issuer == null && a.issuer == null) || this.issuer.equals(a.issuer))) { + return true; + } else { + return false; + } + + } else { + return false; + } + } + + + @Override + public String toString() { + return "[category]" + category + "[category];[type]" + attributeType + "[type];[id]" + attributeId + "[id];[issuer]" + issuer + "[issuer]"; + } + + + public URI getCategory() { + return category; + } + + public URI getAttributeType() { + return attributeType; + } + + public URI getAttributeId() { + return attributeId; + } + + public URI getIssuer() { + return issuer; + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/AuthoAttribute.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/AuthoAttribute.java new file mode 100644 index 0000000..aeba74f --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/AuthoAttribute.java @@ -0,0 +1,83 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.autho; + +import java.net.URI; + +import javax.xml.bind.annotation.XmlType; + +@XmlType(namespace="http://aniketos.eu/autho") +public class AuthoAttribute { + + public static final URI OBLIGATION_CATEGORY = URI.create("urn:category:obligation"); + + enum STATUS { + MISSING, + RESOLVED, + RESOLUTION_ERROR + } + private Long id; + + protected AttributeIdentifier attrId; + protected String value; + + protected boolean underRevision; + + //TODO save, if -) within initial request -) requested through + public static final int INITIAL_REQUST = 0x1, ATTR_RESOLVER = 0x2; + + + + public AuthoAttribute() { + // needed for web service stuff + } + + public AuthoAttribute(AttributeIdentifier attrId, String value) { + this.attrId = attrId; + this.value = value; + } + + + + public AuthoAttribute(URI categoryId, URI attributeId, URI dataType, String value) { + this.attrId = new AttributeIdentifier(categoryId, dataType, attributeId, null); + this.value = value; + } + + public AttributeIdentifier getAttributeIdentifier() { + return this.attrId; + } + + public void setAttributeIdentifier(AttributeIdentifier attrId) { + this.attrId = attrId; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getId() { + return id; + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/AuthoInfo.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/AuthoInfo.java new file mode 100644 index 0000000..4e6956f --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/AuthoInfo.java @@ -0,0 +1,46 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.autho; + +import java.util.List; + +import eu.aniketos.securebpmn.xacml.api.idm.IdInfo; + +public class AuthoInfo extends IdInfo { + + public AuthoInfo() { + + } + + public AuthoInfo(IdInfo idInfo) { + super(idInfo); //TODO copy arguments + } + + //List of attributes assigned to the user, e.g., roles, etc. + //for usual, this information is obtained by the IDM + protected List userAttributes; + + protected String IDManager; + + + +// String getProxyGrantingTicket(); +// String getAuthenticatedUser(); +// SecurityError getException(); +// boolean hasError(); +// ErrorType getError(); +// ReasonType getReason(); +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/AuthoObligation.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/AuthoObligation.java new file mode 100644 index 0000000..6425980 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/AuthoObligation.java @@ -0,0 +1,56 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.autho; + +import java.net.URI; +import java.util.Collection; + +import javax.xml.bind.annotation.XmlType; + +@XmlType(namespace="http://aniketos.eu/autho") +public class AuthoObligation { + + private Long id; + private String type; + private Collection parameters; + + public AuthoObligation() { + + } + + public AuthoObligation(URI type) { + this.type = type.toString(); + } + + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + public Collection getParameters() { + return parameters; + } + public void setParameters(Collection parameters) { + this.parameters = parameters; + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/AuthoResult.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/AuthoResult.java new file mode 100644 index 0000000..7d74480 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/AuthoResult.java @@ -0,0 +1,155 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.autho; + +import java.util.List; + +import javax.xml.bind.annotation.XmlType; + +import eu.aniketos.securebpmn.xacml.api.idm.IdInfo; + +@XmlType(namespace="http://eu.aniketos/autho") +public class AuthoResult { + +// public enum DECISION { +// DECISION_PERMIT, +// DECISION_DENY, +// DECISION_INDETERMINATE, +// DECISION_NOT_APPLICABLE, +// INVALID_DECISION; +// +// private String[] messages = { "Permit", "Deny", +// "Indeterminate", +// "NotApplicable", "Invalid" }; +// +// public String getMessage() { +// return messages[this.ordinal()]; +// } +// +// public static DECISION getFromInt(int decision) { +// switch (decision) { +// case 0: +// return DECISION_PERMIT; +// case 1: +// return DECISION_DENY; +// case 2: +// return DECISION_INDETERMINATE; +// case 3: +// return DECISION_NOT_APPLICABLE; +// case 5: +// return INVALID_DECISION; +// } +// return null; +// } +// } + + private Long evaluationId; + + private Long id; + + /** + * The user for which the evaluation was done. Especially needed, if the + * pep provides the raw AuthInfo to the PDP + */ + private IdInfo idInfo; + + private Decision decision; + + + + private List statusCode; + + private String statusMessage; + + private List missingAttributes; + + private List obligations; + + public String toString() { + StringBuffer buff =new StringBuffer(decision.toString()); + buff.append(", statusCodes: "); + for (String code : statusCode) { + buff.append(code); buff.append(", "); + } + buff.append(", statusMessage: "); buff.append(statusMessage); + buff.append(" obligations: "); buff.append(obligations == null ? "null" : obligations.size()); + return buff.toString(); + } + + public IdInfo getIdInfo() { + return idInfo; + } + + public void setIdInfo(IdInfo idInfo) { + this.idInfo = idInfo; + } + + public Decision getDecision() { + return decision; + } + + public void setDecision(Decision decision) { + this.decision = decision; + } + + public List getMissingAttributes() { + return missingAttributes; + } + + public void setMissingAttributes(List missingAttributes) { + this.missingAttributes = missingAttributes; + } + + public List getObligations() { + return obligations; + } + + public void setObligations(List obligations) { + this.obligations = obligations; + } + + public void setEvaluationId(Long evaluationId) { + this.evaluationId = evaluationId; + } + + public Long getEvaluationId() { + return evaluationId; + } + + public void setId(Long id) { + this.id = id; + } + + public Long getId() { + return id; + } + + public List getStatusCode() { + return statusCode; + } + + public void setStatusCode(List statusCode) { + this.statusCode = statusCode; + } + + public String getStatusMessage() { + return statusMessage; + } + + public void setStatusMessage(String statusMessage) { + this.statusMessage = statusMessage; + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/Decision.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/Decision.java new file mode 100644 index 0000000..1ca8435 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/Decision.java @@ -0,0 +1,52 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.autho; + +import javax.xml.bind.annotation.XmlType; + +@XmlType(namespace="http://aniketos.eu/autho") +public enum Decision { + DECISION_PERMIT, + DECISION_DENY, + DECISION_INDETERMINATE, + DECISION_NOT_APPLICABLE, + INVALID_DECISION; + + private String[] messages = { "Permit", "Deny", + "Indeterminate", + "NotApplicable", "Invalid" }; + + public String getMessage() { + return messages[this.ordinal()]; + } + + public static Decision getFromInt(int decision) { + switch (decision) { + case 0: + return DECISION_PERMIT; + case 1: + return DECISION_DENY; + case 2: + return DECISION_INDETERMINATE; + case 3: + return DECISION_NOT_APPLICABLE; + case 5: + return INVALID_DECISION; + } + return null; + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/DesignatorAttribute.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/DesignatorAttribute.java new file mode 100644 index 0000000..8718584 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/DesignatorAttribute.java @@ -0,0 +1,75 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.autho; + +import java.net.URI; +import java.util.List; +import java.util.Vector; + +/** + * + * Attribtues resolved at runtime by the com.sun.xacml.attr.AttributeDesignator + * + */ +public class DesignatorAttribute { + + protected AttributeIdentifier attrId; + + + protected List values; + + public DesignatorAttribute(AttributeIdentifier attrId) { + this.attrId = attrId; + } + + public DesignatorAttribute(URI attributeId, URI dataType, URI categoryId) { + this.attrId = new AttributeIdentifier(categoryId, dataType, attributeId, null); + } + + public AttributeIdentifier getAttrId() { + return attrId; + } + + public void setAttrId(AttributeIdentifier attrId) { + this.attrId = attrId; + } + + public List getValues() { + return values; + } + public void setValues(List values) { + this.values = values; + } + + public void addBagValue(String bagValue) { + if ( values == null ) { + values = new Vector(); + } + values.add(bagValue); + } + + public List getBagValues() { + return this.values; + } + + public boolean isSingleValue() { + return values!= null && values.size() == 1 ? true : false; + } + + public boolean isEmptyValue() { + return values == null ? true : false; + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IAuthoManager.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IAuthoManager.java new file mode 100644 index 0000000..735e9b8 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IAuthoManager.java @@ -0,0 +1,24 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.autho; + +import eu.aniketos.securebpmn.xacml.api.idm.IdInfo; + +public interface IAuthoManager { + + AuthoInfo getIdentityInformation(IdInfo idInfo); + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IContextProvider.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IContextProvider.java new file mode 100644 index 0000000..084f072 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IContextProvider.java @@ -0,0 +1,36 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.autho; + +import java.util.List; + +public interface IContextProvider { + /** + * resolves one attribute + * + * writes the result to attr and returns it as string + * + * @param attr + * @return + */ + String resolveAttribute(AuthoAttribute attr); + /** + * resolves a set of attributes, returns number of errors + * @param attr + * @return + */ + int resolveAttributes(List attr); +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IObligationService.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IObligationService.java new file mode 100644 index 0000000..20b1be2 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IObligationService.java @@ -0,0 +1,28 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.autho; + +import java.util.List; + +public interface IObligationService { + + public boolean supportsObligation(AuthoObligation obligation); + + public boolean fulfillObligation(AuthoObligation obligation); + + public boolean fulfillObligation(List obligation); + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IPDP.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IPDP.java new file mode 100644 index 0000000..96a18d4 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IPDP.java @@ -0,0 +1,42 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.autho; + +import java.util.List; + +import javax.jws.WebParam; +import javax.jws.WebService; + +import eu.aniketos.securebpmn.xacml.api.SecurityError; +import eu.aniketos.securebpmn.xacml.api.idm.IdInfo; + +@WebService(targetNamespace="aniketos.eu/autho") +public interface IPDP { + + String evaluateXACML(@WebParam(name="xacmlRequ")String xacmlRequest) throws SecurityError; + + AuthoResult evaluate(@WebParam(name="idInfo") IdInfo idInfo, + @WebParam(name="resource") String resource, + @WebParam(name="action")String action, + @WebParam(name="attributes") List attributes) throws SecurityError; + + String getXACMLPEPConfig(); + + boolean logBreakGlassAccess(@WebParam(name="evaluationId") long evaluationId, @WebParam(name="justification") String justification); + + void notifyStateChange(@WebParam(name="evaluationId") long evaluationId) throws SecurityError; + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IPDPManagement.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IPDPManagement.java new file mode 100644 index 0000000..a04a24b --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IPDPManagement.java @@ -0,0 +1,37 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.autho; + +import java.util.List; + +public interface IPDPManagement { + + long loadPolicyVersion(long version); + + boolean setEmergencyLeve(long level, boolean active); + + // role management + List getRoles(String userId); + + void addRole(String userId, String role); + + void removeRole(String userId, String role); + + + //patient - physician relationship + +} + \ No newline at end of file diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IPDPStateManagement.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IPDPStateManagement.java new file mode 100644 index 0000000..a1bbb7f --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/autho/IPDPStateManagement.java @@ -0,0 +1,35 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.autho; + +import eu.aniketos.securebpmn.xacml.api.SecurityError; +import eu.aniketos.securebpmn.xacml.api.log.AccessControlRequest; + +/** + * + * This interface allows the PDP to pass an access control request + * to the PDP State module and update the pdp state according to the + * executed action + * + */ +public interface IPDPStateManagement { + /** + * update the PDPState according to the access control request + * @param execRequest + */ + void updatePDPState(AccessControlRequest execRequest) throws SecurityError; + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/AuthInfo.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/AuthInfo.java new file mode 100644 index 0000000..e6b9459 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/AuthInfo.java @@ -0,0 +1,63 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.idm; + + +/** + * contains (technology neutral) authentication information information, e.g., + *

    + *
  • SAML Token
  • + *
  • CAS Token
  • + *
  • OpenID Token
  • + *
+ * + */ +public class AuthInfo { + protected String authProviderId; + protected String token; + protected IdInfo idInfo; + + public AuthInfo() { + + } + + public AuthInfo(String authProviderId, String token) { + this.authProviderId = authProviderId; + this.token = token; + } + + protected AuthInfo(IdInfo idInfo) { + this.idInfo = idInfo; + } + + public String getAuthProviderId() { + return authProviderId; + } + + public void setAuthProviderId(String authProviderId) { + this.authProviderId = authProviderId; + } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } + + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/IIDProvider.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/IIDProvider.java new file mode 100644 index 0000000..d117e0c --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/IIDProvider.java @@ -0,0 +1,38 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.idm; + +/** + * + * Resovles the AuthInfo with aim of a ID Provider + * + * + */ +public interface IIDProvider { + /** + * Resolved the AuthInfo t + * + * @param authInfo + * @return + */ + IdInfo authenticate(AuthInfo authInfo); + + boolean isValidInfo(String info); + + AuthInfo createAuthInfo(String info); + + String getProviderID(); +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/IIDProviderFactory.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/IIDProviderFactory.java new file mode 100644 index 0000000..d8bcc63 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/IIDProviderFactory.java @@ -0,0 +1,23 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.idm; + +import java.net.URL; + +public interface IIDProviderFactory { + IIDProvider getClient(URL casServer, URL service); + IIDProviderProxy getProxyClient(URL casServer, URL service); +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/IIDProviderProxy.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/IIDProviderProxy.java new file mode 100644 index 0000000..8b9e3ad --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/IIDProviderProxy.java @@ -0,0 +1,26 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.idm; + +import java.net.URL; + +public interface IIDProviderProxy extends IIDProvider { + + IdInfo authenticate(AuthInfo authInfo, boolean proxy); + + String getProxyTicket(IdInfo idInfo, URL targetService); + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/ITicketProvider.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/ITicketProvider.java new file mode 100644 index 0000000..dc4a5f7 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/ITicketProvider.java @@ -0,0 +1,55 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.idm; + +import java.net.URL; + +import eu.aniketos.securebpmn.xacml.api.SecurityError; + +public interface ITicketProvider { + /** + * This method logs in at the SSO Engine (i.e., the CAS Server) + *
+ * In case of any error (e.g., ConnectException, IOException) which result out of an + * incorrect infrastructure, this functions returns null, which signals "not logged in" + * + * @param username used to login at the SSO Engine (i.e., CAS Server) + * @param password used to login at the SSO Engine (i.e., CAS Server) + * @return the value of the Ticket Granting Cookie. CAUTION If the return value is null, + * the login has not been successful, it has to be called login again! + */ + public String login(String username, String password) throws SecurityError; + + /** + * This function is used for every (Web Service) Call that is done in the SoKNOS system, as for each of these + * call a Service Ticket (CAS Ticket) is required. + * + * @param service The URL of the service for which the service ticket is required + * @return + * @throws InvalidCASTicketException This exception is thrown, if there is no valid CAS Ticket available (i.e., + * the user is not logged in or the CAS session expired, etc.) + */ + public AuthInfo getServiceTicket(URL service) throws SecurityError; + + /** + * Invalidates any existing active session. If no active session is available, no error is thrown. If + * this function is called, for further getServiceTicket() calls a (re)login is required + * + * @return true, if logout has been successful or no active session was found and false, + * if any error occured (e.g., network error) + */ + public boolean logout(); +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/ITicketProviderFactory.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/ITicketProviderFactory.java new file mode 100644 index 0000000..2224299 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/ITicketProviderFactory.java @@ -0,0 +1,22 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.idm; + +import java.net.URL; + +public interface ITicketProviderFactory { + ITicketProvider getTicketProvider(URL idProvder); +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/IdInfo.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/IdInfo.java new file mode 100644 index 0000000..f541fff --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/idm/IdInfo.java @@ -0,0 +1,94 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.idm; + +import java.util.List; + +import javax.xml.bind.annotation.XmlType; + +/** + * + * Contains authentication information (ID Provider) and authorization + * relevant information (identity management) about the user + * + */ +@XmlType(namespace="http://idm.aniketos.eu/") +public class IdInfo { + + + + //the resolved userID + protected String userId; // Required + + //ID Provider which was used to resolve the userID + protected String IdProvider; // Required + + //List of services which are in the call chain to the current instance + protected List callChain; // Optional, technology dependant, e.g., CAS + + public IdInfo(String userId) { + this.userId = userId; + } + + + public IdInfo(String userId, String IdProvider, List callChaind) { + this.userId = userId; + this.IdProvider = IdProvider; + this.callChain = callChaind; + } + + protected IdInfo(IdInfo copy) { + this.userId = copy.userId; + this.IdProvider = copy.IdProvider; + this.callChain = copy.callChain; + } + + protected IdInfo() { + + } + + + public String getUserId() { + return userId; + } + + + public void setUserId(String userId) { + this.userId = userId; + } + + + public String getIdProvider() { + return IdProvider; + } + + + public void setIdProvider(String idProvider) { + IdProvider = idProvider; + } + + + public List getCallChain() { + return callChain; + } + + + public void setCallChain(List callChain) { + this.callChain = callChain; + } + + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/log/AccessControlRequest.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/log/AccessControlRequest.java new file mode 100644 index 0000000..42937d4 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/log/AccessControlRequest.java @@ -0,0 +1,216 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.log; + +import java.net.URI; +import java.util.Collection; +import java.util.Date; +import java.util.List; + +import eu.aniketos.securebpmn.xacml.api.autho.AuthoAttribute; +import eu.aniketos.securebpmn.xacml.api.autho.AuthoObligation; +import eu.aniketos.securebpmn.xacml.api.autho.AuthoResult; +import eu.aniketos.securebpmn.xacml.api.autho.DesignatorAttribute; +import eu.aniketos.securebpmn.xacml.api.idm.IdInfo; + +public class AccessControlRequest extends LogEntry { + + private Long evaluationId; + private long policyVersion; + private Date execTime; + + //request part + private IdInfo idInfo; + private URI resource; + private String action; + + private Collection attributes; + + //RequestCtx + private Object request; + private String xacmlRequest; + + + private AuthoResult result; + private List obligations; + + private List designAttrs; + + //ResponseCtx + private Object response; + private String xacmlResponse; + + + private long duration; + private String errorMessage; + + public AccessControlRequest() { + super(null, Log_Type.ACCESS_REQUEST); + } + + public AccessControlRequest(Long evaluationId, String xacmlRequest) { + super(new Date(), Log_Type.ACCESS_REQUEST); + this.evaluationId = evaluationId; + this.xacmlRequest = xacmlRequest; + } + + public AccessControlRequest(Long evaluationId, IdInfo idInfo, + URI resource, String action, List attributes) { + super(new Date(), Log_Type.ACCESS_REQUEST); + this.evaluationId = evaluationId; + this.idInfo = idInfo; + this.resource = resource; + this.action = action; + this.attributes = attributes; + } + + public void finished(Object request, Object response, String xacmlResponse, + Date execTime, long policyVersion, + List designAttrs) { + duration = new Date().getTime() - getArrival().getTime(); + this.setRequest(request); + this.setResponse(response); + this.execTime = execTime; + this.policyVersion = policyVersion; + this.xacmlResponse = xacmlResponse; + this.designAttrs = designAttrs; + } + + public void finished(Object request, Object response, AuthoResult result, + Date execTime, long policyVersion, + List designAttrs) { + duration = new Date().getTime() - getArrival().getTime(); + this.setRequest(request); + this.setResponse(response); + this.execTime = execTime; + this.policyVersion = policyVersion; + this.result = result; + this.designAttrs = designAttrs; + } + + + + + public Long getEvaluationId() { + return evaluationId; + } + public void setEvaluationId(Long evaluationId) { + this.evaluationId = evaluationId; + } + public String getXacmlRequest() { + return xacmlRequest; + } + public void setXacmlRequest(String xacmlRequest) { + this.xacmlRequest = xacmlRequest; + } + public URI getResource() { + return resource; + } + public void setResource(URI resource) { + this.resource = resource; + } + public String getAction() { + return action; + } + public void setAction(String action) { + this.action = action; + } + public Collection getAttributes() { + return attributes; + } + public void setAttributes(Collection attributes) { + this.attributes = attributes; + } + public AuthoResult getResult() { + return result; + } + public void setResult(AuthoResult result) { + this.result = result; + } + public long getDuration() { + return duration; + } + public void setDuration(long duration) { + this.duration = duration; + } + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + public String getErrorMessage() { + return errorMessage; + } + public void setXacmlResponse(String xacmlResponse) { + this.xacmlResponse = xacmlResponse; + } + public String getXacmlResponse() { + return xacmlResponse; + } + public void setObligations(List obligations) { + this.obligations = obligations; + } + public List getObligations() { + return obligations; + } + + public void setPolicyVersion(long policyVersion) { + this.policyVersion = policyVersion; + } + + public long getPolicyVersion() { + return policyVersion; + } + + public void setRequest(Object request) { + this.request = request; + } + + public Object getRequest() { + return request; + } + + public void setResponse(Object response) { + this.response = response; + } + + public Object getResponse() { + return response; + } + + public List getDesignatorAttributes() { + return this.designAttrs; + } + + public void setDesignatorAttributes(List designAttrs) { + this.designAttrs = designAttrs; + } + + public IdInfo getIdInfo() { + return idInfo; + } + + public void setIdInfo(IdInfo idInfo) { + this.idInfo = idInfo; + } + + public Date getExecTime() { + return execTime; + } + + public void setExecTime(Date execTime) { + this.execTime = execTime; + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/log/EventNotification.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/log/EventNotification.java new file mode 100644 index 0000000..c94899a --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/log/EventNotification.java @@ -0,0 +1,59 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.log; + +import java.util.Date; + +public class EventNotification extends LogEntry { + + protected EventNotification(Date arrival, Log_Type type) { + super(arrival, type); + } + + private Long id; + + private Long evaluationId; + private Log_Type type; + private String message; + + + public Long getEvaluationId() { + return evaluationId; + } + public void setEvaluationId(Long evaluationId) { + this.evaluationId = evaluationId; + } + public Log_Type getType() { + return type; + } + public void setType(Log_Type type) { + this.type = type; + } + public String getMessage() { + return message; + } + public void setMessage(String message) { + this.message = message; + } + public void setId(Long id) { + this.id = id; + } + public Long getId() { + return id; + } + + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/log/ILogStore.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/log/ILogStore.java new file mode 100644 index 0000000..ce787b1 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/log/ILogStore.java @@ -0,0 +1,42 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.log; + + + +public interface ILogStore { + /** + * store the provided AccessControlRequest to the log store; + * this function should not block and return immediately, i.e., + * the request should be put on a queue and handled by another + * thread + * @param requ + */ + void storeAccessControlRequest(AccessControlRequest requ); + + boolean logBreakGlassAccess(); + + boolean shutdown(); + + /** + * returns a new unique ID; this ID should be used to create a new + * AccessControlRequest + * @return + */ + Long getNewEvaluationId(); + + AccessControlRequest getAccessControlRequest(Long evaluationId); +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/log/LogEntry.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/log/LogEntry.java new file mode 100644 index 0000000..db66d2a --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/log/LogEntry.java @@ -0,0 +1,49 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.log; + +import java.util.Date; + +public abstract class LogEntry { + + public enum Log_Type { + ACCESS_REQUEST, + BREAK_GLASS + } + + protected LogEntry(Date arrival, Log_Type type) { + this.arrival = arrival; + this.type = type; + } + + private Date arrival; +// private byte[] chkSum; +// +// private Long previous; + + private Log_Type type; + + public Date getArrival() { + return arrival; + } + public void setArrival(Date arrival) { + this.arrival = arrival; + } + + public Log_Type getLogtype() { + return type; + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/pep/IObligationContext.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/pep/IObligationContext.java new file mode 100644 index 0000000..a1aa875 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/pep/IObligationContext.java @@ -0,0 +1,22 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.pep; + +import eu.aniketos.securebpmn.xacml.api.autho.AuthoObligation; + +public interface IObligationContext { + public void fulfill(AuthoObligation obligation); +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/pep/IPEP.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/pep/IPEP.java new file mode 100644 index 0000000..cd432fe --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/pep/IPEP.java @@ -0,0 +1,29 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.pep; + +import java.util.List; + +import eu.aniketos.securebpmn.xacml.api.autho.AuthoAttribute; +import eu.aniketos.securebpmn.xacml.api.idm.IdInfo; + +public interface IPEP { + + boolean authorized(String subjectId, String resource, String action, List ctxAttrs); + + boolean authorized(IdInfo idInfo, String resource, String action, List ctxAttrs); + +} \ No newline at end of file diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/pep/IPEPProxy.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/pep/IPEPProxy.java new file mode 100644 index 0000000..7bf351b --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/main/java/eu/aniketos/securebpmn/xacml/api/pep/IPEPProxy.java @@ -0,0 +1,22 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api.pep; + +import eu.aniketos.securebpmn.xacml.api.idm.IIDProviderProxy; + +public interface IPEPProxy extends IIDProviderProxy { + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/test/java/eu/aniketos/securebpmn/xacml/api/AppTest.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/test/java/eu/aniketos/securebpmn/xacml/api/AppTest.java new file mode 100644 index 0000000..3c3b1f2 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.api/src/test/java/eu/aniketos/securebpmn/xacml/api/AppTest.java @@ -0,0 +1,53 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.api; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.parent/pom.xml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.parent/pom.xml new file mode 100644 index 0000000..43dd7f8 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.parent/pom.xml @@ -0,0 +1,56 @@ + + + 4.0.0 + eu.aniketos.securebpmn.xacml + eu.aniketos.securebpmn.xacml.parent + 1.0 + pom + SecureBPMN XACML - Parent project + + 0.12.0 + + + ../com.sun.xacml + ../com.sun.xacml.support + ../eu.aniketos.securebpmn.xacml.api + ../eu.aniketos.securebpmn.xacml.support + ../eu.aniketos.securebpmn.xacml.pdpstate + ../eu.aniketos.securebpmn.xacml.pdp + + + + + org.eclipse.tycho + tycho-maven-plugin + ${tycho-version} + true + + + org.eclipse.tycho + target-platform-configuration + ${tycho-version} + + p2 + + + + + + + junit + junit + [4.8,) + test + + + log4j + log4j + [1.2,) + + + xalan + xalan + 2.7.1 + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/analysis-pdp.pom.xml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/analysis-pdp.pom.xml new file mode 100644 index 0000000..996e3e0 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/analysis-pdp.pom.xml @@ -0,0 +1,136 @@ + + + 4.0.0 + eu.aniketos.securebpmn.xacml + eu.aniketos.securebpmn.xacml.parent + 1.0 + ../eu.aniketos.securebpmn.xacml.parent/pom.xml + + eu.aniketos.securebpmn.xacml.pdp + jar + 0.1 + SecureBPMN XACML - PDP + http://maven.apache.org + + 2.5.1 + + + ${artifactId} + + + + 2.3.2 + org.apache.maven.plugins + maven-compiler-plugin + + 1.5 + 1.5 + + + + org.codehaus.mojo + aspectj-maven-plugin + 1.3 + + 1.5 + + + + + compile + + + true + true + 1.5 + + + com.sun.xacml + sun-xacml + + + + + + + + + + + + + junit + junit + [4.8,) + test + + + eu.aniketos.securebpmn.xacml + com.sun.xacml + 0.1 + compile + + + eu.aniketos.securebpmn.xacml + com.sun.xacml.support + 0.1 + + + eu.aniketos.securebpmn.xacml + eu.aniketos.securebpmn.xacml.api + 0.1 + + + eu.aniketos.securebpmn.xacml + eu.aniketos.securebpmn.xacml.support + 1.0 + + + eu.aniketos.securebpmn.xacml + eu.aniketos.securebpmn.xacml.pdpstate + 0.1 + runtime + + + log4j + log4j + [1.2,) + + + + org.aspectj + aspectjrt + 1.6.7 + + + + + org.tmatesoft.svnkit + svnkit + 1.3.5 + + + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/doc/AnalysisClasses.zargo b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/doc/AnalysisClasses.zargo new file mode 100644 index 0000000000000000000000000000000000000000..0bc2f776b77cb4ed02cc7fe9d9e8b45de61c8f10 GIT binary patch literal 7199 zcma)>1yCH_vd3|PI~y#xYj6lIK^KAtXYmcr5?liWcXxLQzPP))2MG`)Nbul~+-DLr=~GknpFVR=P5rw2odP@pKFo{fF%9+Jqy8`u<&=n4Buk|k+k1%gQ3j6*h3_~Jyb#*LXce5AqJj5Ep+2m%voD8Z`F)rD_ zle`ES7ZBv49xFDk!CQjOmv~)y7UlL3ZKlCY%+*<(LN`kl@H)?fQifMdKVgc>9Aq@e zUZ*RtCQ}UP+sb{fx#M=UNT^QjfI3w(inBu?+4=E90$hc|Vf;05;1)m0n;yYp!*-vM z#J-@?R?sTaT-cV<&w0(f1K};yQclE-NrpXiM@;`o00pK5|#6j(hF;GinQF zv3(HfC8H9JgufGq-d1mQ6E3}L^j0u2ktl~PMdGustg1-CQ%H}SBVMYkrkbgXYygg? zASHI|v!^Lc<4zwcMpay0$4y*Dz_z#0*Ma%wVbPhTbo^2Q%6Gc#tmC@rH}#t*uqPbM<%b{rOGthR?~isoCWo#7 zAA5<*bao`11HEv^I??Vft#b}%rmP9--{wUGbQ_6dDI7kORwytwmAWLJ=NgUSw?Zl0 zp$!-}za&%_eBvd#N12|~A_yxQcik;APTDy?h^7Jy0)>{4&U7t^E(HkGMDG#bDImXq zJMR?dgoA-;M1p~N_kW%_%730Y!+)JUDKN;w5oE(=Z((D7q;F%l(m?pQX1MtSOOk!E zIalg{7RZU9RHJM3^;10w2YOGS$xP%iK6CVT9nopsS!2y z_v_pWgj?1z8(mbS_qV45Aa41YksY2VOV7O(}Y<-v@Lxy%RIn2c5FK z2MB-6%o6dE?H*A1thK)8V3;(3D>VN0Tst7e;Uzxx>1DYxP1EC*ls91Uhn-=!oU_Y3 zyN5$i&yxPzNPJ0lr?N^d)uPh7*&l7XA8C3FxfH+^IsN~=BP#z-Uz9ZVdZgnFxd(kX6)3|uOm!9dEulxfO<&{kH1r`O`#fQLJ{=}pnWU;x|m z>k$-hdM(wZDeE$cyU%NhGkYmUZ2PIszu}V;*caHzT{^%mfn>b=6>CNmU@gRoIiwM6(mZ1-i*wSD#Md7Y*vH&<& zxrqO~Zyt(qp=wR#QGvf=k~u9OiovUDjZ|rqvnVEBZL=4;?BXN{hbi{##sDJT3QoUx zj>R3XkFF+$;)qC6=D=M;x%$Y_9=*HHJJhDd+v0Uwh%w&M%WyDaAKUuL8{chYA$o?8 z?hZ)4LU4?#C7S&dwgYt0spn0Oon3teYxF$ zW*pP<D%{M3%T5F#euy6Fa$Ug|7 zNGe*uvV_I<+a6dsw_}P8VE$diyH{J$=Cg@HuJ(=c4};i|Jp0O4QrB0^_*9=UP>&A_ zH{{8e>x;24f}hZ{rPmSZ1gA1{D4BvFxgiYNsIXExiU=%@!Dn96;eaE1gE}h*18!^q zEPK!DuJuL|FNoVY3Vjs6irZu)FIFl#jE0DE5%N*Ji0qE+D{gpooKl<9Y_f5GLPhBk zi_5}XuuIR>4+-|1$puWT0oAS?~yK~)T>*JO7` zv0BjSS_a2qEWle$MI;&>>8w0Y$91%RQYC#n$(+HM^mU$x6ntnEyEJ39jQ>fe{NTjrhwL%eCQ0=VS)=BjRS7h$s&dk;xG89S=sCGLA%9vvo5|FlxK2CL2 zqll5}7~#XH2{agnPBKJBAVk`{M(U424Tqy3PA(MS#pUPSSY{@CnXrUTwz;Skm1h}~ z)#y$$@KoEVF=d?}V-8>XNrySYbBYNXX`Y9gI`-1|RgF!~l5F-;dS5hCglX6mH?4Rx zm{(e`f_oS;aPcnIJi8KknsbbhLSF^kYo3rITN@)*E1;;5@RrU|2@9`rRpOY2n0F z-~rFFY71_TxjiFQEnM0tNg8D!5P2EQ?we__7fctrhC}KFFgw{dZ1iUK;-f|$ zGz8{DG3CoisFO`-lspH&H-d+EkAL*5tF;$UijPl6@8x>3a?<3IP?u1|3ZF9(a7Ugc z*v!Va!GN7xgTgbkS#7daJSWsl*~Ju4WvHe)xrJ*F7;6C8w1KIl)oox#l z*xI9}i4fDr%I7O!7c1(fw>Ond>^S@(E>7<@Qx?5=hTC)LoEtQmbc zt^Kv{X8~9UlV>jRt{^$_b?I-R z4kD$!L}_k3S$dv$`$idZHW-wL^)Y?cw#NgEc>ATkueC+O2vJJTRLwdIQAOx+_EIn;r6gtF~?=*0+P-X>Z~G!&Xn zW($`AMo0usweQfS%EUgr<+NNw%Ps)04`tuc`NMhNv5d2|7|ZDf>f3q}U9>?bN-@>d zB){b*P)^|&*(Olp#IYj~IPJtX$P-v|DCwKYW-muuuY_T;Q6{n&u6_Y09t5H2OItt4 zKXFi^O4#-crS04rn{5to+%*pz82hH-&4~?AvaXI?YhC)5c(#%v)&An|fX8PUxo5i8 zVqMsHLrl2~_5C!sMa*JT#gxG6xfPzSrbLUj07b+n3bE;6#KU6;j$GNd;;vf0X87`qZhE=L>h!(U9Fjw(V21c(P6Vjgs?HK(V0-~ zh==LCV0MnQl4KPzA#_GLS&z*kkKhTs9x0e`3Yw(kgP%a0(oUoun4@TN_Nw^49j)lIH3H;M<1_L`bkpaqcoYh(Ma)Ij8V8*C3AjN7Nd1rCwpdqBlg6%?Gl&iJ1Hkq5w+v5 zu_McxBgDgIk?b|&X8PDO6Wf6;{+(p?oy>%GZaDnxKZQo?D;jfjRu6UcX^)Q)346Hp zH}X}dSE6wmJPjzQ+h1mIehRm&$TEz@S=Wxm0mkK2P*EGhw&lA$I)5H-9hxNLTM`tj zn5pV5jnpZkg#Mi8vdZ`jFk9hPo+X@!DFhS5)vW?oL%tPa#MM=`#MMbcABT{cUEr!_ zE|q%50xOn(WWabbx-J{sH=||396I&ko%a{VHC~0%!x+kEHUK)l$I`>-;sn)}ZP{}a zNA|oPn&U~b0|c!&_>{m;jwrODaqA!GW$&Naqj5WI-m@y~TdBb`uoNH{w``xCy=3Nw zodr9(l~52PQzz{O>e;e;A8q4)Ow}`Z1&X2bH5lBv`nCXMQ(+!71I8v{Im?~puIL@V zWxG5qt&=~i+528l`Bb>uT*y}Kqd_%NPQ&i4OgrsJCnjOagdn?Wyc${GFS5a>amH$U zr>doR=2#Fs&X>7;Ibxg{c%58X`$h418k&Pk1Xt><6W3DN>#BMe+p-;z__93I(gx@V z=-7=iVjGqo`YpR zFkbclEp?;*52>35#7q(dG5dS+22`rX{KSF3dK0>wv5fmpLJYY}E-!?GBc;%b7l@#U z*54Hcl}0`}`#kcsMX%lKqss+?$>k&<87CCy!Z^BF3(@w#E7`d2E5c2#(9yw_UQUoB zR??NKmP|k!g=738t-0hUg14gmO*R~%_IaO&0`KL<5;nVKUE`2B8*fSiy~tI(SuC0yuGjaMJqgX1@0_iZy^L8YPXMU`w8p! zr(g-}&u@NS=-Ko2e`m4(sdD0EXKGhl{bg`Wg+YOpX?%1-txDq^=PcJdRoO9xapj>= z1!R$9p66)?O$-$TXEm+qOU2T}t>K_az38|GIco0cv z>Z`c6Pz*&3XFYg!dX~yup7ivYt|8^NA$(RWW6t+oNo7$&eY9M2858Pkd)WfNUU7<> zv0I_`9nwofqDJ(q;VQ9JQiY{O$@VI`z%oP;cB0Hc;DVLK7yQ75qBYnW-*m>|1L#g_ z7b$5d!;G(jwB5!U1jVdIk`vOzX$P0J@)KnbA$p5h@1X<5oGPYkbQyX=tlK0l{aBAL zIy0*VoLhHVV?rQYL{ z<9tWeFff)ea%b>tbIr3)6xFUbORQqV8)Kfmw3mkJ(B|zpXOALkoMWye!pt|)e;2E5 zApusSQV9!7HMpZJg*soo<1X=+l@-Zp(SBHD#paEU&m~u=H?ZU@BMlZrl!Ax*RCw28 z(z#)3=0p*0ES^92@be zp6qx!k!RJ3T)#T*LqJ_Flh;o%8coX+VvVUqnUnza;aXy4$BF{i-aWV_kzwOEs3xSv zjqMqdgdX95zROdk%9%UB+sos=uxxjhi?NsYwf-hVInzxH>N<^!Ow#e{oz_t|eaB0$ z0zGub_YE4qRb?uq@R~mnZTOj-KB{wgms`cW9{G_)zfaSFn)i!|O)4%?*nu@ZSQxmS zxP@5bKRMTrRyb$Zm5-m9lD|Vsjgdly=V+XL;^+5t{{nv!?J`xn&_Gb_I<*nanv4U* zBeMV1ZM&5*iUasWJwUvYU`{5lJ0H<=Y7v%;8YT)QQrkCfVp)^3-Tn60ZAc&qS9^B9 z8Y7A;jZ$(}xidE${XL>)4IOtHPO|ilKxL1ks+76djCiZ@8l?r2W!|!2*LZLh6r{TA z2do|l2Q6_K&zB|3D!remr5<->W!mID3>Mt#=F{UXGUzVh^0B@q37gX{(E*|e+1@lGcgjR7*vSQ0WZ^2*>N`gmVs}tS`AH!%10+6-rR;=L%%%XqEA^`ELPe zcN*=7N3%?JT{$;Kx*)I&j&7Om?4;*vs?yTJUZ8BBausF6FYdhzL9MT*EE8*GxK+p6 zymMcvL|q0C%uvdsx~H;p?Coper2#SB@K2y4a;M%!xvnLQ8{s)p~Z!T{sZ(ms7ruQ-Z(DEH*8KBx@Pyuv@o47Mbi@)HrVe zW=r5izKEmi$PZ8fxWa6e9H>X0MX%RJ6EsWhjKN~F zlKrT<75UmM93k!oJw&{}?{h)R2@b@DMU{RqXot`P-Itb1q6Fas6mC6!)I84^qF87Q zQQ{qejD`)rW*&&&O~zGfLf7qHdUBul0iQC`MM)|+Ozu<__ztF~zpJlJgiGG%fDB2h zSi!bvN^>o!2A<#O%EQHV)urSJ{RrK!%3ta28Gwd#jD+sbq%!9Pa?#a+PW%~eN0Gx? zG&-DRO86|flNFk}RyFlGtz3IEj7jd16ee{s&Cdn2VI40%zLrCzYMoB2FTn(Si>$X^29Oo6qhf7#>w^2W0t4xCqza+cyo9GU1YW1Ob87|$ Q2I+a!z{0?25&xe34}P*OTL1t6 literal 0 HcmV?d00001 diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/doc/policy-config.xml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/doc/policy-config.xml new file mode 100644 index 0000000..39a13e7 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/doc/policy-config.xml @@ -0,0 +1,164 @@ + + + + + + + + + + + + + file:policy1.xacml + conf:useLines:true + + + + + + + conf:svn_url:https://demo-server/demo-repository + conf:username:pdp + conf:password:secret + conf:version:-1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + eu.aniketos.securebpmn.xacml.log.LogServer + + + true + + + + + + + + + + + + + + + + + + + + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/doc/svn-config.xml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/doc/svn-config.xml new file mode 100644 index 0000000..f98ca0d --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/doc/svn-config.xml @@ -0,0 +1,12 @@ + + + + + + + -1 + false + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/local-pdp.pom.xml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/local-pdp.pom.xml new file mode 100644 index 0000000..3c24202 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/local-pdp.pom.xml @@ -0,0 +1,145 @@ + + + 4.0.0 + + eu.aniketos.securebpmn.xacml + eu.aniketos.securebpmn.xacml.parent + 1.0 + ../eu.aniketos.securebpmn.xacml.parent/pom.xml + + eu.aniketos.securebpmn.xacml.pdp + war + 0.1 + SecureBPMN XACML - PDP + http://maven.apache.org + + 2.5.1 + + + ${artifactId} + + + + 2.3.2 + org.apache.maven.plugins + maven-compiler-plugin + + 1.5 + 1.5 + + + + org.codehaus.mojo + aspectj-maven-plugin + 1.3 + + 1.5 + + + + + compile + + + true + true + 1.5 + + + com.sun.xacml + sun-xacml + + + + **/AttributeFinderModuleObserver.aj + + + + + + + maven-war-plugin + 2.1-alpha-2 + + + WEB-INF/lib/sun-xacml-0.1.jar,WEB-INF/classes/builddef.lst + + + + + + + junit + junit + 3.8.1 + test + + + com.sun.xacml + sun-xacml + 0.1 + compile + + + eu.aniketos.securebpmn.xacml + com.sun.xacml + 0.1 + + + eu.aniketos.securebpmn.xacml + com.sun.xacml.support + 0.1 + + + eu.aniketos.securebpmn.xacml + eu.aniketos.securebpmn.xacml.api + 0.1 + + + eu.aniketos.securebpmn.xacml + eu.aniketos.securebpmn.xacml.support + 1.0 + + + eu.aniketos.securebpmn.xacml + eu.aniketos.securebpmn.xacml.pdpstate + 0.1 + runtime + + + log4j + log4j + [1.2,) + + + org.apache.cxf + cxf-rt-transports-http + ${cxf-version} + runtime + + + org.apache.cxf + cxf-rt-frontend-jaxws + ${cxf-version} + runtime + + + org.aspectj + aspectjrt + 1.6.7 + + + + + org.tmatesoft.svnkit + svnkit + [1.3,) + + + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/pom.xml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/pom.xml new file mode 100644 index 0000000..98fec34 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/pom.xml @@ -0,0 +1,132 @@ + + + 4.0.0 + + eu.aniketos.securebpmn.xacml + eu.aniketos.securebpmn.xacml.parent + 1.0 + ../eu.aniketos.securebpmn.xacml.parent/pom.xml + + eu.aniketos.securebpmn.xacml.pdp + war + 0.1 + SecureBPMN XACML - PDP + http://maven.apache.org + + 2.5.1 + + + ${artifactId} + + + + 2.3.2 + org.apache.maven.plugins + maven-compiler-plugin + + 1.5 + 1.5 + + + + + maven-assembly-plugin + 2.3 + + + jar-with-dependencies + + + + + + + + + + junit + junit + [4.8,) + test + + + eu.aniketos.securebpmn.xacml + com.sun.xacml + 0.1 + + + eu.aniketos.securebpmn.xacml + com.sun.xacml.support + 0.1 + + + eu.aniketos.securebpmn.xacml + eu.aniketos.securebpmn.xacml.api + 0.1 + + + eu.aniketos.securebpmn.xacml + eu.aniketos.securebpmn.xacml.support + 1.0 + + + eu.aniketos.securebpmn.xacml + eu.aniketos.securebpmn.xacml.pdpstate + 0.1 + runtime + + + log4j + log4j + [1.2,) + + + org.apache.cxf + cxf-rt-transports-http + ${cxf-version} + runtime + + + org.apache.cxf + cxf-rt-frontend-jaxws + ${cxf-version} + runtime + + + org.tmatesoft.svnkit + svnkit + 1.3.5 + + + + org.slf4j + slf4j-simple + 1.5.8 + runtime + + + javassist + javassist + [3,) + runtime + + + + + + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/AnalysisConfig.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/AnalysisConfig.java new file mode 100644 index 0000000..a62aa23 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/AnalysisConfig.java @@ -0,0 +1,177 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml; + +import java.lang.reflect.Method; +import java.util.List; +import java.util.Map; +import java.util.Vector; + +import org.apache.log4j.Logger; + +import eu.aniketos.securebpmn.xacml.pdp.PDPServer; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.AnalysisFinderModule; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.attributes.AnalysisAttributeResolver; +import eu.aniketos.securebpmn.xacml.combine.AnalysisCombiningAlgFactory; +import eu.aniketos.securebpmn.xacml.combine.AnalysisCombiningAlgFactoryProxy; +import eu.aniketos.securebpmn.xacml.cond.AnalysisLogicalFunction; + +import com.sun.xacml.PDPConfig; +import com.sun.xacml.combine.CombiningAlgFactory; +import com.sun.xacml.combine.CombiningAlgFactoryProxy; +import com.sun.xacml.cond.FunctionFactory; +import com.sun.xacml.cond.LogicalFunction; +import com.sun.xacml.finder.AttributeFinder; +import com.sun.xacml.finder.AttributeFinderModule; +import com.sun.xacml.finder.PolicyFinderModule; + +/** + * This configuration should be used when using the PDP in + * analysis mode: Create an AnalysisConfig by using an existing + * PDPConfig.
+ * + * Code sample for creating an Analysis PDP: + *
    + *
  • Create the normal Configuration, e.g.,
    + * ConfigurationStore config = new ConfigurationStore(new File("some/url/config.xml"));
    + PDPConfig pdpConfig = config.getDefaultPDPConfig();
  • + *
  • Create the AnalysisConfig
    + * AnalysisConfig analysisConfig = new AnalysisConfig(pdpConfig);
  • + *
  • Create the PDPServer
    + * PDPServer pdp = new PDPServer(analysisConfig);
  • + *
      + * + */ +public class AnalysisConfig extends PDPConfig { + + private static Logger logger = Logger.getLogger(AnalysisConfig.class); + + private AnalysisFinderModule attrFinder = null; + + /** + * this is more or less a copy constructor which modifies the PDPConfig + * for analysis purposes + * @param config + */ + public AnalysisConfig(PDPConfig config) { + //remove all attributeFinderModules and set to + // eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.EvaluationFinderModule + super(getAnalysisAttrFinder(), config.getPolicyFinder(), + config.getResourceFinder(), config.getRevocationFinder()); + //get EvaluationFinderModule "back" - cannot save it to the instance as created during super constructor call + attrFinder = (AnalysisFinderModule) super.getAttributeFinder().getModules().get(0); + logger.info("Created Analysis Configuration with " + attrFinder.getClass().getName() + " attributeFinder"); + if ( super.getAttributeFinder().getModules().size() != 1 ) { + //should not be the case as we want to retrieve all attributes via our simulated environment + logger.warn("More than the " + attrFinder.getClass().getName() + " attributeFinders are in use!"); + } + + init(config, true); + + } + + private void init(PDPConfig config, boolean abstractEval) { + + /* + * set option conf:useLines:true of all loaded policyFinderModules + * this will give a more detailed information during load of policies + * and during evaluation + */ + boolean finderModuleError = false; + int patchCount = 0; + for ( PolicyFinderModule policyModule : config.getPolicyFinder().getModules() ) { + try { + Method enfUseLines = policyModule.getClass().getMethod("enforceUseLines", (Class[]) null); + enfUseLines.invoke(policyModule, (Object[]) null); + logger.debug("Enforced useLines on class " + policyModule.getClass()); + ++patchCount; + } catch (NoSuchMethodException e) { + logger.warn("Class " + policyModule.getClass() + " does not support useLines feature"); + } catch (Exception e) { + logger.warn("Error when setting useLines to class " + policyModule.getClass() + " " + + e.getClass() + ": " + e.getMessage()); + } + } + if ( ! finderModuleError ) { + logger.info("Successfully set option \"useLines\" to true for " + patchCount + " finderModules"); + } + + /* + * copy constructor: copy custom attrs which are not created + * with the super() constructor + * but assure that no logServer is used + */ + Map customAttr = config.getCustomAttrs(); + if ( customAttr.containsKey(PDPServer.LOG_SERVER)) { + customAttr.remove(PDPServer.LOG_SERVER); + logger.info("Removed " + PDPServer.LOG_SERVER + " from configuration (must not be use for non-productive usage)"); + } + super.setCutomAttrs(customAttr); + + + + /* + * if abstract evaluation is enabled, replace standard algorithms with + * analysis versions + */ + if ( abstractEval ) { +// CombiningAlgFactory defaultCombAlg = CombiningAlgFactory.getInstance(); +// Set algs = defaultCombAlg.getSupportedAlgorithms(); + + AnalysisCombiningAlgFactory analysisAlgFactory = AnalysisCombiningAlgFactory.getFactory(); + CombiningAlgFactoryProxy analysisAlgProxy = new AnalysisCombiningAlgFactoryProxy(analysisAlgFactory); + + CombiningAlgFactory.setDefaultFactory(analysisAlgProxy); + logger.info("Replaced default combining algorithms with analysis versions"); + + FunctionFactory func = FunctionFactory.getGeneralInstance(); + func.addFunction(new AnalysisLogicalFunction(LogicalFunction.NAME_OR) , true); + func.addFunction(new AnalysisLogicalFunction(LogicalFunction.NAME_AND) , true); + } + } + + + public AnalysisFinderModule getEvaluationFinderModule() { + return this.attrFinder; + } + + public int addAnalysisAttributeResolver(AnalysisAttributeResolver attrResolver) { + return attrFinder.addAnalysisAttributeResolver(attrResolver); + } + + public boolean removeAttrResolver(AnalysisAttributeResolver attrResolver) { + return attrFinder.removeAttrResolver(attrResolver); + } + + public void clearAttrResolver() { + attrFinder.clearAttrResolver(); + } + + + /** + * returns an AttributeFinder which only contains only + * the attributeFinderModule required for analysis + * @return + */ + private static AttributeFinder getAnalysisAttrFinder() { + AttributeFinder attrFinder = new AttributeFinder(); + List attrModules = new Vector(); + attrModules.add(new AnalysisFinderModule()); + attrFinder.setModules(attrModules); + return attrFinder; + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/AnalysisCtx.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/AnalysisCtx.java new file mode 100644 index 0000000..0006d38 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/AnalysisCtx.java @@ -0,0 +1,58 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml; + +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.EvalInfoProvider; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.EvaluationEventHub; +import eu.aniketos.securebpmn.xacml.support.EvaluationIdContext; + +import com.sun.xacml.PDPConfig; +import com.sun.xacml.ParsingException; +import com.sun.xacml.ctx.RequestCtx; + + +/** + * This is the context required for analysis, as it holds the + * objects to keep track of the current evaluation and analysis status. + *
      + * For running an analysis evaluation, an AnalysisCtx has to be created + * and analysed with PDPServer.analyse() + * + */ +public class AnalysisCtx extends EvaluationIdContext { + + private EvaluationEventHub evalHub; + + private EvalInfoProvider evalInfo; + + public AnalysisCtx(RequestCtx request, PDPConfig config, Long evaluationId, + EvaluationEventHub evalHub) + throws ParsingException { + super(request, config.getAttributeFinder(), + config.getRevocationFinder(), true, evaluationId); + this.evalHub = evalHub; + this.evalInfo = evalHub.getEvalInfo(); + } + + public EvaluationEventHub getEvalHub() { + return this.evalHub; + } + + public EvalInfoProvider getEvalInfo() { + return this.evalInfo; + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/SVNPDPConfig.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/SVNPDPConfig.java new file mode 100644 index 0000000..ab2542b --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/SVNPDPConfig.java @@ -0,0 +1,269 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +import org.apache.log4j.Logger; +import org.tmatesoft.svn.core.SVNException; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import eu.aniketos.securebpmn.xacml.api.SecurityError; +import eu.aniketos.securebpmn.xacml.api.ErrorType; +import eu.aniketos.securebpmn.xacml.api.ReasonType; +import eu.aniketos.securebpmn.xacml.finder.MySVNClient; +import eu.aniketos.securebpmn.xacml.finder.SVNPolicyFinderModule; + +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.PDPConfig; +import com.sun.xacml.finder.PolicyFinderModule; + +/** + * + * This class allows to load the pdp configuration from the svn server + * + */ +public abstract class SVNPDPConfig { + + private static Logger logger = Logger.getLogger(SVNPDPConfig.class); + + public static final String SVN_CLIENT = "SVN_CLIENT", + ANALYSIS_ENGINE = "analysis_engine", + PASSWORD = "password", + POLICY_FILE = "policies", + SVN_URL = "svn_url", + UPDATE_JARS = "updateJars", + USE_SVN = "use_svn", + USERNAME = "username", + VERSION = "version"; + + +// public SVNPDPConfig(PDPConfig pdpConfig) { +// super(pdpConfig.getAttributeFinder(), +// pdpConfig.getPolicyFinder(), +// pdpConfig.getResourceFinder(), +// pdpConfig.getRevocationFinder()); +// super.setCutomAttrs(pdpConfig.); +// } + +// public SVNPDPConfig() { +// +// } + +// public SVNPDPConfig(AttributeFinder attributeFinder, +// PolicyFinder policyFinder, +// ResourceFinder resourceFinder, +// RevocationFinder revocationFinder) { +// super () +// } + + + public static PDPConfig getSVNPDPConfig(File confFile) throws SecurityError { + + URL svn_url = null; + String username, password; + long version; + //boolean updateJars; + + //create DOM builder + DocumentBuilderFactory dbFactory = + DocumentBuilderFactory.newInstance(); + + dbFactory.setIgnoringComments(true); + dbFactory.setNamespaceAware(false); + dbFactory.setValidating(false); + + DocumentBuilder db = null; + try { + db = dbFactory.newDocumentBuilder(); + } catch (ParserConfigurationException e) { + logger.error("Could not load DocumentBuilder: ParserConfigurationException: " + e.getMessage()); + throw new SecurityError(ErrorType.CONFIGURATION_ERROR, ReasonType.PDE_ENGINE_ERROR, "Could not load DocumentBuilder", e); + } + //read conf file + Document doc = null; + try { + doc = db.parse(new FileInputStream(confFile)); + } catch (IOException ioe) { + logger.error("Failed to load svn configuration from file: IOException: " + ioe.getMessage()); + throw new SecurityError(ErrorType.CONFIGURATION_ERROR, ReasonType.PDE_ENGINE_ERROR, "failed to load the configuration from string ", ioe); + } catch (SAXException saxe) { + logger.error("Could not parse configuration: SAXException: " + saxe.getMessage()); + throw new SecurityError(ErrorType.CONFIGURATION_ERROR, ReasonType.PDE_ENGINE_ERROR, "Could not parse configuration: SAXException: " + saxe.getMessage(), saxe); + } catch (IllegalArgumentException iae) { + logger.error("Failed to load the configuration from file: IllegalArgumentException: " + iae.getMessage()); + throw new SecurityError(ErrorType.CONFIGURATION_ERROR, ReasonType.PDE_ENGINE_ERROR, "Failed to load the configuration from file: IllegalArgumentException: " + iae.getMessage(), iae); + } + + Element confNode = doc.getDocumentElement(); + + if ( ! confNode.getTagName().equals("config")) { + throw new SecurityError(ErrorType.CONFIGURATION_ERROR, ReasonType.PDE_ENGINE_ERROR, "configuration requires elemement als root!"); + } + + Map attrs = new HashMap(); + Node n; + NodeList list = confNode.getChildNodes(); + for ( int i = 0; i < list.getLength(); ++i) { + n = list.item(i); + + if ( n.getNodeType() == Node.ELEMENT_NODE ) { + String key = null, value = null; + if ( n.getFirstChild() != null ) { + key = n.getNodeName(); + if ( n.getFirstChild().getNodeType() == Node.TEXT_NODE ) { + value = n.getFirstChild().getNodeValue().trim(); + } + } else { + NamedNodeMap foo = n.getAttributes(); + if (foo != null ) { + key = foo.getNamedItem("key").getNodeValue(); + value = foo.getNamedItem("value").getNodeValue(); + } + } + if ( key != null && value != null ) { +// if (logger.isDebugEnabled()) { +// logger.debug("Read custom attribute " + key + " with value " + value); +// } + attrs.put(key, value); + } + } + } + + if ( ! attrs.containsKey(SVN_URL)) { + logger.error(SVN_URL + " is missing in " + confFile.getAbsolutePath()); + throw new SecurityError(ErrorType.CONFIGURATION_ERROR, ReasonType.PDE_ENGINE_ERROR, + "SVNPDPConfig requires the property " + SVN_URL); + } + + try { + svn_url = new URL(attrs.get(SVN_URL)); + } catch (MalformedURLException e) { + logger.error(SVN_URL + " is not a valid URL: " + e.getMessage() + " in " + confFile.getAbsolutePath()); + throw new SecurityError(ErrorType.CONFIGURATION_ERROR, ReasonType.PDE_ENGINE_ERROR, + "SVNPDPConfig: " + SVN_URL + " has to be a valid URL", e); + } + + if ( ! attrs.containsKey(USERNAME)) { + logger.error(USERNAME + " is missing in " + confFile.getAbsolutePath()); + throw new SecurityError(ErrorType.CONFIGURATION_ERROR, ReasonType.PDE_ENGINE_ERROR, + "SVNPDPConfig requires the property " + USERNAME); + } else { + username = attrs.get(USERNAME); + } + + if ( ! attrs.containsKey(PASSWORD)) { + logger.error(PASSWORD + " is missing in " + confFile.getAbsolutePath()); + throw new SecurityError(ErrorType.CONFIGURATION_ERROR, ReasonType.PDE_ENGINE_ERROR, + "SVNPDPConfig requires the property " + PASSWORD); + } else { + password = attrs.get(PASSWORD); + } + + + if ( ! attrs.containsKey(VERSION)) { + logger.warn(VERSION + " is missing in " + confFile.getAbsolutePath() + " using -1 as default"); + version = -1; + } else { + String tmpNr = attrs.get(VERSION).trim(); + try { + version = Long.parseLong(tmpNr); + } catch (NumberFormatException e) { + version = -1; + logger.warn("Could not parse " + tmpNr + " to a Long value (" + e.getMessage() + "); using -1 as default"); + } + } + + logger.info("SVN config: svn-url: " + svn_url.toString() + ", username: " + username + ", version: " + version); + + return getSVNPDPConfig(svn_url.toString(), username, password, version); + +// MySVNClient svnClient = new MySVNClient(svn_url.toString(), username, password, version); +// +// try { +// String configuration = svnClient.getTextFile(SVNPolicyFinderModule.XACML_FOLDER + "/policy-config.xml"); +// ConfigurationStore confStore = new ConfigurationStore(configuration); +// PDPConfig pdpConfig = confStore.getDefaultPDPConfig(); +//// Set policyFinders = pdpConfig.getPolicyFinder().getModules(); +//// for ( PolicyFinderModule module : policyFinders ) { +//// if ( module instanceof SVNPolicyFinderModule ) { +//// +//// } +//// } +// +// return new SVNPDPConfig(pdpConfig); +// +// } catch (SVNException e) { +// logger.error("Could not load configuration from SVN Repository: SVNException:" + e.getMessage() + " (" +e.getErrorMessage() + ")"); +// e.printStackTrace(); +// throw new SecurityError(ErrorType.CONFIGURATION_ERROR, ReasonType.PDE_ENGINE_ERROR, "Could not load configuration from SVN Repository: " + e.getMessage(), e); +// } catch (Exception e) { +// logger.error("Could not load configuration: " + e.getClass() + ": " + e.getMessage()); +// throw new SecurityError(ErrorType.CONFIGURATION_ERROR, ReasonType.PDE_ENGINE_ERROR, "Could not load configuration from SVN Repository: " + e.getClass() + ": " + e.getMessage(), e); +// } + } + + public static PDPConfig getSVNPDPConfig(String svn_url, + String username, String password, long version) throws SecurityError { + + MySVNClient svnClient = new MySVNClient(svn_url, username, password, version); + Map customAttrs = new HashMap(); + customAttrs.put(SVN_CLIENT, svnClient); + customAttrs.put(SVN_URL, svn_url); + customAttrs.put(USERNAME, username); + customAttrs.put(PASSWORD, password); + customAttrs.put(VERSION, version); + + try { + String configuration = svnClient.getTextFile(SVNPolicyFinderModule.XACML_FOLDER + "/policy-config.xml"); + logger.debug("Creating ConfigurationStore from svn policy-config.xml"); + //System.out.println("####\n" + configuration + "\n######"); + ConfigurationStore confStore = new ConfigurationStore(configuration, customAttrs); + PDPConfig pdpConfig = confStore.getDefaultPDPConfig(); + //pdpConfig.getPolicyFinder().addPolicyFinderModule(new SVNPolicyFinderModule(svnClient)); + Set modules = pdpConfig.getPolicyFinder().getModules(); + modules.add(new SVNPolicyFinderModule(svnClient)); + pdpConfig.getPolicyFinder().setModules(modules); + logger.debug("Created SVNPolicyFinderModule and added to PDPConfig"); + //return new SVNPDPConfig(pdpConfig); + pdpConfig.setCustomAttr(SVN_CLIENT, svnClient); + return pdpConfig; + } catch (SVNException e) { + logger.error("Could not load configuration from SVN Repository: SVNException:" + e.getMessage() + " (" +e.getErrorMessage() + ")"); + e.printStackTrace(); + throw new SecurityError(ErrorType.CONFIGURATION_ERROR, ReasonType.PDE_ENGINE_ERROR, "Could not load configuration from SVN Repository: " + e.getMessage(), e); + } catch (Exception e) { + logger.error("Could not load configuration: " + e.getClass() + ": " + e.getMessage()); + throw new SecurityError(ErrorType.CONFIGURATION_ERROR, ReasonType.PDE_ENGINE_ERROR, "Could not load configuration from SVN Repository: " + e.getClass() + ": " + e.getMessage(), e); + } + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisCombiningAlgFactory.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisCombiningAlgFactory.java new file mode 100644 index 0000000..15a1398 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisCombiningAlgFactory.java @@ -0,0 +1,164 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.combine; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.apache.log4j.Logger; + +import com.sun.xacml.Constants; +import com.sun.xacml.UnknownIdentifierException; +import com.sun.xacml.combine.BaseCombiningAlgFactory; +import com.sun.xacml.combine.CombiningAlgFactory; +import com.sun.xacml.combine.CombiningAlgorithm; + + + +public class AnalysisCombiningAlgFactory extends BaseCombiningAlgFactory { + + // the single factory instance + private static AnalysisCombiningAlgFactory factoryInstance = null; + + // the algorithms supported by this factory + private static Set supportedAlgorithms = null; + + // identifiers for the supported algorithms + private static Set supportedAlgIds; + + private static Logger logger = Logger.getLogger(AnalysisCombiningAlgFactory.class); + + + private AnalysisCombiningAlgFactory() { + super(supportedAlgorithms); + } + +// private static void initAlgorithms() { +// logger.debug("Initializing standard combining algorithms"); +// +// supportedAlgorithms = new HashSet(); +// supportedAlgIds = new HashSet(); +// +//// supportedAlgorithms.add(new DenyOverridesRuleAlg()); +//// supportedAlgIds.add(DenyOverridesRuleAlg.algId); +//// supportedAlgorithms.add(new DenyOverridesPolicyAlg()); +//// supportedAlgIds.add(DenyOverridesPolicyAlg.algId); +//// +//// supportedAlgorithms.add(new OrderedDenyOverridesRuleAlg()); +//// supportedAlgIds.add(OrderedDenyOverridesRuleAlg.algId); +//// supportedAlgorithms.add(new OrderedDenyOverridesPolicyAlg()); +//// supportedAlgIds.add(OrderedDenyOverridesPolicyAlg.algId); +//// +//// supportedAlgorithms.add(new PermitOverridesRuleAlg()); +//// supportedAlgIds.add(PermitOverridesRuleAlg.algId); +//// supportedAlgorithms.add(new PermitOverridesPolicyAlg()); +//// supportedAlgIds.add(PermitOverridesPolicyAlg.algId); +//// +//// supportedAlgorithms.add(new OrderedPermitOverridesRuleAlg()); +//// supportedAlgIds.add(OrderedPermitOverridesRuleAlg.algId); +//// supportedAlgorithms.add(new OrderedPermitOverridesPolicyAlg()); +//// supportedAlgIds.add(OrderedPermitOverridesPolicyAlg.algId); +// +// supportedAlgorithms.add(new AnalysisFirstApplicableRuleAlg()); +// supportedAlgIds.add(AnalysisFirstApplicableRuleAlg.algId); +// supportedAlgorithms.add(new AnalysisFirstApplicableRuleAlg()); +// supportedAlgIds.add(AnalysisFirstApplicableRuleAlg.algId); +// +//// supportedAlgorithms.add(new OnlyOneApplicablePolicyAlg()); +//// supportedAlgIds.add(OnlyOneApplicablePolicyAlg.algId); +// +// supportedAlgIds = Collections.unmodifiableSet(supportedAlgIds); +// } + + private static void initAlgorithms() { + logger.debug("Initializing analysis versions of standard combining algorithms"); + + supportedAlgorithms = new HashSet(); + supportedAlgIds = new HashSet(); + + supportedAlgorithms.add(new AnalysisDenyOverridesRuleAlg()); + supportedAlgIds.add(AnalysisDenyOverridesRuleAlg.algId); + supportedAlgorithms.add(new AnalysisDenyOverridesPolicyAlg()); + supportedAlgIds.add(AnalysisDenyOverridesPolicyAlg.algId); + + supportedAlgorithms.add(new AnalysisFirstApplicableRuleAlg()); + supportedAlgIds.add(AnalysisFirstApplicableRuleAlg.algId); + supportedAlgorithms.add(new AnalysisFirstApplicablePolicyAlg()); + supportedAlgIds.add(AnalysisFirstApplicablePolicyAlg.algId); + + supportedAlgorithms.add(new AnalysisOnlyOneApplicablePolicyAlg()); + supportedAlgIds.add(AnalysisOnlyOneApplicablePolicyAlg.algId); + + supportedAlgorithms.add(new AnalysisOrderedDenyOverridesRuleAlg()); + supportedAlgIds.add(AnalysisOrderedDenyOverridesRuleAlg.algId); + supportedAlgorithms.add(new AnalysisOrderedDenyOverridesPolicyAlg()); + supportedAlgIds.add(AnalysisOrderedDenyOverridesPolicyAlg.algId); + + supportedAlgorithms.add(new AnalysisOrderedPermitOverridesRuleAlg()); + supportedAlgIds.add(AnalysisOrderedPermitOverridesRuleAlg.algId); + supportedAlgorithms.add(new AnalysisOrderedPermitOverridesPolicyAlg()); + supportedAlgIds.add(AnalysisOrderedPermitOverridesPolicyAlg.algId); + + supportedAlgorithms.add(new AnalysisPermitOverridesRuleAlg()); + supportedAlgIds.add(AnalysisPermitOverridesRuleAlg.algId); + supportedAlgorithms.add(new AnalysisPermitOverridesPolicyAlg()); + supportedAlgIds.add(AnalysisPermitOverridesPolicyAlg.algId); + + supportedAlgIds = Collections.unmodifiableSet(supportedAlgIds); + + logger.debug("Created " + supportedAlgIds.size() + " analysis combining algorithms"); + } + + + public static synchronized AnalysisCombiningAlgFactory getFactory() { + if (factoryInstance == null) { + initAlgorithms(); + factoryInstance = new AnalysisCombiningAlgFactory(); + } + + return factoryInstance; + } + + public static CombiningAlgFactory getNewFactory() { + // first we make sure everything's been initialized... + getFactory(); + + // ...then we create the new instance + return new BaseCombiningAlgFactory(supportedAlgorithms); + } + + + public static Set getStandardAlgorithms(String xacmlVersion) + throws UnknownIdentifierException + { + if ((xacmlVersion.equals(Constants.XACML_1_0_IDENTIFIER)) || + (xacmlVersion.equals(Constants.XACML_2_0_IDENTIFIER)) || + (xacmlVersion.equals(Constants.XACML_3_0_IDENTIFIER))) { + return supportedAlgIds; + } + + throw new UnknownIdentifierException("Unknown XACML version: " + + xacmlVersion); + } + + + public void addAlgorithm(CombiningAlgorithm alg) { + throw new UnsupportedOperationException("this factory cannot " + + "support new algorithms"); + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisCombiningAlgFactoryProxy.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisCombiningAlgFactoryProxy.java new file mode 100644 index 0000000..b723647 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisCombiningAlgFactoryProxy.java @@ -0,0 +1,34 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.combine; + +import com.sun.xacml.combine.CombiningAlgFactory; +import com.sun.xacml.combine.CombiningAlgFactoryProxy; + +public class AnalysisCombiningAlgFactoryProxy implements + CombiningAlgFactoryProxy { + + private AnalysisCombiningAlgFactory factory; + + public AnalysisCombiningAlgFactoryProxy(AnalysisCombiningAlgFactory factory) { + this.factory = factory; + } + + public CombiningAlgFactory getFactory() { + return factory; + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisDenyOverridesPolicyAlg.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisDenyOverridesPolicyAlg.java new file mode 100644 index 0000000..af9bba1 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisDenyOverridesPolicyAlg.java @@ -0,0 +1,134 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.combine; + +import java.net.URI; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import eu.aniketos.securebpmn.xacml.AnalysisCtx; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.MatchResult; +import com.sun.xacml.Obligation; +import com.sun.xacml.combine.CombinerElement; +import com.sun.xacml.combine.CombinerParameter; +import com.sun.xacml.combine.DenyOverridesPolicyAlg; +import com.sun.xacml.combine.PolicyCombinerElement; +import com.sun.xacml.ctx.Result; + +public class AnalysisDenyOverridesPolicyAlg extends DenyOverridesPolicyAlg { + + + public AnalysisDenyOverridesPolicyAlg() { + super(); + } + + public void setConfigurationStore(ConfigurationStore conf) { + //this.conf = conf; + } + + public AnalysisDenyOverridesPolicyAlg(URI identifier) { + super(identifier); + } + + public Result combine(EvaluationCtx context, List parameters, + List policyElements) { + boolean atLeastOnePermit = false; + Set permitObligations = new HashSet(); + Iterator it = policyElements.iterator(); + + Result finalResult = null; + + while (it.hasNext()) { + AbstractPolicy policy = ((PolicyCombinerElement) it.next()).getPolicy(); + + // make sure that the policy matches the context + context.newEvent(policy); + MatchResult match = policy.match(context); + + if (match.getResult() == MatchResult.INDETERMINATE) { + Result result = new Result(Result.DECISION_DENY, context); + context.closeCurrentEvent(result); + if ( ((AnalysisCtx)context).getEvalInfo().isMissingAttribute() ) { + if ( finalResult == null ) { + finalResult = result; + } + } else { + return result; + } + } + + if (match.getResult() == MatchResult.NO_MATCH) { + context.closeCurrentEvent( + new Result(Result.DECISION_NOT_APPLICABLE)); + } + + if (match.getResult() == MatchResult.MATCH) { + // evaluate the policy + Result result = policy.evaluate(context); + context.closeCurrentEvent(result); + // do not treat the discarded values + if (result != null) { + int effect = result.getDecision(); + + // unlike in the RuleCombining version of this alg, we + // always return DENY if any Policy returns DENY or + // INDETERMINATE + if ((effect == Result.DECISION_DENY) || + (effect == Result.DECISION_INDETERMINATE)) { + + result = new Result(Result.DECISION_DENY, + context, + result.getObligations()); + + if ( ((AnalysisCtx)context).getEvalInfo().isMissingAttribute() ) { + if ( finalResult == null ) { + finalResult = result; + } + } else { + return result; + } + + } + + // remember if at least one Policy said PERMIT + if (effect == Result.DECISION_PERMIT) { + atLeastOnePermit = true; + permitObligations.addAll(result.getObligations()); + } + } + } + } + + if ( finalResult != null ) { + return finalResult; + } + + // if we got a PERMIT, return it, otherwise it's NOT_APPLICABLE + if (atLeastOnePermit) { + return new Result(Result.DECISION_PERMIT, + context, + permitObligations); + } + return new Result(Result.DECISION_NOT_APPLICABLE, + context); + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisDenyOverridesRuleAlg.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisDenyOverridesRuleAlg.java new file mode 100644 index 0000000..d523396 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisDenyOverridesRuleAlg.java @@ -0,0 +1,131 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.combine; + +import java.net.URI; +import java.util.Iterator; +import java.util.List; + +import eu.aniketos.securebpmn.xacml.AnalysisCtx; + +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.Rule; +import com.sun.xacml.combine.CombinerElement; +import com.sun.xacml.combine.CombinerParameter; +import com.sun.xacml.combine.DenyOverridesRuleAlg; +import com.sun.xacml.combine.RuleCombinerElement; +import com.sun.xacml.ctx.Result; + +public class AnalysisDenyOverridesRuleAlg extends DenyOverridesRuleAlg { + + + public AnalysisDenyOverridesRuleAlg() { + super(); + } + //private ConfigurationStore conf; + + public void setConfigurationStore(ConfigurationStore conf) { + //this.conf = conf; + } + + protected AnalysisDenyOverridesRuleAlg(URI identifier) { + super(identifier); + } + + @Override + public Result combine(EvaluationCtx context, List parameters, + List ruleElements) { + boolean atLeastOneError = false; + boolean potentialDeny = false; + boolean atLeastOnePermit = false; + Result firstIndeterminateResult = null; + Iterator it = ruleElements.iterator(); + + Result finalDeny = null; + + while (it.hasNext()) { + Rule rule = ((RuleCombinerElement)(it.next())).getRule(); + Result result = rule.evaluate(context); + int value = result.getDecision(); + + // if there was a value of DENY, then regardless of what else + // we've seen, we always return DENY + if (value == Result.DECISION_DENY) { + if ( ((AnalysisCtx)context).getEvalInfo().isMissingAttribute() ) { + if (finalDeny == null ) { + finalDeny = result; + } + } else { + return result; + } + } + + // if it was INDETERMINATE, then we couldn't figure something + // out, so we keep track of these cases... + if (value == Result.DECISION_INDETERMINATE) { + atLeastOneError = true; + + // there are no rules about what to do if multiple cases + // cause errors, so we'll just return the first one + if (firstIndeterminateResult == null) { + firstIndeterminateResult = result; + } + + // if the Rule's effect is DENY, then we can't let this + // alg return PERMIT, since this Rule might have denied + // if it could do its stuff + if (rule.getEffect() == Result.DECISION_DENY) { + potentialDeny = true; + } + } else { + // keep track of whether we had at least one rule that + // actually pertained to the request + if (value == Result.DECISION_PERMIT) { + atLeastOnePermit = true; + } + } + } + + if ( finalDeny != null ) { + return finalDeny; + } + + // we didn't explicitly DENY, but we might have had some Rule + // been evaluated, so we have to return INDETERMINATE + if (potentialDeny) { + return firstIndeterminateResult; + } + + // some Rule said PERMIT, so since nothing could have denied, + // we return PERMIT + if (atLeastOnePermit) { + return new Result(Result.DECISION_PERMIT, + context); + } + + // we didn't find anything that said PERMIT, but if we had a + // problem with one of the Rules, then we're INDETERMINATE + if (atLeastOneError) { + return firstIndeterminateResult; + } + + // if we hit this point, then none of the rules actually applied + // to us, so we return NOT_APPLICABLE + return new Result(Result.DECISION_NOT_APPLICABLE, + context); + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisFirstApplicablePolicyAlg.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisFirstApplicablePolicyAlg.java new file mode 100644 index 0000000..3f16538 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisFirstApplicablePolicyAlg.java @@ -0,0 +1,117 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.combine; + +import java.util.Iterator; +import java.util.List; + +import eu.aniketos.securebpmn.xacml.AnalysisCtx; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.MatchResult; +import com.sun.xacml.combine.CombinerElement; +import com.sun.xacml.combine.CombinerParameter; +import com.sun.xacml.combine.FirstApplicablePolicyAlg; +import com.sun.xacml.combine.PolicyCombinerElement; +import com.sun.xacml.ctx.Result; + +public class AnalysisFirstApplicablePolicyAlg extends FirstApplicablePolicyAlg { + + public AnalysisFirstApplicablePolicyAlg() { + super(); + } + + @Override + public Result combine(EvaluationCtx context, List parameters, + List policyElements) { + + Result finalResult = null; + + Iterator it = policyElements.iterator(); + + while (it.hasNext()) { + AbstractPolicy policy = + ((PolicyCombinerElement)(it.next())).getPolicy(); + + // make sure that the policy matches the context + context.newEvent(policy); + MatchResult match = policy.match(context); + + if (match.getResult() == MatchResult.INDETERMINATE) { + Result result = new Result(Result.DECISION_INDETERMINATE, + match.getStatus(), + context); + context.closeCurrentEvent(result); + + if ( ((AnalysisCtx)context).getEvalInfo().isMissingAttribute() ) { + if ( finalResult == null) { + finalResult = result; + } + } else { + return result; + } + } + + if (match.getResult() == MatchResult.NO_MATCH) { + context.closeCurrentEvent( + new Result(Result.DECISION_NOT_APPLICABLE)); + } + + if (match.getResult() == MatchResult.MATCH) { + // evaluate the policy + Result result = policy.evaluate(context); + context.closeCurrentEvent(result); + + + // do not treat the discarded values + if (result != null) { + int effect = result.getDecision(); + + // in the case of PERMIT, DENY, or INDETERMINATE, we always + // just return that result, so only on a rule that doesn't + // apply do we keep going... + if (effect != Result.DECISION_NOT_APPLICABLE) { + if (((AnalysisCtx)context).getEvalInfo().isMissingAttribute()) { + if ( ( finalResult == null) ) { + finalResult = result; + } + + } else { + return result; + } + } + } + } + } + if ( finalResult != null ) { + return finalResult; + } + + // if we got here, then none of the rules applied + return new Result(Result.DECISION_NOT_APPLICABLE, + context); + } + + + public void setConfigurationStore(ConfigurationStore conf) { + //this.conf = conf; + } + + + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisFirstApplicableRuleAlg.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisFirstApplicableRuleAlg.java new file mode 100644 index 0000000..ab9353d --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisFirstApplicableRuleAlg.java @@ -0,0 +1,77 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.combine; + +import java.util.Iterator; +import java.util.List; + +import eu.aniketos.securebpmn.xacml.AnalysisCtx; + +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.Rule; +import com.sun.xacml.combine.CombinerElement; +import com.sun.xacml.combine.CombinerParameter; +import com.sun.xacml.combine.FirstApplicableRuleAlg; +import com.sun.xacml.combine.RuleCombinerElement; +import com.sun.xacml.ctx.Result; + + +public class AnalysisFirstApplicableRuleAlg extends FirstApplicableRuleAlg { + + @Override + public Result combine(EvaluationCtx context, List parameters, + List ruleElements) { + + Result finalResult = null; + + Iterator it = ruleElements.iterator(); + + + while (it.hasNext()) { + Rule rule = ((RuleCombinerElement)(it.next())).getRule(); + Result result = rule.evaluate(context); + int value = result.getDecision(); + + // in the case of PERMIT, DENY, or INDETERMINATE, we always + // just return that result, so only on a rule that doesn't + // apply do we keep going... + if (value != Result.DECISION_NOT_APPLICABLE) { + if ( ((AnalysisCtx)context).getEvalInfo().isMissingAttribute()) { + // and it was within "this round", thus we will return the result of this + if ( finalResult == null ) { + finalResult = result; + } + } else { + return result; + } + } + } + + if ( finalResult != null ) { + return finalResult; + } + + // if we got here, then none of the rules applied + return new Result(Result.DECISION_NOT_APPLICABLE, + context); + } + + public void setConfigurationStore(ConfigurationStore conf) { + //this.conf = conf; + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisOnlyOneApplicablePolicyAlg.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisOnlyOneApplicablePolicyAlg.java new file mode 100644 index 0000000..0c890f4 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisOnlyOneApplicablePolicyAlg.java @@ -0,0 +1,134 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.combine; + + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import eu.aniketos.securebpmn.xacml.AnalysisCtx; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.MatchResult; +import com.sun.xacml.combine.CombinerElement; +import com.sun.xacml.combine.CombinerParameter; +import com.sun.xacml.combine.OnlyOneApplicablePolicyAlg; +import com.sun.xacml.combine.PolicyCombinerElement; +import com.sun.xacml.ctx.Result; +import com.sun.xacml.ctx.Status; + +public class AnalysisOnlyOneApplicablePolicyAlg extends + OnlyOneApplicablePolicyAlg { + + + public AnalysisOnlyOneApplicablePolicyAlg() { + super(); + } + + public void setConfigurationStore(ConfigurationStore conf) { + //this.conf = conf; + } + + public Result combine(EvaluationCtx context, List parameters, + List policyElements) { + boolean atLeastOne = false; + AbstractPolicy selectedPolicy = null; + Iterator it = policyElements.iterator(); + + Result finalResult = null; + + while (it.hasNext()) { + AbstractPolicy policy = + ((PolicyCombinerElement)(it.next())).getPolicy(); + + // see if the policy matches the context + context.newEvent(policy); + MatchResult match = policy.match(context); + + // if there is an error in trying to match any of the targets, + // we always return INDETERMINATE immediately + if (match.getResult() == MatchResult.INDETERMINATE) { + Result result = new Result(Result.DECISION_INDETERMINATE, + match.getStatus(), + context); + context.closeCurrentEvent(result); + if ( ((AnalysisCtx)context).getEvalInfo().isMissingAttribute() ) { + if ( finalResult == null) { + finalResult = result; + } + } else { + return result; + } + } + + if (match.getResult() == MatchResult.NO_MATCH) { + context.closeCurrentEvent( + new Result(Result.DECISION_NOT_APPLICABLE)); + } + + if (match.getResult() == MatchResult.MATCH) { + // if this isn't the first match, then this is an error + if (atLeastOne) { + List code = new ArrayList(); + code.add(Status.STATUS_PROCESSING_ERROR); + String message = "Too many applicable policies"; + Result result = new Result(Result.DECISION_INDETERMINATE, + new Status(code, message), + context); + context.closeCurrentEvent(result); + if ( ((AnalysisCtx)context).getEvalInfo().isMissingAttribute() ) { + if ( finalResult == null) { + finalResult = result; + } + } else { + return result; + } + } else { + // if this was the first applicable policy in the set, then + // remember it for later + atLeastOne = true; + selectedPolicy = policy; + context.closeCurrentEvent("Evaluated later"); + } + } + } + + if ( finalResult != null ) { + return finalResult; + } + + // if we got through the loop and found exactly one match, then + // we return the evaluation result of that policy + if (atLeastOne) { + context.newEvent(selectedPolicy); + Result result = selectedPolicy.evaluate(context); + context.closeCurrentEvent(result); + // do not treat the discarded values + if (result != null) { + return result; + } + } + + // if we didn't find a matching policy, then we don't apply + return new Result(Result.DECISION_NOT_APPLICABLE, + context); + } + + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisOrderedDenyOverridesPolicyAlg.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisOrderedDenyOverridesPolicyAlg.java new file mode 100644 index 0000000..cb5a999 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisOrderedDenyOverridesPolicyAlg.java @@ -0,0 +1,52 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.combine; + +import java.net.URI; + +import com.sun.xacml.combine.OrderedDenyOverridesPolicyAlg; + +public class AnalysisOrderedDenyOverridesPolicyAlg extends + AnalysisDenyOverridesPolicyAlg { + + // a URI form of the identifier + private static URI identifierURI; + // exception if the URI was invalid, which should never be a problem + private static RuntimeException earlyException; + + public static final String algId = OrderedDenyOverridesPolicyAlg.algId; + + static { + try { + identifierURI = URI.create(OrderedDenyOverridesPolicyAlg.algId); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * Standard constructor. + */ + public AnalysisOrderedDenyOverridesPolicyAlg() { + super(identifierURI); + + if (earlyException != null) { + throw earlyException; + } + } + + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisOrderedDenyOverridesRuleAlg.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisOrderedDenyOverridesRuleAlg.java new file mode 100644 index 0000000..ef6b0f1 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisOrderedDenyOverridesRuleAlg.java @@ -0,0 +1,52 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.combine; + +import java.net.URI; + +import com.sun.xacml.combine.OrderedDenyOverridesRuleAlg; + +public class AnalysisOrderedDenyOverridesRuleAlg extends + AnalysisDenyOverridesRuleAlg { + + + // a URI form of the identifier + private static URI identifierURI; + // exception if the URI was invalid, which should never be a problem + private static RuntimeException earlyException; + + public static final String algId = OrderedDenyOverridesRuleAlg.algId; + + static { + try { + identifierURI = URI.create(OrderedDenyOverridesRuleAlg.algId); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * Standard constructor. + */ + public AnalysisOrderedDenyOverridesRuleAlg() { + super(identifierURI); + + if (earlyException != null) { + throw earlyException; + } + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisOrderedPermitOverridesPolicyAlg.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisOrderedPermitOverridesPolicyAlg.java new file mode 100644 index 0000000..b67e82f --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisOrderedPermitOverridesPolicyAlg.java @@ -0,0 +1,49 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.combine; + +import java.net.URI; + +import com.sun.xacml.combine.OrderedPermitOverridesPolicyAlg; + +public class AnalysisOrderedPermitOverridesPolicyAlg extends + AnalysisPermitOverridesPolicyAlg { + // a URI form of the identifier + private static URI identifierURI; + // exception if the URI was invalid, which should never be a problem + private static RuntimeException earlyException; + + public static final String algId = OrderedPermitOverridesPolicyAlg.algId; + + static { + try { + identifierURI = URI.create(OrderedPermitOverridesPolicyAlg.algId); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * Standard constructor. + */ + public AnalysisOrderedPermitOverridesPolicyAlg() { + super(identifierURI); + + if (earlyException != null) { + throw earlyException; + } + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisOrderedPermitOverridesRuleAlg.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisOrderedPermitOverridesRuleAlg.java new file mode 100644 index 0000000..58c7840 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisOrderedPermitOverridesRuleAlg.java @@ -0,0 +1,52 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.combine; + +import java.net.URI; + +import com.sun.xacml.combine.OrderedPermitOverridesRuleAlg; + +public class AnalysisOrderedPermitOverridesRuleAlg extends + AnalysisPermitOverridesPolicyAlg { + + + // a URI form of the identifier + private static URI identifierURI; + // exception if the URI was invalid, which should never be a problem + private static RuntimeException earlyException; + + public static final String algId = OrderedPermitOverridesRuleAlg.algId; + + static { + try { + identifierURI = URI.create(OrderedPermitOverridesRuleAlg.algId); + } catch (IllegalArgumentException e) { + earlyException = e; + } + } + + /** + * Standard constructor. + */ + public AnalysisOrderedPermitOverridesRuleAlg() { + super(identifierURI); + + if (earlyException != null) { + throw earlyException; + } + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisPermitOverridesPolicyAlg.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisPermitOverridesPolicyAlg.java new file mode 100644 index 0000000..480fc7c --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisPermitOverridesPolicyAlg.java @@ -0,0 +1,139 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.combine; + +import java.net.URI; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import eu.aniketos.securebpmn.xacml.AnalysisCtx; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.MatchResult; +import com.sun.xacml.Obligation; +import com.sun.xacml.combine.CombinerElement; +import com.sun.xacml.combine.CombinerParameter; +import com.sun.xacml.combine.PermitOverridesPolicyAlg; +import com.sun.xacml.combine.PolicyCombinerElement; +import com.sun.xacml.ctx.Result; +import com.sun.xacml.ctx.Status; + +public class AnalysisPermitOverridesPolicyAlg extends PermitOverridesPolicyAlg { + + public AnalysisPermitOverridesPolicyAlg() { + super(); + } + + public void setConfigurationStore(ConfigurationStore conf) { + //this.conf = conf; + } + + public AnalysisPermitOverridesPolicyAlg(URI identifier) { + super(identifier); + } + + public Result combine(EvaluationCtx context, List parameters, + List policyElements) { + boolean atLeastOneError = false; + boolean atLeastOneDeny = false; + Set denyObligations = new HashSet(); + Status firstIndeterminateStatus = null; + Iterator it = policyElements.iterator(); + + Result finalResult = null; + + while (it.hasNext()) { + AbstractPolicy policy = + ((PolicyCombinerElement)(it.next())).getPolicy(); + + // make sure that the policy matches the context + context.newEvent(policy); + MatchResult match = policy.match(context); + + if (match.getResult() == MatchResult.INDETERMINATE) { + context.closeCurrentEvent( + new Result(Result.DECISION_INDETERMINATE, context)); + atLeastOneError = true; + + // keep track of the first error, regardless of cause + if (firstIndeterminateStatus == null) { + firstIndeterminateStatus = match.getStatus(); + } + } else if (match.getResult() == MatchResult.NO_MATCH) { + context.closeCurrentEvent( + new Result(Result.DECISION_NOT_APPLICABLE)); + } else if (match.getResult() == MatchResult.MATCH) { + // now we evaluate the policy + Result result = policy.evaluate(context); + context.closeCurrentEvent(result); + + // do not treat the discarded values + if (result != null) { + int effect = result.getDecision(); + + // this is a little different from DenyOverrides... + if (effect == Result.DECISION_PERMIT) { + if ( ((AnalysisCtx)context).getEvalInfo().isMissingAttribute() ) { + if ( finalResult == null ) { + finalResult = result; + } + } else { + return result; + } + } + + if (effect == Result.DECISION_DENY) { + atLeastOneDeny = true; + denyObligations.addAll(result.getObligations()); + } else if (effect == Result.DECISION_INDETERMINATE) { + atLeastOneError = true; + + // keep track of the first error, regardless of cause + if (firstIndeterminateStatus == null) { + firstIndeterminateStatus = result.getStatus(); + } + } + } + } + } + + if ( finalResult != null ) { + return finalResult; + } + + // if we got a DENY, return it + if (atLeastOneDeny) { + return new Result(Result.DECISION_DENY, + context, + denyObligations); + } + + // if we got an INDETERMINATE, return it + if (atLeastOneError) { + return new Result(Result.DECISION_INDETERMINATE, + firstIndeterminateStatus, + context); + } + + // if we got here, then nothing applied to us + return new Result(Result.DECISION_NOT_APPLICABLE, + context); + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisPermitOverridesRuleAlg.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisPermitOverridesRuleAlg.java new file mode 100644 index 0000000..0c68bca --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/combine/AnalysisPermitOverridesRuleAlg.java @@ -0,0 +1,135 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.combine; + +import java.net.URI; +import java.util.Iterator; +import java.util.List; + +import eu.aniketos.securebpmn.xacml.AnalysisCtx; + +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.Rule; +import com.sun.xacml.combine.CombinerElement; +import com.sun.xacml.combine.CombinerParameter; +import com.sun.xacml.combine.PermitOverridesRuleAlg; +import com.sun.xacml.combine.RuleCombinerElement; +import com.sun.xacml.ctx.Result; + +public class AnalysisPermitOverridesRuleAlg extends PermitOverridesRuleAlg { + + public AnalysisPermitOverridesRuleAlg() { + super(); + + } + + public void setConfigurationStore(ConfigurationStore conf) { + //this.conf = conf; + } + + /** + * Protected constructor used by the ordered version of this algorithm. + * + * @param identifier the algorithm's identifier + */ + protected AnalysisPermitOverridesRuleAlg(URI identifier) { + super(identifier); + } + + public Result combine(EvaluationCtx context, List parameters, + List ruleElements) { + boolean atLeastOneError = false; + boolean potentialPermit = false; + boolean atLeastOneDeny = false; + Result firstIndeterminateResult = null; + Iterator it = ruleElements.iterator(); + + Result finalResult = null; + + while (it.hasNext()) { + Rule rule = ((RuleCombinerElement)(it.next())).getRule(); + Result result = rule.evaluate(context); + int value = result.getDecision(); + + // if there was a value of PERMIT, then regardless of what + // else we've seen, we always return PERMIT + if (value == Result.DECISION_PERMIT) { + if ( ((AnalysisCtx)context).getEvalInfo().isMissingAttribute() ) { + if ( finalResult == null) { + finalResult = result; + } + } else { + return result; + } + } + + // if it was INDETERMINATE, then we couldn't figure something + // out, so we keep track of these cases... + if (value == Result.DECISION_INDETERMINATE) { + atLeastOneError = true; + + // there are no rules about what to do if multiple cases + // cause errors, so we'll just return the first one + if (firstIndeterminateResult == null) { + firstIndeterminateResult = result; + } + + // if the Rule's effect is PERMIT, then we can't let this + // alg return DENY, since this Rule might have permitted + // if it could do its stuff + if (rule.getEffect() == Result.DECISION_PERMIT) { + potentialPermit = true; + } + } else { + // keep track of whether we had at least one rule that + // actually pertained to the request + if (value == Result.DECISION_DENY) { + atLeastOneDeny = true; + } + } + } + + if ( finalResult != null ) { + return finalResult; + } + + // we didn't explicitly PERMIT, but we might have had some Rule + // been evaluated, so we have to return INDETERMINATE + if (potentialPermit) { + return firstIndeterminateResult; + } + + // some Rule said DENY, so since nothing could have permitted, + // we return DENY + if (atLeastOneDeny) { + return new Result(Result.DECISION_DENY, + context); + } + + // we didn't find anything that said DENY, but if we had a + // problem with one of the Rules, then we're INDETERMINATE + if (atLeastOneError) { + return firstIndeterminateResult; + } + + // if we hit this point, then none of the rules actually applied + // to us, so we return NOT_APPLICABLE + return new Result(Result.DECISION_NOT_APPLICABLE, + context); + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/cond/AnalysisLogicalFunction.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/cond/AnalysisLogicalFunction.java new file mode 100644 index 0000000..e4f221b --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/cond/AnalysisLogicalFunction.java @@ -0,0 +1,108 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.cond; + +import java.util.Iterator; +import java.util.List; + +import eu.aniketos.securebpmn.xacml.AnalysisCtx; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BooleanAttribute; +import com.sun.xacml.cond.Evaluatable; +import com.sun.xacml.cond.EvaluationResult; +import com.sun.xacml.cond.Expression; +import com.sun.xacml.cond.LogicalFunction; + +/** + * todo define and/or + * + */ +public class AnalysisLogicalFunction extends LogicalFunction { + + public AnalysisLogicalFunction(String functionName) { + super(functionName); + } + // internal identifiers for each of the supported functions + private static final int ID_OR = 0; + private static final int ID_AND = 1; + + /** + * Private helper that looks up the private id based on the function name. + */ + protected static int getId(String functionName) { + if (functionName.equals(NAME_OR)) { + return ID_OR; + } else if (functionName.equals(NAME_AND)) { + return ID_AND; + } else { + throw new IllegalArgumentException("unknown logical function: " + + functionName); + } + } + + /** + * Evaluate the function, using the specified parameters. + * + * @param inputs a List of Evaluatable + * objects representing the arguments passed to the function + * @param context an EvaluationCtx so that the + * Evaluatable objects can be evaluated + * @return an EvaluationResult representing the + * function's result + */ + @Override + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + + // Evaluate the arguments one by one. As soon as we can + // return a result, do so. Return Indeterminate if any argument + // evaluated is indeterminate. + Iterator it = inputs.iterator(); + while (it.hasNext()) { + Evaluatable eval = (Evaluatable)(it.next()); + + // Evaluate the argument + EvaluationResult result = eval.evaluate(context); + if (result.indeterminate()) { + return result; + } + + AttributeValue value = result.getAttributeValue(); + boolean argBooleanValue = ((BooleanAttribute)value).getValue(); + + if (getFunctionId() == ID_OR) { + if (argBooleanValue && + ! ((AnalysisCtx)context).getEvalInfo().isMissingAttribute()) { + // TODO unmark super-element as not abstract + return EvaluationResult.getTrueInstance(); + } + } else if (getFunctionId() == ID_AND) { + if (!argBooleanValue && + ! ((AnalysisCtx)context).getEvalInfo().isMissingAttribute()) { + // TODO unmark super-element as not abstract + return EvaluationResult.getFalseInstance(); + } + } + } + + if (getFunctionId() == ID_OR) { + return EvaluationResult.getFalseInstance(); + } + return EvaluationResult.getTrueInstance(); + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/cond/CustomCompareFunction.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/cond/CustomCompareFunction.java new file mode 100644 index 0000000..1648ee5 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/cond/CustomCompareFunction.java @@ -0,0 +1,135 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.cond; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.attr.AnyURIAttribute; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BooleanAttribute; +import com.sun.xacml.attr.StringAttribute; +import com.sun.xacml.cond.EvaluationResult; +import com.sun.xacml.cond.Expression; +import com.sun.xacml.cond.FunctionBase; + +public class CustomCompareFunction extends FunctionBase { + + public static final String NAMESPACE = "urn:custom:"; + + public static final String NAME_STRING_STARTSWITH = NAMESPACE + "string-starts-with"; + public static final int ID_STRING_STARTSWITH = 0; + + public static final String NAME_URI_STARTSWITH = NAMESPACE + "uri-starts-with"; + public static final int ID_URI_STARTSWITH = 1; + + public static final String NAME_URI_STARTSWITH_STRING = NAMESPACE + "uri-starts-with-string"; + public static final int ID_URI_STARTSWITH_STRING = 2; + + + private static final String[][] functionParams = new String[][] { + new String[] { StringAttribute.identifier, StringAttribute.identifier }, + new String[] { AnyURIAttribute.identifier, AnyURIAttribute.identifier }, + new String[] { AnyURIAttribute.identifier, StringAttribute.identifier } + }; + + + /** + * Creates a new StringFunction object. + * + * @param functionName the standard XACML name of the function to be + * handled by this object, including the full namespace + * + * @throws IllegalArgumentException if the function is unknown + */ + public CustomCompareFunction(String functionName) { + super (functionName, getId(functionName), + functionParams[getId(functionName)], + new boolean[] {false, false}, + BooleanAttribute.identifier, false); + +// int id = getId(functionName); +// +// switch ( id ) { +// case ID_STRING_STARTSWITH: +// super(functionName, getId(functionName), StringAttribute.identifier, +// false, 2, BooleanAttribute.identifier, false); +// +// } + + } + + public static Set getSupportedIdentifiers() { + Set set = new HashSet(); + + set.add(NAME_STRING_STARTSWITH); + set.add(NAME_URI_STARTSWITH); + set.add(NAME_URI_STARTSWITH_STRING); + + return set; + } + + public EvaluationResult evaluate(List inputs, EvaluationCtx context) { + + // Evaluate the arguments + AttributeValue [] argValues = new AttributeValue [inputs.size()]; + EvaluationResult result = evalArgs(inputs, context, argValues); + if (result != null) { + return result; + } + // Now that we have real values, perform the comparison operation + + String s1, s2; + + boolean resultVal; + + switch (getFunctionId()) { + case ID_STRING_STARTSWITH: + s1 = ((StringAttribute) argValues[0]).getValue(); + s2 = ((StringAttribute) argValues[1]).getValue(); + break; + case ID_URI_STARTSWITH: + s1 = (((AnyURIAttribute) argValues[0]).getValue()).toString(); + s2 = (((AnyURIAttribute) argValues[1]).getValue()).toString(); + break; + case ID_URI_STARTSWITH_STRING: + s1 = (((AnyURIAttribute) argValues[0]).getValue()).toString(); + s2 = ((StringAttribute) argValues[1]).getValue(); + break; + default : + throw new IllegalArgumentException("unknown functionId " + getFunctionId()); + } + resultVal = s1.startsWith(s2) | s2.startsWith(s1); + + return EvaluationResult.getInstance(resultVal); + } + + private static int getId(String functionName) { + if ( NAME_STRING_STARTSWITH.equals(functionName) ) { + return ID_STRING_STARTSWITH; + } else if ( NAME_URI_STARTSWITH.equals(functionName) ) { + return ID_URI_STARTSWITH; + } else if ( NAME_URI_STARTSWITH_STRING.equals(functionName) ) { + return ID_URI_STARTSWITH_STRING; + } + + + throw new IllegalArgumentException("unknown match function: " + + functionName); + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/cond/CustomFunctionCluster.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/cond/CustomFunctionCluster.java new file mode 100644 index 0000000..c4d5a18 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/cond/CustomFunctionCluster.java @@ -0,0 +1,49 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.cond; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.apache.log4j.Logger; + +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.cond.Function; +import com.sun.xacml.cond.cluster.FunctionCluster; + +public class CustomFunctionCluster implements FunctionCluster { + + private static Logger logger = Logger.getLogger(CustomFunctionCluster.class); + + public CustomFunctionCluster() { + logger.debug("Loading CustomFunctionCluster"); + } + + public Set getSupportedFunctions() { + Set set = new HashSet(); + + Iterator it = CustomCompareFunction.getSupportedIdentifiers().iterator(); + while (it.hasNext()) { + set.add(new CustomCompareFunction(it.next())); + } + return set; + } + + public void setConfigurationStore(ConfigurationStore confStore) { + + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/finder/MySVNClient.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/finder/MySVNClient.java new file mode 100644 index 0000000..25392ae --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/finder/MySVNClient.java @@ -0,0 +1,198 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.finder; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.List; + +import org.apache.log4j.Logger; +import org.tmatesoft.svn.core.SVNErrorCode; +import org.tmatesoft.svn.core.SVNErrorMessage; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNNodeKind; +import org.tmatesoft.svn.core.SVNProperties; +import org.tmatesoft.svn.core.SVNURL; +import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager; +import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory; +import org.tmatesoft.svn.core.io.SVNRepository; +import org.tmatesoft.svn.core.io.SVNRepositoryFactory; +import org.tmatesoft.svn.core.wc.SVNWCUtil; + +public class MySVNClient { + private SVNRepository repository; + private String svn_url, username, password; + private long version; + + private Logger logger = Logger.getLogger(MySVNClient.class); + + public static final String COMMIT_VERSION = "svn:entry:committed-rev", + COMMIT_DATE = "svn:entry:committed-date", + VERION = "svn:entry:revision"; + + + public MySVNClient(String svn_url, String username, String password, long version) { + this.svn_url = svn_url; + this.username = username; + this.password = password; + this.version = version; + init(); + } + + public MySVNClient(List args) { + if ( args.size() < 3 ) { + throw new RuntimeException("Missing parameters for " + this.getClass().toString()); + } else { + svn_url = args.get(0); + username = args.get(1); + password = args.get(2); + + version = -1; + + if ( args.size() >= 4 ) { + try { + version = Integer.parseInt(args.get(3)); + } catch(NumberFormatException e) { + logger.warn("Could not retreive int value from " + args.get(3) + ", using -1 as default"); + } + } + } + init(); + } + + // String svn_url, String username, String password, int version + private void init() { + logger.info("Creating MySVNClient for svn " + svn_url + ", username " + username + ", password " + password.replaceAll(".", "\\*")); + + DAVRepositoryFactory.setup( ); + SVNURL url; + try { + url = SVNURL.parseURIDecoded(svn_url); + repository = SVNRepositoryFactory.create( url ); + + ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager( username , password ); + repository.setAuthenticationManager( authManager ); + } catch (SVNException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + public long getCheckinSVNVersion(String svn_path) { + + SVNProperties props = new SVNProperties(); + try { + repository.getFile(svn_path, version, props, null); + return Long.parseLong(props.getStringValue(COMMIT_VERSION)); + } catch (SVNException e) { + logger.error("Could not retreive file infos for " + svn_path + ": " + e.getMessage(), e); + return -1; + } catch (NumberFormatException e) { + logger.warn("Could not transform committed revision " + props.getStringValue("svn:entry:committed-rev") + " to a long value"); + return -1; + } + } + + public long getSVNVersion(String svn_path) { + + SVNProperties props = new SVNProperties(); + try { + repository.getFile(svn_path, version, props, null); + return Long.parseLong(props.getStringValue(VERION)); + } catch (SVNException e) { + logger.error("Could not retreive file infos for " + svn_path + ": " + e.getMessage(), e); + return -1; + } catch (NumberFormatException e) { + logger.warn("Could not transform committed revision " + props.getStringValue("svn:entry:committed-rev") + " to a long value"); + return -1; + } + } + + + + public long downloadFile(String svn_path, String local_path) throws SVNException, IOException { + SVNNodeKind nodeKind = repository.checkPath(svn_path, version); + + if ( nodeKind == SVNNodeKind.FILE ) { + SVNProperties props = new SVNProperties(); + FileOutputStream fOS = new FileOutputStream(new File(local_path)); + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + long updated = repository.getFile(svn_path, version, props, fOS); + buffer.flush(); + buffer.close(); + try { + updated = Long.parseLong(props.getStringValue(COMMIT_VERSION)); + } catch (NumberFormatException e) { + logger.warn("Could not transform committed revision " + props.getStringValue("svn:entry:committed-rev") + " to a long value"); + } + return updated; + } else { + throw new SVNException(SVNErrorMessage.create(SVNErrorCode.BAD_FILENAME, "requested file " + svn_path + " is not a file")); + } + + } + + public String getTextFile(String name) throws SVNException { + return getTextFile(name, this.version, null, null); + } + + public String getTextFile(String name, int version) throws SVNException { + return getTextFile(name, version, null, null); + } + + public String getTextFile(String name, long version, SVNProperties props, ByteArrayOutputStream buffer) throws SVNException { + if ( logger.isDebugEnabled() ) { + logger.debug("Try to retreive file " + repository.getLocation().toString() + "/" + name + " in version " + version); + } + SVNNodeKind nodeKind = repository.checkPath(name, version ); + + if ( nodeKind == SVNNodeKind.FILE ) { + if ( buffer == null ) { + buffer = new ByteArrayOutputStream(); + } else { + buffer.reset(); + } + long revision = repository.getFile( name , version , props , buffer ); + if ( logger.isDebugEnabled() ) { + logger.debug("got " + name + " in revision " + revision); + } + + return buffer.toString(); + } else { + logger.error("URL \"" + svn_url + "/" + name + "\" does not point to a file or does not exist"); + return null; + } + } + + public String getSvn_url() { + return svn_url; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + public long getVersion() { + return version; + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/finder/SVNPolicyFinderModule.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/finder/SVNPolicyFinderModule.java new file mode 100644 index 0000000..e7ce1e1 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/finder/SVNPolicyFinderModule.java @@ -0,0 +1,294 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.finder; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.StringReader; +import java.util.List; +import java.util.Vector; + +import org.apache.log4j.Logger; +import org.tmatesoft.svn.core.SVNException; +import org.tmatesoft.svn.core.SVNProperties; + +import eu.aniketos.securebpmn.xacml.SVNPDPConfig; +import eu.aniketos.securebpmn.xacml.support.finder.FilePolicyModule; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.PDPConfig; +import com.sun.xacml.ParsingException; +import com.sun.xacml.finder.PolicyFinder; +import com.sun.xacml.support.finder.PolicyReader; + +public class SVNPolicyFinderModule extends FilePolicyModule { + + + protected String svn_url; + protected long version; + + private static Logger logger = Logger.getLogger(SVNPolicyFinderModule.class); + + public static final String XACML_FOLDER = "xacml"; + + protected MySVNClient svn; + + public SVNPolicyFinderModule(List args) { + super(args); + } + + + public SVNPolicyFinderModule(String svn_url, String username, String password, int version) { + svn = new MySVNClient(svn_url, username, password, version); + } + + public SVNPolicyFinderModule(MySVNClient svnClient) { + svn = svnClient; + } + + public SVNPolicyFinderModule() { + + } + + + @Override + public void init(PolicyFinder finder) { + + logger.debug("Initializing SVNPolicyFinderModule"); + + svnInit(finder); + + this.svn_url = svn.getSvn_url(); + this.version = svn.getVersion(); + + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + List policyFiles = null; + try { + policyFiles = getPolicyFileNames(version, buffer); + } catch (SVNException e) { + logger.error("SVNException when reading file " + SVNPDPConfig.POLICY_FILE + " from repository: " + e.getMessage() + ", will not be able to retrieve policies from SVN storage"); + policyFiles = new Vector(); + } + + List policies = getPolicies(finder, policyFiles, version, buffer); + for ( AbstractPolicy policy : policies ) { + super.addPolicy(policy); + } + // svn client is not required any more, release resources locally + svn = null; + } + + /** + * Does some initialization of for a SVN finder, i.e., getting + * a SVN client and setting other parameters such as useLines + * @param finder + */ + protected void svnInit(PolicyFinder finder) { + PDPConfig pdpConfig = finder.getPDPConfiguration(); + + // if we did not get the svn client with the constructor + if ( svn != null ) { + svn = getSVNClient(pdpConfig, finder); + } + + pdpConfig.setCustomAttr(SVNPDPConfig.SVN_CLIENT, svn); + + //check if we have to use lines parser + if ( super.enf_useLines ) { + useLines = true; + } + // check use lines configuration + else if ( confParams.containsKey(CONF_USELINES)) { + useLines = getBool(confParams.get(CONF_USELINES)); + logger.debug("Use lines: " + useLines + " (loaded from FinderModule configuration)"); + } else if ( pdpConfig.getCustomAttr(CONF_USELINES) != null ) { + useLines = getBool( (String) pdpConfig.getCustomAttr(CONF_USELINES)); + logger.debug("Use lines: " + useLines + " (loaded from PDP wide configuration)"); + } + } + + protected MySVNClient getSVNClient(PDPConfig pdpConfig, PolicyFinder finder) { + + // first, check if there is a local configuration + List confArgs = null; + if ( confParams.containsKey(SVNPDPConfig.SVN_URL) && confParams.containsKey(SVNPDPConfig.USERNAME) && + confParams.containsKey(SVNPDPConfig.PASSWORD) ) { + confArgs = new Vector(); + confArgs.add(confParams.get(SVNPDPConfig.SVN_URL)); + confArgs.add(confParams.get(SVNPDPConfig.USERNAME)); + confArgs.add(confParams.get(SVNPDPConfig.PASSWORD)); + if (confParams.get(SVNPDPConfig.VERSION) != null ) { + confArgs.add(confParams.get(SVNPDPConfig.VERSION)); + } + logger.info("Loading SVN configuration from FinderModule configuration: " + + confParams.get(SVNPDPConfig.SVN_URL) +" in version " + confParams.get(SVNPDPConfig.VERSION)); + } + // check if we can reuse an existing client + else if (pdpConfig.getCustomAttr(SVNPDPConfig.SVN_CLIENT) != null) { + MySVNClient client = (MySVNClient) pdpConfig.getCustomAttr(SVNPDPConfig.SVN_CLIENT); + logger.info("Using PDP wide SVN client and configuration: " + svn.getSvn_url() + + " in version " + svn.getVersion()); + return client; + } + // check if there is a pdp wide svn configuration + else if (pdpConfig.getCustomAttr(SVNPDPConfig.SVN_URL) != null && pdpConfig.getCustomAttr(SVNPDPConfig.USERNAME) != null && + pdpConfig.getCustomAttr(SVNPDPConfig.PASSWORD) != null ) { + confArgs = new Vector(); + confArgs.add( (String) pdpConfig.getCustomAttr(SVNPDPConfig.SVN_URL)); + confArgs.add( (String) pdpConfig.getCustomAttr(SVNPDPConfig.USERNAME)); + confArgs.add( (String) pdpConfig.getCustomAttr(SVNPDPConfig.PASSWORD)); + if ( pdpConfig.getCustomAttr(SVNPDPConfig.VERSION) != null ) { + confArgs.add( (String) pdpConfig.getCustomAttr(SVNPDPConfig.VERSION)); + } + logger.info("Loading SVN configuration from PDP wide configuration: " + + pdpConfig.getCustomAttr(SVNPDPConfig.SVN_URL) +" in version " + pdpConfig.getCustomAttr(SVNPDPConfig.VERSION)); + } else { + logger.fatal("No configuration for SVN access found; No policies will be loaded"); + } + + if (confArgs != null ) { + return new MySVNClient(confArgs); + } else { + return null; + } + } + + + + protected List getPolicyFileNames(long version, ByteArrayOutputStream buffer) throws SVNException { + List fileNames = new Vector(); + + String policiesFile = svn.getTextFile(XACML_FOLDER + "/" + SVNPDPConfig.POLICY_FILE, version, null, buffer); + if ( policiesFile == null ) { + logger.error("Could not find policies file (" + svn_url + "/" + XACML_FOLDER + "/" + SVNPDPConfig.POLICY_FILE); + throw new RuntimeException("Could not find policies file (" + svn_url + "/" + XACML_FOLDER + "/" + SVNPDPConfig.POLICY_FILE); + } + + BufferedReader reader = new BufferedReader(new StringReader(policiesFile)); + try { + String filePolicy = null; + while ( (filePolicy = reader.readLine()) != null ) { + if ( ! ( filePolicy.startsWith("#") || filePolicy.length() == 0) ) { + fileNames.add(filePolicy.trim()); + } + } + } catch (IOException e) { + // must not happen as stream is got from a string... + } + return fileNames; + } + + protected List getPolicies(PolicyFinder finder, + List policyFileNames, long version, ByteArrayOutputStream buffer) { + List policies = new Vector(); + + SVNProperties props = new SVNProperties(); + PolicyReader reader = new PolicyReader(finder, + java.util.logging.Logger.getLogger(this.getClass().getName()), null); + if ( buffer == null ) { + buffer = new ByteArrayOutputStream(); + } + + for ( String policyFile : policyFileNames ) { + String policy; + try { + policy = svn.getTextFile(XACML_FOLDER + "/" + policyFile, version, props, buffer); + + if ( policy == null ) { + logger.error("Could not retreive " + policyFile + " from SVN repository. WARNING: This policy will not be loaded"); + } else { + policies.add(reader.readPolicy(new ByteArrayInputStream(policy.getBytes()))); + logger.info("Loaded policies from " + policyFile + " (checked in with version " + + props.getStringValue(MySVNClient.COMMIT_VERSION) + " on " + + props.getStringValue(MySVNClient.COMMIT_DATE) + ")"); // + props.clear(); + } + } catch (SVNException e) { + logger.error("SVN Error at retreiving " + policyFile + ": " + e.getMessage() + ". WARNING: This policy will not be loaded"); + } catch (ParsingException e) { + logger.error("ParsingException at parsing " + policyFile + ": " + e.getMessage() + ". WARNING: This policy will not be loaded"); + e.printStackTrace(); + } + } + return policies; + } + + + + + + +// try { +// String policiesFile = svn.getTextFile(XACML_FOLDER + "/" + SVNPDPConfig.POLICY_FILE, version, props, buffer); +// +// if ( policiesFile == null ) { +// logger.error("Could not find policies file (" + svn_url + "/" + XACML_FOLDER + "/" + SVNPDPConfig.POLICY_FILE); +// throw new RuntimeException("Could not find policies file (" + svn_url + "/" + XACML_FOLDER + "/" + SVNPDPConfig.POLICY_FILE); +// } +// +// BufferedReader reader = new BufferedReader(new StringReader(policiesFile)); +// +// +// String filePolicy = null; +// try { +// while ( (filePolicy = reader.readLine()) != null ) { +// if ( ! ( filePolicy.startsWith("#") || filePolicy.length() == 0) ) { +// policyFiles.add(filePolicy.trim()); +// } +// } +// } catch (IOException e) { +// logger.error("IOExeption when reading file " + SVNPDPConfig.POLICY_FILE + " from repository: " + e.getMessage()); +// e.printStackTrace(); +// } +// } catch (SVNException e) { +// logger.error("SVNException when reading file " + SVNPDPConfig.POLICY_FILE + " from repository: " + e.getMessage()); +// e.printStackTrace(); +// } + +// SVNProperties props = new SVNProperties(); +// PolicyReader reader = new PolicyReader(finder, +// java.util.logging.Logger.getLogger(this.getClass().getName()), null); +// +// for ( String policyFile : policyFiles ) { +// String policy; +// try { +// policy = svn.getTextFile(XACML_FOLDER + "/" + policyFile, version, props, buffer); +// +// if ( policy == null ) { +// logger.error("Could not retreive " + policyFile + " from SVN repository. WARNING: This policy will not be loaded"); +// } else { +// super.addPolicy(reader.readPolicy(new ByteArrayInputStream(policy.getBytes()))); +// logger.info("Loaded policies from " + policyFile + " (checked in with version " + +// props.getStringValue(MySVNClient.COMMIT_VERSION) + " on " + +// props.getStringValue(MySVNClient.COMMIT_DATE) + ")"); // +// props.clear(); +// } +// } catch (SVNException e) { +// logger.error("SVN Error at retreiving " + policyFile + ": " + e.getMessage() + ". WARNING: This policy will not be loaded"); +// } catch (ParsingException e) { +// logger.error("ParsingException at parsing " + policyFile + ": " + e.getMessage() + ". WARNING: This policy will not be loaded"); +// e.printStackTrace(); +// } +// } + + +// private void checkForConfig() { +// +// } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/finder/SVNStatePolicyFinderModule.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/finder/SVNStatePolicyFinderModule.java new file mode 100644 index 0000000..33a23e4 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/finder/SVNStatePolicyFinderModule.java @@ -0,0 +1,188 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.finder; + +import java.io.ByteArrayOutputStream; +import java.net.URI; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Vector; + +import org.apache.log4j.Logger; +import org.tmatesoft.svn.core.SVNException; + +import eu.aniketos.securebpmn.xacml.SVNPDPConfig; +import eu.aniketos.securebpmn.xacml.support.finder.IPDPStateEvaluationContext; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.PolicyMetaData; +import com.sun.xacml.VersionConstraints; +import com.sun.xacml.ctx.Status; +import com.sun.xacml.finder.PolicyFinder; +import com.sun.xacml.finder.PolicyFinderResult; + +/** + * + * This class retrieves, in contrast to the super class SVNPolicyFinderModule, + * the information which svn version to use from the context, which has to be + * a IPDPStateEvaluationContext. For this, a "main" instance manages all "sub" + * instances which hold a specific version. + *
      + * This class may be enhanced for productive usage, i.e., check if a new policy + * version will become active in a specific time frame, remove policies which will + * not be used any more from the cache, allow to trigger a load operation to + * circumvent delays for requests first using a new policy version. + * + */ +public class SVNStatePolicyFinderModule extends SVNPolicyFinderModule { + + /* + * there typ "types" of this class: the main instance manages + * all sub instances, i.e., a instance has either the policyCache + * or the version set to a reasonable value + */ + private Map policyCache = null; + private PolicyFinder finder; + + private long version = -1; + + private static final Logger logger = Logger.getLogger(SVNStatePolicyFinderModule.class); + + + @Override + public void init(PolicyFinder finder) { + logger.debug("Creating " + SVNStatePolicyFinderModule.class.getSimpleName() + " as main instance"); + this.finder = finder; + policyCache = new HashMap(); + // do the init, e.g., get svn client + super.svnInit(finder); + } + + + protected synchronized SVNStatePolicyFinderModule loadVersion(Long version) { + if ( policyCache.containsKey(version)) { + return policyCache.get(version); + } else { + SVNStatePolicyFinderModule module = new SVNStatePolicyFinderModule(finder, svn, version.longValue()); + policyCache.put(version, module); + return module; + } + } + + + protected SVNStatePolicyFinderModule(PolicyFinder finder, MySVNClient client, long version) { + logger.debug("Creating " + SVNStatePolicyFinderModule.class.getSimpleName() + " as sub instance"); + super.svn = client; + + super.svnInit(finder); + // create a buffer which can be used for all coming read operations + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + + List policyFileNames = null; + try { + policyFileNames = super.getPolicyFileNames(version, buffer); + } catch (SVNException e) { + logger.error("SVNException when reading file " + SVNPDPConfig.POLICY_FILE + " from repository: " + e.getMessage() + ", will not be able to retrieve policies from SVN storage"); + policyFileNames = new Vector(); + } + + List policies = getPolicies(finder, policyFileNames, version, buffer); + for ( AbstractPolicy policy : policies ) { + super.addPolicy(policy); + } + super.svn = null; + } + + + @Override + public PolicyFinderResult findPolicy(EvaluationCtx context) { + // check if we are the "main" finder which manages the policy cache + if ( policyCache != null ) { + if ( context instanceof IPDPStateEvaluationContext ) { + IPDPStateEvaluationContext stateContext = (IPDPStateEvaluationContext) context; + + SVNStatePolicyFinderModule module = policyCache.get(new Long(stateContext.getVersion())); + if ( module == null ) { + module = loadVersion(new Long(version)); + } + return module.findPolicy(context); + } else { + return new PolicyFinderResult(Status.createStatus(Status.STATUS_PROCESSING_ERROR, "SVNStatePolicyFinderModule requires IPDPStateEvaluationContext")); + } + } else { + // we are a "sub" finder, i.e., we can use our super class impl to find what we neeed + return super.findPolicy(context); + } + } + + @Override + public PolicyFinderResult findPolicy(EvaluationCtx context, + URI idReference, int type, + VersionConstraints constraints, + PolicyMetaData parentMetaData) { + + // check if we are the "main" finder which manages the policy cache + if ( policyCache != null ) { + // we do not need to do checks any more - they must have been failed when searching the main policy + return policyCache.get(new Long( ((IPDPStateEvaluationContext) context).getVersion())). + findPolicy(context, idReference, type, constraints, parentMetaData); + } else { + return super.findPolicy(context, idReference, type, constraints, parentMetaData); + } + } + + +// private long getCurrentPolicyVersion(AttributeFinder finder) { +// try { +// BasicEvaluationCtx ctx = new BasicEvaluationCtx(new RequestCtx(new HashSet(), null, null)); +// EvaluationResult evalResult = finder.findAttribute(Constants.ENVIRONMENT_CAT, TypeIdentifierConstants.INTEGER_URI, PDPSTATE_URI, null, ctx); +// +// return getCurrentPolicyVersion(evalResult); +// } catch (IllegalArgumentException e) { +// e.printStackTrace(); +// } catch (ParsingException e) { +// e.printStackTrace(); +// } +// return -1; +// } +// +// public static long getCurrentPolicyVersion(EvaluationCtx context) { +// return getCurrentPolicyVersion( +// context.getAttribute( +// Constants.ENVIRONMENT_CAT, TypeIdentifierConstants.INTEGER_URI, PDPSTATE_URI, null)); +// } +// +// private static long getCurrentPolicyVersion(EvaluationResult evalResult) { +// if ( !evalResult.getAttributeValue().isBag() || +// ((BagAttribute) evalResult.getAttributeValue()).size() != 1 ) { +// logger.error("Did not retreive a bag with one (" +((BagAttribute) evalResult.getAttributeValue()).size() + +// ") entry after attribute search for current svn policy version number " + +// "SVNStatePolicyFinderModule requires exactly one attribute to be defined"); +// return -1; +// } +// IntegerAttribute attrVal = (IntegerAttribute) ((BagAttribute) evalResult.getAttributeValue()).iterator().next(); +// +// return attrVal.getValue(); +// } +// + + //TODO create policy cache + // get policies in correct version from policy cache - key is svn ID + // + // TODO create a time stamp for when the active policy version was checked +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/finder/impl/PDPStateModule.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/finder/impl/PDPStateModule.java new file mode 100644 index 0000000..809deb7 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/finder/impl/PDPStateModule.java @@ -0,0 +1,29 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.finder.impl; + +import com.sun.xacml.finder.AttributeFinderModule; + +/** + * retreives information + * + */ +public class PDPStateModule extends AttributeFinderModule { + + // role + // relationship + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/finder/impl/RoleFinderFileModule.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/finder/impl/RoleFinderFileModule.java new file mode 100644 index 0000000..fbbd206 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/finder/impl/RoleFinderFileModule.java @@ -0,0 +1,227 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.finder.impl; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; +import java.net.URI; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.Vector; + +import org.apache.log4j.Logger; +import org.tmatesoft.svn.core.SVNException; + +import eu.aniketos.securebpmn.xacml.SVNPDPConfig; +import eu.aniketos.securebpmn.xacml.finder.MySVNClient; +import eu.aniketos.securebpmn.xacml.finder.SVNPolicyFinderModule; + +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.Constants; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BagAttribute; +import com.sun.xacml.attr.StringAttribute; +import com.sun.xacml.attr.TypeIdentifierConstants; +import com.sun.xacml.cond.EvaluationResult; +import com.sun.xacml.finder.AttributeFinderModule; + +/** + * + * This module selects a bag of roles which are assigned + * to the subject in the current evaluation context. + * The role assignment is read from a configuration + * file roles.config at startup of the PDP. This is + * intended for simple tests, for a more sohpisticated + * setup use PDPStateModule which retrieves the current + * state of the assignment from a database at runtime. + * + */ +public class RoleFinderFileModule extends AttributeFinderModule { + + public static final String USER_ROLES = "subject-roles", + CONFIG_FILE = "roles.config"; + + + public static final URI USER_ROLES_URI = URI.create(USER_ROLES); + + private Map> roleAssignments; + + private ConfigurationStore conf; + + private static final Logger logger = Logger.getLogger(RoleFinderFileModule.class); + + public RoleFinderFileModule() { +// roleAssignments = readConfig( +// "burli:Role1;MasterGuru;UseCaseCaptain\n" + +// "maxi:fuzzi;Ruzzi;bulli\n" + +// "\n" + +// " \n" + +// "root:Role1;MasterGuru;Nurse;asdf" +// ); + } + + + public boolean isDesignatorSupported() { + return true; + } + + + public void setConfigurationStore(ConfigurationStore conf) { + this.conf = conf; + if (this.conf != null) { + String config = null; + //check, if there is a svn client + MySVNClient svn = (MySVNClient) conf.getCustomAttr(SVNPDPConfig.SVN_CLIENT); + + if ( svn != null ) { + try { + roleAssignments = readConfig(svn.getTextFile(SVNPolicyFinderModule.XACML_FOLDER + "/" + CONFIG_FILE)); + } catch (SVNException e) { + logger.error("Could not retreive " + CONFIG_FILE + " for role configuration from SVN storage"); + } + } else + + //if there is no config from the svn + if ( config == null ) { + String baseDir = conf.getBaseDir(); + File confFile = new File(baseDir + CONFIG_FILE); + logger.debug("Try to load role configuration from file: " + confFile.getAbsolutePath() + " (baseDir: " + baseDir + ")"); + if ( confFile.exists() ) { + try { + roleAssignments = readConfig(new InputStreamReader(new FileInputStream(confFile))); + } catch (FileNotFoundException e) { + logger.error("File (role configuration) not found: " + confFile.getAbsolutePath() + ": " + e.getMessage(), e); + } + } else { + logger.error("File (role configuration) not found: " + confFile.getAbsolutePath()); + } + } + } else { + logger.error("Did not retreive a valid configuration!"); + } + } + + + private Map> readConfig(Reader in) { + + Map> roleConfig + = new HashMap>(); + BufferedReader reader = new BufferedReader(in); + + String line = null, user, roles; + try { + for ( int i = 0; (line = reader.readLine()) != null ; ++i) { + if ( line.startsWith("#") || line.trim().length() == 0) { + //ignore comments; + continue; + } + int a = line.indexOf(":"); + if ( a < 1 ) { + logger.warn("Error in line " + i + ": Did not find \":\""); + continue; + } + else { + user = line.substring(0, a).trim(); + roles = line.substring(a + 1, line.length()); + StringTokenizer tokenizer = new StringTokenizer(roles, ";"); + Collection tmpCol = new Vector(); + + while ( tokenizer.hasMoreElements()) { + tmpCol.add(StringAttribute.getInstance(tokenizer.nextToken().trim())); + } + roleConfig.put(user, tmpCol); + } + } + } catch (IOException e) { + e.printStackTrace(); + } + + return roleConfig; + } + + /** + * helper function to read the configuration and save it into the local map + * @param config + * @return + */ + private Map> readConfig(String config) { + return readConfig(new StringReader(config)); + } + + @Override + public EvaluationResult findAttribute(URI category, URI attributeType, + URI attributeId, URI issuer, + EvaluationCtx context) { + + if ( USER_ROLES_URI.equals(attributeId) && + TypeIdentifierConstants.STRING_URI.equals(attributeType) ) { + String user = getUserID(context); + if ( user == null || roleAssignments.get(user) == null + || roleAssignments.get(user).size() == 0 ) { + logger.warn("Found no role assignments for user " + user); + } else { + return new EvaluationResult(new BagAttribute(attributeType, roleAssignments.get(user))); + } + } + // if found nothing or not responsible, return empty bag + return new EvaluationResult(BagAttribute.createEmptyBag(attributeType)); + } + + + private String getUserID(EvaluationCtx context) { + +// if ( context instanceof AttrCachingEvaluationCtx ) { +// AttrCachingEvaluationCtx c_context = (AttrCachingEvaluationCtx) context; +// } + + // if ( context instanceof EvaluationIdContext ) + // more efficient impl + // else get "classical" + + // if user == null + //logger.warn("Could not retreive the subject-id from the current context"); + + EvaluationResult result = context.getAttribute(Constants.SUBJECT_CAT, TypeIdentifierConstants.STRING_URI, + Constants.SUBJECT_ID, null); + + if (! result.getAttributeValue().isBag()) { + logger.error("Did not retreive a bag after attribute search"); + return null; + } else { + Iterator it = ((BagAttribute) result.getAttributeValue()).iterator(); + String firstUser = null; + for ( int i = 0; it.hasNext(); ++i) { + String user = ((StringAttribute)it.next()).getValue(); + if ( i > 0) { + logger.warn("Retreived more than subjectID: " + user + " which will be ignored"); + } else { + firstUser = user; + } + } + return firstUser; + } + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/AttributeFinderModuleObserver.aj b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/AttributeFinderModuleObserver.aj new file mode 100644 index 0000000..8336e78 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/AttributeFinderModuleObserver.aj @@ -0,0 +1,42 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp; + +import java.net.URI; + +import eu.aniketos.securebpmn.xacml.finder.IRecordEvaluationContext; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.cond.EvaluationResult; +import com.sun.xacml.finder.AttributeFinderModule; + +aspect AttributeFinderModuleObserver { + + pointcut findAttributeCall(URI category, URI attributeType, URI attributeId, URI issuer, EvaluationCtx context): + call (EvaluationResult AttributeFinderModule.findAttribute(URI, URI, URI, URI, EvaluationCtx)) + && args (category, attributeType, attributeId, issuer, context); + + after(URI category, URI attributeType, URI attributeId, URI issuer, EvaluationCtx context) + returning (EvaluationResult result): + findAttributeCall(category, attributeType, attributeId, issuer, context) { + + if ( context instanceof IRecordEvaluationContext ) { + ((IRecordEvaluationContext) context).retreiveDesignatorAttributeSearch( + category, attributeType, attributeId, issuer, result); + } + } +} + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/EvaluationEventObserver.aj b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/EvaluationEventObserver.aj new file mode 100644 index 0000000..32b33a6 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/EvaluationEventObserver.aj @@ -0,0 +1,214 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + + +package eu.aniketos.securebpmn.xacml.pdp; + +import java.net.URI; +import java.util.List; + +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.EvaluationEventHub; +import eu.aniketos.securebpmn.xacml.AnalysisCtx; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.MatchResult; +import com.sun.xacml.PolicyTreeElement; +import com.sun.xacml.MatchElement; +import com.sun.xacml.Rule; // TODO remove +import com.sun.xacml.combine.CombiningAlgorithm; +import com.sun.xacml.combine.CombinerElement; +import com.sun.xacml.combine.CombinerParameter; +import com.sun.xacml.cond.Evaluatable; +import com.sun.xacml.cond.EvaluationResult; +import com.sun.xacml.cond.Expression; +import com.sun.xacml.cond.Function; +import com.sun.xacml.ctx.Result; +import com.sun.xacml.finder.AttributeFinderModule; +import com.sun.xacml.debug.Locatable; +import com.sun.xacml.debug.RuntimeInfo; + + +/** + * This aspect has two tasks + *
        + *
      • Report all events to the EvaluationEventHub
      • + *
      • Report the information required for creating the call stack to the + * RuntimeInfor Object
      • + *
      + * + */ +aspect EvaluationEventObserver { + + //Policy, PolicySet, PolicyReference, Rule + pointcut evaluateCalled(EvaluationCtx context): + call ( public Result PolicyTreeElement.evaluate(EvaluationCtx) ) + && (target(Locatable)) + && args (context); + + before(EvaluationCtx context) : evaluateCalled(context) { + RuntimeInfo src = ((Locatable) thisJoinPoint.getTarget()).getRuntimeInfo(); + if ( src != null ) { + if ( thisJoinPoint.getThis() instanceof Locatable ) { + src.setCalledFrom( ((Locatable) thisJoinPoint.getThis()).getRuntimeInfo() ); + } + } + if ( context instanceof AnalysisCtx ) { + ((AnalysisCtx) context).getEvalHub().beforePolicyTreeElement( (PolicyTreeElement) thisJoinPoint.getTarget(), context); + } + //AnalysisCtx ctx = (AnalysisCtx) context; + //ctx.getEvalHub().beforePolicyTreeElement( (PolicyTreeElement) thisJoinPoint.getTarget(), context); + } + + after(EvaluationCtx context) returning (Result result) : evaluateCalled(context) { + //AnalysisCtx ctx = (AnalysisCtx) context; + //ctx.getEvalHub().afterPolicyTreeElement( (PolicyTreeElement) thisJoinPoint.getTarget(), context, result); + if ( context instanceof AnalysisCtx ) { + ((AnalysisCtx) context).getEvalHub().afterPolicyTreeElement( (PolicyTreeElement) thisJoinPoint.getTarget(), context, result); + } + RuntimeInfo src = ((Locatable) thisJoinPoint.getTarget()).getRuntimeInfo(); + if ( src != null ) { + if ( thisJoinPoint.getThis() instanceof Locatable ) { + src.unsetCalledFrom( ((Locatable) thisJoinPoint.getThis()).getRuntimeInfo() ); + } + } + } + + + // AttributeDesignator, AttributeSelector, AttributeValue, VariableReference, Condition, Apply + pointcut evaluateCall2(EvaluationCtx context): + call ( public EvaluationResult Evaluatable.evaluate(EvaluationCtx) ) + && (target(Locatable)) + && args (context); + + before(EvaluationCtx context) : evaluateCall2(context) { + RuntimeInfo src = ((Locatable) thisJoinPoint.getTarget()).getRuntimeInfo(); + if ( src != null ) { + src.setCalledFrom( ((Locatable) thisJoinPoint.getThis()).getRuntimeInfo() ); + } + if ( context instanceof AnalysisCtx ) { + ((AnalysisCtx) context).getEvalHub().beforeEvaluatable((Evaluatable) thisJoinPoint.getTarget(), context); + } + //AnalysisCtx ctx = (AnalysisCtx) context; + //ctx.getEvalHub().beforeEvaluatable((Evaluatable) thisJoinPoint.getTarget(), context); + } + + after(EvaluationCtx context) returning (EvaluationResult result) : evaluateCall2(context) { + //AnalysisCtx ctx = (AnalysisCtx) context; + //ctx.getEvalHub().afterEvaluatable( (Evaluatable) thisJoinPoint.getTarget(), context, result); + if ( context instanceof AnalysisCtx ) { + ((AnalysisCtx) context).getEvalHub().afterEvaluatable( (Evaluatable) thisJoinPoint.getTarget(), context, result); + } + RuntimeInfo src = ((Locatable) thisJoinPoint.getTarget()).getRuntimeInfo(); + if ( src != null ) { + src.unsetCalledFrom( ((Locatable) thisJoinPoint.getThis()).getRuntimeInfo() ); + } + } + + + //Target, TargetMatch, TargetMatchGroup, TargetSection + pointcut matchCall(EvaluationCtx context): + call ( public MatchResult MatchElement.match(EvaluationCtx ) ) + && (target(Locatable)) + && args (context); + + before(EvaluationCtx context) : matchCall(context) { + RuntimeInfo src = ((Locatable) thisJoinPoint.getTarget()).getRuntimeInfo(); + if ( src != null ) { + src.setCalledFrom( ((Locatable) thisJoinPoint.getThis()).getRuntimeInfo() ); + } + if ( context instanceof AnalysisCtx ) { + ((AnalysisCtx) context).getEvalHub().beforeMatch((MatchElement) thisJoinPoint.getTarget(), context); + } + //AnalysisCtx ctx = (AnalysisCtx) context; + //ctx.getEvalHub().beforeMatch((MatchElement) thisJoinPoint.getTarget(), context); + } + + after(EvaluationCtx context) returning (MatchResult result) : matchCall(context) { + //AnalysisCtx ctx = (AnalysisCtx) context; + //ctx.getEvalHub().afterMatch( (MatchElement) thisJoinPoint.getTarget(), context, result); + if ( context instanceof AnalysisCtx ) { + ((AnalysisCtx) context).getEvalHub().afterMatch( (MatchElement) thisJoinPoint.getTarget(), context, result); + } + RuntimeInfo src = ((Locatable) thisJoinPoint.getTarget()).getRuntimeInfo(); + if ( src != null ) { + src.unsetCalledFrom( ((Locatable) thisJoinPoint.getThis()).getRuntimeInfo() ); + } + } + + //Function + pointcut evaluateFunction(List inputs, EvaluationCtx context): + call ( public EvaluationResult Function.evaluate(List, EvaluationCtx) ) + && (target(Locatable)) + && args (inputs, context); + + before(List inputs, EvaluationCtx context) : evaluateFunction(inputs, context) { + RuntimeInfo src = ((Locatable) thisJoinPoint.getTarget()).getRuntimeInfo(); + if ( src != null ) { + src.setCalledFrom( ((Locatable) thisJoinPoint.getThis()).getRuntimeInfo() ); + } + if ( context instanceof AnalysisCtx ) { + ((AnalysisCtx) context).getEvalHub().beforeFunction((Function) thisJoinPoint.getTarget( ), inputs, context); + } + //AnalysisCtx ctx = (AnalysisCtx) context; + //ctx.getEvalHub().beforeFunction((Function) thisJoinPoint.getTarget( ), inputs, context); + } + + after(List inputs, EvaluationCtx context) returning (EvaluationResult result) : evaluateFunction(inputs, context) { + //AnalysisCtx ctx = (AnalysisCtx) context; + //ctx.getEvalHub().afterFunction( (Function) thisJoinPoint.getTarget(), inputs, context, result); + if ( context instanceof AnalysisCtx ) { + ((AnalysisCtx) context).getEvalHub().afterFunction( (Function) thisJoinPoint.getTarget(), inputs, context, result); + } + RuntimeInfo src = ((Locatable) thisJoinPoint.getTarget()).getRuntimeInfo(); + if ( src != null ) { + src.unsetCalledFrom( ((Locatable) thisJoinPoint.getThis()).getRuntimeInfo() ); + } + } + + //CombiningAlgorithm + pointcut evaluateCombiningAlg(EvaluationCtx context, List parameters, List inputs): + call ( public Result CombiningAlgorithm.combine(EvaluationCtx, List, List) ) + && (target(Locatable)) + && args (context, parameters, inputs); + + before(EvaluationCtx context, List parameters, List inputs) : evaluateCombiningAlg(context, parameters, inputs) { + RuntimeInfo src = ((Locatable) thisJoinPoint.getTarget()).getRuntimeInfo(); + if ( src != null ) { + src.setCalledFrom( ((Locatable) thisJoinPoint.getThis()).getRuntimeInfo() ); + } + if ( context instanceof AnalysisCtx ) { + ((AnalysisCtx) context).getEvalHub().beforeCombiningAlg((CombiningAlgorithm) thisJoinPoint.getTarget( ), context, parameters, inputs); + } + //AnalysisCtx ctx = (AnalysisCtx) context; + //ctx.getEvalHub().beforeCombiningAlg((CombiningAlgorithm) thisJoinPoint.getTarget( ), context, parameters, inputs); + } + + after(EvaluationCtx context, List parameters, List inputs) returning (Result result) : evaluateCombiningAlg(context, parameters, inputs) { + //AnalysisCtx ctx = (AnalysisCtx) context; + //ctx.getEvalHub().afterCombiningAlg( (CombiningAlgorithm) thisJoinPoint.getTarget(), context, parameters, inputs, result); + if ( context instanceof AnalysisCtx ) { + ((AnalysisCtx) context).getEvalHub().afterCombiningAlg( (CombiningAlgorithm) thisJoinPoint.getTarget(), context, parameters, inputs, result); + } + RuntimeInfo src = ((Locatable) thisJoinPoint.getTarget()).getRuntimeInfo(); + if ( src != null ) { + src.unsetCalledFrom( ((Locatable) thisJoinPoint.getThis()).getRuntimeInfo() ); + } + } + + //TODO: Obligation? +} + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/PDPServer.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/PDPServer.java new file mode 100644 index 0000000..8f0ca30 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/PDPServer.java @@ -0,0 +1,676 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.lang.reflect.Method; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Date; +import java.util.List; +import java.util.Properties; + +import javax.jws.WebService; + +import org.apache.log4j.Logger; +import org.apache.log4j.PropertyConfigurator; + +import eu.aniketos.securebpmn.xacml.api.ErrorType; +import eu.aniketos.securebpmn.xacml.api.ReasonType; +import eu.aniketos.securebpmn.xacml.api.SecurityError; +import eu.aniketos.securebpmn.xacml.api.autho.AuthoAttribute; +import eu.aniketos.securebpmn.xacml.api.autho.AuthoResult; +import eu.aniketos.securebpmn.xacml.api.autho.Decision; +import eu.aniketos.securebpmn.xacml.api.autho.IPDP; +import eu.aniketos.securebpmn.xacml.api.autho.IPDPStateManagement; +import eu.aniketos.securebpmn.xacml.api.idm.IdInfo; +import eu.aniketos.securebpmn.xacml.api.log.AccessControlRequest; +import eu.aniketos.securebpmn.xacml.api.log.ILogStore; +import eu.aniketos.securebpmn.xacml.pdp.idHandler.IDHandler; +import eu.aniketos.securebpmn.xacml.AnalysisConfig; +import eu.aniketos.securebpmn.xacml.AnalysisCtx; +import eu.aniketos.securebpmn.xacml.support.RecordAttributeFinder; +import eu.aniketos.securebpmn.xacml.support.RecordEvaluationContext; +import eu.aniketos.securebpmn.xacml.SVNPDPConfig; +import eu.aniketos.securebpmn.xacml.support.XACML2APIMapper; +import eu.aniketos.securebpmn.xacml.support.XACMLDecoder; +import eu.aniketos.securebpmn.xacml.support.XACMLEncoder; +import eu.aniketos.securebpmn.xacml.combine.AnalysisDenyOverridesPolicyAlg; +import eu.aniketos.securebpmn.xacml.combine.AnalysisDenyOverridesRuleAlg; +import eu.aniketos.securebpmn.xacml.combine.AnalysisFirstApplicablePolicyAlg; +import eu.aniketos.securebpmn.xacml.combine.AnalysisFirstApplicableRuleAlg; +import eu.aniketos.securebpmn.xacml.combine.AnalysisOnlyOneApplicablePolicyAlg; +import eu.aniketos.securebpmn.xacml.combine.AnalysisOrderedDenyOverridesPolicyAlg; +import eu.aniketos.securebpmn.xacml.combine.AnalysisOrderedDenyOverridesRuleAlg; +import eu.aniketos.securebpmn.xacml.combine.AnalysisOrderedPermitOverridesPolicyAlg; +import eu.aniketos.securebpmn.xacml.combine.AnalysisOrderedPermitOverridesRuleAlg; +import eu.aniketos.securebpmn.xacml.combine.AnalysisPermitOverridesPolicyAlg; +import eu.aniketos.securebpmn.xacml.combine.AnalysisPermitOverridesRuleAlg; + +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.PDP; +import com.sun.xacml.PDPConfig; +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; +import com.sun.xacml.combine.BaseCombiningAlgFactory; +import com.sun.xacml.combine.CombiningAlgFactory; +import com.sun.xacml.ctx.RequestCtx; +import com.sun.xacml.ctx.ResponseCtx; +import com.sun.xacml.finder.AttributeFinder; +import com.sun.xacml.finder.RevocationFinder; + +@WebService(endpointInterface = "eu.aniketos.securebpmn.xacml.autho.IPDP", serviceName = "PolicyDecisionPoint", targetNamespace = "http://pdp.aniketos.eu/") +public class PDPServer implements IPDP { + + private static Logger logger = Logger.getLogger(PDPServer.class); + + private static PDPServer pdpServer; + + private PDP xacmlPDP; + private AttributeFinder attrFinder; + private RevocationFinder revocFinder; + + private IDHandler idHandler; + private ILogStore logServer; + private IPDPStateManagement pdpState; + + private boolean log = false; + private boolean pdpStateMgt = false; + private static boolean tomcatEnv = false; + private static String baseDir = null; + + private long start = -1; + + /** + * for analysis, some of the static parameters (e.g., CombiningAlgFactory, + * etc.) have to be reset, i.e., within one JVM only productive OR analysis + * pdp can exist + */ + private static PDP_MODE mode = PDP_MODE.UNSET; + + private static boolean replacedFAnalysis = false; + + private static enum PDP_MODE { + ANALYSIS, PRODUCTIVE, UNSET + } + + private static final String LOG4J_FILENAME = "log4j.properties", + SVN_CONFIG = "svn-config.xml", XACML_CONFIG = "policy-config.xml", + CATALINA_BASE = "CATALINA_BASE", WBAPPS_FOLDER = "webapps", + WEBAPP_NAME = "pdp", WEB_INF = "WEB-INF", SLASH = System + .getProperty("file.separator"); + + public static final String LOG_SERVER = "logServer", + PDPSTATE_MGT = "pdpStateManagement"; + + static { + // check if running in tomcat or not + String catHome = System.getenv(CATALINA_BASE); + File catHomeF; + + if (catHome != null && catHome.length() > 0 + && (catHomeF = new File(catHome)).exists()) { + tomcatEnv = true; + baseDir = catHomeF.getAbsolutePath() + SLASH + WBAPPS_FOLDER + + SLASH + WEBAPP_NAME + SLASH + WEB_INF + SLASH; + String log4jPath = baseDir + LOG4J_FILENAME; + + Properties log4jProps = new Properties(); + try { + // log4jProps.load(new + // BufferedInputStream(PDPServer.class.getResourceAsStream(LOG4J_FILEURL))); + log4jProps.load(new BufferedInputStream(new FileInputStream( + new File(log4jPath)))); + PropertyConfigurator.configure(log4jProps); + logger.info("Loaded log4j configuration from " + log4jPath); + } catch (IOException e) { + // logger.warn("Could not load log4j configuration from " + + // LOG4J_FILEURL + " IOException: " + e.getMessage()); + System.err.println("Could not load log4j configuration from " + + log4jPath + " IOException: " + e.getMessage()); + } catch (Exception e) { + // logger.warn("Could not load log4j configuration from " + + // LOG4J_FILEURL + " " + e.getClass() + ": " + e.getMessage()); + System.err.println("Could not load log4j configuration from " + + log4jPath + " " + e.getClass() + ": " + + e.getMessage()); + } + } else { + tomcatEnv = false; + baseDir = new File("foo").getAbsolutePath(); // "foo" must not exist + baseDir = baseDir.substring(0, baseDir.length() - 3); + + // when used as analysis PDP, host app has to set log4j properties + + logger.info("base direcotry for configuration: " + baseDir); + } + } + + /** + * The empty contructor is used when deploying the PDPServer as productice + * system into a Tomcat environment; thus, it may not be called outside of a + * Tomcat + */ + public PDPServer() { + if (mode == PDP_MODE.UNSET || mode == PDP_MODE.PRODUCTIVE) { + mode = PDP_MODE.PRODUCTIVE; + } else { + throw new RuntimeException( + "Cannot create a productive PDPServer in a JVM where an AnalysisPDP already exists"); + } + + if (pdpServer == null) { + if (!tomcatEnv) { + throw new RuntimeException( + "The empty constructor may not be called when not running within PDP"); + } + + logger.debug("Start loading XACML configuration from configuration files"); + // load pdp configuration from file + ConfigurationStore config = null; + + try { + // check if there is a SVN_CONFIG available + File svn_conf = new File(baseDir + SVN_CONFIG); + if (svn_conf.exists()) { + logger.debug("Found " + SVN_CONFIG + " file in " + baseDir + + "; trying to load configuration from svn"); + try { + PDPConfig pdpconfig = SVNPDPConfig + .getSVNPDPConfig(svn_conf); + logger.info("Loaded Configuration from svn"); + init(pdpconfig); + return; + } catch (SecurityError e) { + logger.error("Could not load svn configuration (SecurityError): " + + e.getMessage()); + } + } + + File confFile = new File(baseDir + XACML_CONFIG); + if (!confFile.exists()) { + logger.fatal("Could not find configuration file " + + confFile.getAbsolutePath()); + return; + } + logger.info("Loading config from " + confFile.getAbsolutePath()); + config = new ConfigurationStore(confFile, baseDir); + // } + } catch (ParsingException e) { + logger.fatal("Could not load Configuration: ParsingException: " + + e.getMessage()); + return; + } + + try { + synchronized (logger) { + if (pdpServer == null) { + init(config.getDefaultPDPConfig()); + pdpServer = this; + } else { + logger.warn("Two threads creating a PDPServer; aborting this thread"); + } + } + } catch (UnknownIdentifierException e) { + logger.fatal("Could not load Configuration: UnknownIdentifierException: " + + e.getMessage()); + } + } else { + copyFromStatic(); + } + } + + /** + * + */ + public PDPServer(File confFile) throws FileNotFoundException, + ParsingException, UnknownIdentifierException { + + logger.info("Loading XACML configuration from " + + confFile.getAbsolutePath()); + ConfigurationStore config = new ConfigurationStore(confFile); + + init(config.getDefaultPDPConfig()); + } + + /** + * + */ + public PDPServer(File confFile, String baseDir) + throws FileNotFoundException, ParsingException, + UnknownIdentifierException { + + logger.info("Loading XACML configuration from " + + confFile.getAbsolutePath() + ", baseDir: " + baseDir); + ConfigurationStore config = new ConfigurationStore(new FileInputStream( + confFile), baseDir); + + init(config.getDefaultPDPConfig()); + } + + /** + * Loads a new PDPSever instance + */ + public PDPServer(PDPConfig configuration) { + + logger.info("Creating new PDPServer from configuration"); + init(configuration); + } + + /** + * @param configuration + */ + private void init(PDPConfig configuration) { + // load IDHandler with corresponding settings; IDResolver and IDManager + + // load XACML Engine + logger.info("Loading XACML engine"); + start = new Date().getTime(); + this.attrFinder = configuration.getAttributeFinder(); + this.revocFinder = configuration.getRevocationFinder(); + xacmlPDP = new PDP(configuration); + logger.info("Loaded XACML engine" + + (start == -1 ? "" : " in " + (new Date().getTime() - start) + + "ms")); + + // load logServer + String logServerName = null; + if ((logServerName = (String) configuration.getCustomAttr(LOG_SERVER)) != null) { + Class logServerClass; + try { + logger.info("Loading LogServer from class " + logServerName); + logServerClass = Class.forName(logServerName); + Method getInstance = logServerClass.getMethod("getInstance", + (Class[]) null); + start = new Date().getTime(); + logServer = (ILogStore) getInstance.invoke(null, + (Object[]) null); + // TODO changed to false + log = false; + this.attrFinder = new RecordAttributeFinder(attrFinder); + logger.info("Loaded LogServer with class " + + logServer.getClass() + " in " + + (new Date().getTime() - start) + "ms"); + } catch (Exception e) { + // check if rootcause is "known"... + if (e.getCause() != null + && e.getCause() + .getClass() + .getName() + .equals("org.hibernate.exception.JDBCConnectionException")) { + logger.error("Could not load LogServer: JDBCConnectionException: " + + e.getMessage()); + e.printStackTrace(); + } else { + logger.error( + "Could not load LogServer from class " + + logServerName + ": " + e.getClass() + + " - " + e.getMessage(), e); + e.printStackTrace(); + } + } + } else { + logger.debug("No entry for LogServer in configuration found"); + } + + String pdpStateManager = null; + if ((pdpStateManager = (String) configuration + .getCustomAttr(PDPSTATE_MGT)) != null) { + Class pdpStateMgtClass; + try { + logger.info("Loading PDPStateManagement from class " + + pdpStateManager); + pdpStateMgtClass = Class.forName(pdpStateManager); + Method getInstance = pdpStateMgtClass.getMethod("getInstance", + (Class[]) null); + start = new Date().getTime(); + pdpState = (IPDPStateManagement) getInstance.invoke(null, + (Object[]) null); + pdpStateMgt = true; + logger.info("Loaded PDPStateManagement with class " + + logServer.getClass() + " in " + + (new Date().getTime() - start) + "ms"); + } catch (Exception e) { + // check if rootcause is "known"... + if (e.getCause() != null + && e.getCause() + .getClass() + .getName() + .equals("org.hibernate.exception.JDBCConnectionException")) { + logger.error("Could not load PDPStateManagement: JDBCConnectionException: " + + e.getMessage()); + e.printStackTrace(); + } else { + logger.error( + "Could not load PDPStateManagement from class " + + logServerName + ": " + e.getClass() + + " - " + e.getMessage(), e); + e.printStackTrace(); + } + } + } else { + logger.debug("No entry for LogServer in configuration found"); + } + logger.info("Loaded PDPServer (LogServer: " + log + + ", PDPStateManagement: " + pdpStateMgt + ")"); + } + + /** + * "copy constructor"... PDPServer has to be a singleton, but for the web + * service framework a public constructor is required; thus, this creates a + * pseudo-further instance (pseudo in the sense, as it holds the same + * private elements as the "singleton" instance + */ + private void copyFromStatic() { + logger.warn("A second instance of PDPServer is created!"); + + this.xacmlPDP = pdpServer.xacmlPDP; + this.idHandler = pdpServer.idHandler; + this.log = pdpServer.log; + // TODO keep up to date + } + + public String evaluateXACML(String xacmlRequest) throws SecurityError { + + AccessControlRequest logEntry = null; + Long evaluationId = null; + if (log) { + evaluationId = logServer.getNewEvaluationId(); + logEntry = new AccessControlRequest(evaluationId, xacmlRequest); + } + + RequestCtx request = XACMLDecoder.decodeRequestCtx(xacmlRequest); + PDPResult res = evaluate(request, evaluationId); + ResponseCtx response = res.getResponseCtx(); + String responseStr = XACMLEncoder.encodeResponseCtx(response); + + if (log) { + RecordEvaluationContext ctx = (RecordEvaluationContext) res + .getEvaluationCtx(); + logEntry.finished(request, response, responseStr, + ctx.getExecTime(), ctx.getVersion(), + ctx.getDesignatorAttributes()); + logServer.storeAccessControlRequest(logEntry); + } + + return responseStr; + } + + public AuthoResult evaluate(IdInfo idInfo, String resource, String action, + List attributes) throws SecurityError { + + if (idInfo == null || resource == null) { + logger.error("Received request with idInfo or resource being null"); + throw new SecurityError(ErrorType.AUTHORIZATION_FAILED, + ReasonType.INVALID_PARAMETERS, + "Parameters \"idInfo\" or \"resource\" may not be null!"); + } + URI resourceUri = null; + try { + resourceUri = new URI(resource); + } catch (URISyntaxException e) { + logger.error("Received request with resource not being an URI"); + throw new SecurityError(ErrorType.AUTHORIZATION_FAILED, + ReasonType.INVALID_PARAMETERS, + "Parameters \"resource\" has to be an URI!"); + } + + AccessControlRequest logEntry = null; + Long evaluationId = null; + if (log) { + evaluationId = logServer.getNewEvaluationId(); + logEntry = new AccessControlRequest(evaluationId, idInfo, + resourceUri, action, attributes); + } + // create XACML request + RequestCtx request = XACMLDecoder.decodeRequestCtx(idInfo, resourceUri, + action, attributes); + + // TODO sysout comment + // System.out.println("start with eval of " + evaluationId.longValue() + + // ", " + XACMLEncoder.encodeRequestCtx(request)); + // evaluate + PDPResult res = evaluate(request, evaluationId); + ResponseCtx response = res.getResponseCtx(); + // translate result + AuthoResult result = XACML2APIMapper.getAuthoResult(res + .getResponseCtx()); + + if (log) { + RecordEvaluationContext ctx = (RecordEvaluationContext) res + .getEvaluationCtx(); + logEntry.finished(request, response, result, ctx.getExecTime(), + ctx.getVersion(), ctx.getDesignatorAttributes()); + logServer.storeAccessControlRequest(logEntry); + } + return result; + } + + protected PDPResult evaluate(RequestCtx request, Long evaluationId) + throws SecurityError { + + ResponseCtx response = null; + ; + // RecordEvaluationContext context = null; + EvaluationCtx context = null; + + if (log) { + if (evaluationId == null) { + evaluationId = new Long(-1); + } + // if logging is activated, create a context which is + // able to keep track of all resovled attributes + try { + context = new RecordEvaluationContext(request, attrFinder, + revocFinder, evaluationId); + } catch (ParsingException e) { + logger.error("ParsingException during creation of RecordEvaluationContext: " + + e.getMessage()); + throw new SecurityError(ErrorType.CONFIGURATION_ERROR, + ReasonType.PDE_ENGINE_ERROR); + } + response = xacmlPDP.evaluate(context); + } else { + response = xacmlPDP.evaluate(request); + } + + return new PDPResult(response, context); + } + + /** + * This method creates, based on an existing configuration, a configuration + * as needed for running the PDP in analysis mode. For this, + *
        + *
      • make the static settings
      • + *
      • modify (i.e. create a new) PDPConfig
      • + *
      + * + * @param config + * @return + */ + public AnalysisConfig makeAnalysisConfig(PDPConfig config) { + + // replace all elements which are static and are required to change for + // analysis + replaceStaticAnalysisStuff(); + + return new AnalysisConfig(config); + } + + public ResponseCtx analyze(AnalysisCtx ctx) { + return xacmlPDP.evaluate(ctx); + } + + // TODO check with analysis config? + private synchronized void replaceStaticAnalysisStuff() { + if (!replacedFAnalysis) { + if (mode == PDP_MODE.UNSET || mode == PDP_MODE.ANALYSIS) { + mode = PDP_MODE.ANALYSIS; + } else { + throw new RuntimeException( + "Cannot create an Analysis PDPServer in a JVM where an productive PDP already exists"); + } + + replacedFAnalysis = true; + } + + CombiningAlgFactory factory = new BaseCombiningAlgFactory(); + + factory.addAlgorithm(new AnalysisDenyOverridesPolicyAlg()); + factory.addAlgorithm(new AnalysisDenyOverridesRuleAlg()); + factory.addAlgorithm(new AnalysisFirstApplicablePolicyAlg()); + factory.addAlgorithm(new AnalysisFirstApplicableRuleAlg()); + factory.addAlgorithm(new AnalysisOnlyOneApplicablePolicyAlg()); + factory.addAlgorithm(new AnalysisOrderedDenyOverridesPolicyAlg()); + factory.addAlgorithm(new AnalysisOrderedDenyOverridesRuleAlg()); + factory.addAlgorithm(new AnalysisOrderedPermitOverridesPolicyAlg()); + factory.addAlgorithm(new AnalysisOrderedPermitOverridesRuleAlg()); + factory.addAlgorithm(new AnalysisPermitOverridesPolicyAlg()); + factory.addAlgorithm(new AnalysisPermitOverridesRuleAlg()); + + CombiningAlgFactory.setAllFactories(factory); + } + + public String getXACMLPEPConfig() { + // TODO Auto-generated method stub + return null; + } + + public boolean logBreakGlassAccess(long arg0, String arg1) { + // TODO Auto-generated method stub + return false; + } + + /** + * This function is called by PEPs which have to fulfill the TODO + * obligation, i.e., notify the PDP about an actually executed action which + * influences the state of the PDP. For this, the AccessControlRequest is + * loaded from the logServer and passed to the PDPState manager which + * updates the PDP State according to the request. + */ + public void notifyStateChange(long evaluationId) throws SecurityError { + // get log entry + if (log) { + AccessControlRequest request = logServer + .getAccessControlRequest(new Long(evaluationId)); + if (request == null) { + logger.error("PDP received a notifyChange for evaluationId " + + evaluationId + + " where no AccessControlRequest was stored for or the entry"); + throw new SecurityError(ErrorType.CONFIGURATION_ERROR, + ReasonType.PDE_ENGINE_ERROR, "Invalid evaluationId"); + } else if (!(request.getResult().getDecision() == Decision.DECISION_PERMIT)) { + logger.error("PDP received a notifyChange for evaluationId " + + evaluationId + + " which was not permitted in the first place"); + throw new SecurityError(ErrorType.AUTHORIZATION_FAILED, + ReasonType.DENY, "Referenced request was not permitted"); + } else { + pdpState.updatePDPState(request); + } + } else { + logger.error("Received a notifyStateChange (evaluationId " + + evaluationId + "), but no logService is active!"); + } + } + + public void unload() { + if (this.logServer != null) { + this.logServer.shutdown(); + } + } + + private class PDPResult { + private ResponseCtx resCtx; + private EvaluationCtx recCtx; + + public PDPResult(ResponseCtx resCtx, EvaluationCtx recCtx) { + this.resCtx = resCtx; + this.recCtx = recCtx; + } + + public ResponseCtx getResponseCtx() { + return resCtx; + } + + public EvaluationCtx getEvaluationCtx() { + return recCtx; + } + + // public AuthoResult getAuthoResult() throws SecurityError { + // if ( authoResult == null ) { + // authoResult = new AuthoResult(); + // + // if (resCtx.getResults().size() != 1 ) { + // logger.error("Received unexpected number of results: " + + // resCtx.getResults().size()); + // throw new SecurityError(ErrorType.CONFIGURATION_ERROR, + // ReasonType.PDE_ENGINE_ERROR, + // "Received unexpected number of results"); + // } + // + // Result xacmlResult = resCtx.getResults().iterator().next(); + // + // authoResult.setDecision(Decision.getFromInt(xacmlResult.getDecision())); + // authoResult.setObligations(transform(xacmlResult.getObligations())); + // authoResult.setStatusCode(xacmlResult.getStatus().getCode()); + // authoResult.setStatusMessage(xacmlResult.getStatus().getMessage()); + // + // // TODO get missing attributes + // + // } + // return authoResult; + // } + // + // private List transform(Set xacmlOblgs) { + // if ( xacmlOblgs == null && xacmlOblgs.size() > 0 ) { + // List oblgs = new Vector(); + // + // for ( Obligation xacmlOblg : xacmlOblgs ) { + // AuthoObligation oblg = new AuthoObligation(xacmlOblg.getId()); + // if ( xacmlOblg.getAssignments() != null && + // xacmlOblg.getAssignments().size() > 0 ) { + // Collection attrs = new + // Vector(xacmlOblg.getAssignments().size()); + // for ( Attribute xacmlAttr : xacmlOblg.getAssignments()) { + // attrs.add(new AuthoAttribute(AuthoAttribute.OBLIGATION_CATEGORY, + // xacmlAttr.getId(), xacmlAttr.getValue().getType(), + // xacmlAttr.getValue().toString())); + // } + // oblg.setParameters(attrs); + // } + // oblgs.add(oblg); + // } + // return oblgs; + // } else { + // return null; + // } + // } + + // protected static AuthoResult createAuthoResult(ResponseCtx response) + // throws SecurityError { + // AuthoResult result = new AuthoResult(); + // + + // } + + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/idHandler/IDHandler.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/idHandler/IDHandler.java new file mode 100644 index 0000000..318148d --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/idHandler/IDHandler.java @@ -0,0 +1,59 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.idHandler; + +//import java.util.Date; +// +//import eu.aniketos.securebpmn.xacml.idm.AuthInfo; +//import eu.aniketos.securebpmn.xacml.idm.IDInfo; + +public class IDHandler { + +// private IDInfoCache cache; +// +// private int cacheEntryMinValid = 60; +// +// public IDHandler() { +// cache = new IDInfoCache(); +// } +// +// +// public IDInfo resolveID(AuthInfo authinfo) { +// // TODO authInfo cache? +// IDInfo idInfo = queryIDProvider(authinfo); +// +// IDInfoCacheEntry cacheEntry = cache.getEntry(idInfo); +// +// if ( cacheEntry != null ) { +// long now = new Date().getTime(); +// +// if ( true ) { // check if entry older than cacheEntryMinValid +// //return cacheEntry.foo; +// } +// } +// IDInfo info = queryIDManager(idInfo); +// cache.putEntry(info); +// return info; +// } +// +// private IDInfo queryIDProvider(AuthInfo auhtinfo) { +// return null; +// } +// +// private IDInfo queryIDManager(IDInfo idInfo) { +// return null; +// } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/idHandler/IDInfoCache.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/idHandler/IDInfoCache.java new file mode 100644 index 0000000..d882a71 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/idHandler/IDInfoCache.java @@ -0,0 +1,69 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.idHandler; + +//import java.util.Date; +//import java.util.HashMap; +//import java.util.Map; +// +//import eu.aniketos.securebpmn.xacml.idm.AuthInfo; +//import eu.aniketos.securebpmn.xacml.idm.IDInfo; + +public class IDInfoCache { + +// private static Map cache; +// +// public IDInfoCache() { +// cache = new HashMap(); +// +// //todo start thread which removes old entries +// } +// +// +// +// /** +// * +// * @param idInfo +// */ +// +// public synchronized void putEntry(IDInfo idInfo) { +// //cache.put(new IDInfoKey(), arg1) +// } +// +// public void updateEntry(IDInfo idInfo) { +// +// } +// +// public IDInfoCacheEntry getEntry(IDInfo idInfo) { +// return null; +// } +// +// class IDInfoKey { +// private String userID, idManagerID; +// +// public IDInfoKey(String userID, String idManagerID) { +// this.userID = userID; +// this.idManagerID = idManagerID; +// } +// +// @Override +// public int hashCode() { +// return this.userID.hashCode() + this.idManagerID.hashCode(); +// } +// } +// + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/idHandler/IDInfoCacheEntry.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/idHandler/IDInfoCacheEntry.java new file mode 100644 index 0000000..3db5658 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/idHandler/IDInfoCacheEntry.java @@ -0,0 +1,27 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.idHandler; + +//import java.util.Date; +// +//import eu.aniketos.securebpmn.xacml.idm.AuthInfo; + +public class IDInfoCacheEntry { +// private AuthInfo authInfo; +// private long lastUpdate; +// + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/AnalysisFinderModule.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/AnalysisFinderModule.java new file mode 100644 index 0000000..6a6b748 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/AnalysisFinderModule.java @@ -0,0 +1,99 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation; + +import java.net.URI; +import java.util.List; +import java.util.Vector; + +import org.apache.log4j.Logger; + +import eu.aniketos.securebpmn.xacml.api.autho.AttributeIdentifier; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.attributes.AnalysisAttributeResolver; +import eu.aniketos.securebpmn.xacml.AnalysisCtx; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.attr.BagAttribute; +import com.sun.xacml.cond.EvaluationResult; +import com.sun.xacml.debug.RuntimeInfo; +import com.sun.xacml.finder.AttributeFinderModule; + +/** + * + * This is an AttributeFinderModule which is used for the analysis + * PDP to control which attributes can or are be resolved. This + * is the AttributeFinderModule which is used by the Workbench, + * whereas one can provide several AnalysisAttributeResolvers + * which are queried according to their registration ordering to + * provide a value (see doc at AnalysisAttributeResolver). + *
      + * If no of the AnalysisAttributeResolvers provide such a value (or no + * one is registered), an empty bag is returned (i.e. resolution failded) + * + */ +public class AnalysisFinderModule extends AttributeFinderModule { + + private List attrResolvers = new Vector(); + + + @Override + public boolean isDesignatorSupported() { + return true; + } + + private static Logger logger = Logger.getLogger(AnalysisFinderModule.class); + + public AnalysisFinderModule() { + + } + + + + + public int addAnalysisAttributeResolver(AnalysisAttributeResolver attrResolver) { + this.attrResolvers.add(attrResolver); + return this.attrResolvers.size(); + } + + public boolean removeAttrResolver(AnalysisAttributeResolver attrResolver) { + return this.attrResolvers.remove(attrResolver); + } + + public void clearAttrResolver() { + this.attrResolvers.clear(); + } + + @Override + public EvaluationResult findAttribute(URI category, URI attributeType, + URI attributeId, URI issuer, + EvaluationCtx context) { + AttributeIdentifier attrId = new AttributeIdentifier(category, attributeType, attributeId, issuer); + RuntimeInfo runtimeInfo = ((AnalysisCtx) context).getEvalInfo().getCurrentRuntimeInfo(); + //context.get + + for (AnalysisAttributeResolver attrResolver : attrResolvers ) { + BagAttribute bagAttr = attrResolver.resolveAttribute(attrId, context, runtimeInfo); + if ( bagAttr != null ) { + return new EvaluationResult(bagAttr); + } + } + if ( logger.isDebugEnabled() ) { + logger.debug("Did not find an AttributeResolver providing a value: returning empty bag for " + + attributeType + " type " + attributeType); + } + return new EvaluationResult(BagAttribute.createEmptyBag(attributeType)); + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/ConditionTargetCapture.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/ConditionTargetCapture.java new file mode 100644 index 0000000..ddbcc13 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/ConditionTargetCapture.java @@ -0,0 +1,224 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation; + +import java.net.URI; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Vector; + +import eu.aniketos.securebpmn.xacml.api.autho.AttributeIdentifier; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.attributes.AttributeHelper; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.MatchElement; +import com.sun.xacml.MatchResult; +import com.sun.xacml.PolicyTreeElement; +import com.sun.xacml.Rule; +import com.sun.xacml.TargetMatch; +import com.sun.xacml.attr.AttributeDesignator; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.combine.CombinerElement; +import com.sun.xacml.combine.CombinerParameter; +import com.sun.xacml.combine.CombiningAlgorithm; +import com.sun.xacml.cond.Evaluatable; +import com.sun.xacml.cond.EvaluationResult; +import com.sun.xacml.cond.Expression; +import com.sun.xacml.cond.Function; +import com.sun.xacml.ctx.Result; +import com.sun.xacml.ctx.Status; +import com.sun.xacml.debug.Locatable; + + +/* + * Rule: TM => TRUE && Condition => fehlt attribut: + * => condition -> effect + * alles andere: wenn matched + effect eindeutig (=> keni fehlendes attribute in sub element) + * => TRUE -> effect + */ + +/** + * + * This class reports all attributes of a rule + *
        + *
      • when the target of the rule matches
      • + *
      • if evaluated or not
      • + *
      + * + */ +public class ConditionTargetCapture implements EvaluationEvents, KnownAttrStore { + + /** + * hashmap which allows to retreive all targetMatches for a policy, policyset or rule + */ + private Map>> policyMatches + = new HashMap>>(); + + /** + * keeps track of the current trace through the policy evauation + */ + private XACMLTree policyTree = new XACMLTree(); + + /** + * saves all attributes which are are "known", i.e., where a fix value for + * this evaluation is given. + */ + private Map knownAttributes; + + /** + * keeps track of all attributes which are requested but in the set of knownAttributes + */ + private Set missingAttribtues = new HashSet(); + +// private static final Logger logger = Logger.getLogger(ConditionTargetCapture.class); + + private static ExtToolTypeEncoder typeEnc = HOLEncoder.getInstance(); + private ExtToolEncoder enc = new PraefixEncoder(typeEnc, this); + + private PolicyTreeElement missingTargetAttr = null; + + //private int policyTreeLevel = 0; + + public ConditionTargetCapture(Map knownAttributes) { + /* should contain all known attributes, may be needed for attributes which are contained + * within a condition but not evaluated at runtime + */ + this.knownAttributes = knownAttributes; + } + + public void afterEvaluatable(Evaluatable target, EvaluationCtx context, + EvaluationResult result) { + // record all evaluated attributes + if ( target instanceof AttributeDesignator ) { + AttributeDesignator attrDsgn = (AttributeDesignator) target; + AttributeIdentifier attrId = AttributeHelper.getAttributeIdentifier(attrDsgn); + + if ( AttributeHelper.containsAbstractValue(result) || + ( result.getStatus() != null && result.getStatus().getCode()!= null + && result.getStatus().getCode().contains(Status.STATUS_MISSING_ATTRIBUTE))) { // missing attribute + missingAttribtues.add(attrId); + PolicyTreeElement fatherEle = AttributeHelper.getPolicyTreeElement( ((Locatable) target).getRuntimeInfo()); + // assure that we do not overwrite an existing value + if ( missingTargetAttr != null && missingTargetAttr != fatherEle && + ! policyTree.getCurrent().isFather(missingTargetAttr)) { + System.err.println("Overwriting missingTargetAttr element!"); + //for now / test cases, throw exception + throw new RuntimeException("Overwriting missingTargetAttr element!"); + } + // remember that we have to print the target/condition for this policy tree element + missingTargetAttr = fatherEle; + } else { + if ( knownAttributes.containsKey(attrId)) { + //TODO compare values + } else { + knownAttributes.put(attrId, result.getAttributeValue()); + } + } + } +// else if ( target instanceof Condition ) { +// System.err.print(" CONDITION TARGETS: "); +// enc.printConditionAndMatches((Condition) target, policyMatches, this.policyTree.getCurrent(), System.err); +// System.err.println(""); +// } + } + + public void beforeFunction(Function target, List inputs, + EvaluationCtx context) { + + } + + + public void beforeMatch(MatchElement target, EvaluationCtx context) { + if ( target instanceof TargetMatch) { + PolicyTreeElement container = AttributeHelper.getPolicyTreeElement( ((Locatable) target).getRuntimeInfo()); + addMatchElement(container, (TargetMatch) target ); + } + } + + private void addMatchElement(PolicyTreeElement container, TargetMatch match) { + initMatches(container); + if ( ! (policyMatches.get(container).containsKey(match.getCategory()))) { + List matches = new Vector(); + matches.add(match); + policyMatches.get(container).put(match.getCategory(), matches); + } else { + policyMatches.get(container).get(match.getCategory()).add(match); + } + } + + private void initMatches(PolicyTreeElement container) { + if ( ! policyMatches.containsKey(container) ) { + policyMatches.put(container, new HashMap>()); + } + } + + public void beforePolicyTreeElement(PolicyTreeElement target, + EvaluationCtx context) { + + policyTree.addChild(target); + initMatches(target); + } + public void afterPolicyTreeElement(PolicyTreeElement target, + EvaluationCtx context, Result result) { + if ( missingTargetAttr == target ) { + //this policytree element contained an unresolved attribute designator + // => relevant to print! + + if ( target instanceof Rule && ((Rule)target).getCondition() != null ) { + System.err.print(" CONDITION TARGETS: "); + enc.printConditionAndMatches(((Rule) target).getCondition(), policyMatches, this.policyTree.getCurrent(), System.err); + System.err.println(""); + } else { + System.err.print(" MATCH TARGETS: "); + enc.printTargetMatches(policyMatches, this.policyTree.getCurrent(), System.err); + System.err.println(""); + } + missingTargetAttr = null; + } + policyTree.close(target); + } + + public AttributeValue getAttributeValue(AttributeIdentifier attrId) { + return this.knownAttributes.get(attrId); + } + + + + + /* + * EMPTY - NON USED STUB FUNCTIONS + */ + public void afterCombiningAlg(CombiningAlgorithm target, + EvaluationCtx context, List parameters, + List inputs, Result result) { } + public void afterFunction(Function target, List inputs, + EvaluationCtx context, EvaluationResult result) { } + public void afterMatch(MatchElement target, EvaluationCtx context, + MatchResult result) { } + public void beforeCombiningAlg(CombiningAlgorithm target, + EvaluationCtx context, List parameters, + List inputs) { } + public void beforeEvaluatable(Evaluatable target, EvaluationCtx context) { } + + public void setAttributeValue(AttributeIdentifier attrId, + AttributeValue attr) { + // TODO Auto-generated method stub + + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/EvalInfo.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/EvalInfo.java new file mode 100644 index 0000000..8d22b4e --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/EvalInfo.java @@ -0,0 +1,77 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation; + +import com.sun.xacml.ctx.Result; + +/** + * + * Saves information about one policy tree element for abstract evaluation: + *
        + *
      • Result of the PolicyTreeElement at evaluation
      • + *
      • Has there been at least one attribute be missing during + * evaluation, and where (in the target, in the condition or in + * a subelement (e.g., for a policy, in a rule)
      • + *
      + * + */ +public class EvalInfo { + + /** + * indicates, where the a (missing) attribute is + */ + public enum MissingAttrType { + Target, + Condition, + subElement + } + + + private Result result; + private boolean[] missingAttribute = new boolean[MissingAttrType.values().length]; + //private String condition; + + public EvalInfo() { + for ( int i = 0; i < MissingAttrType.values().length; ++i) { + missingAttribute[i] = false; + } + } + + public void setMissingAttribtue(MissingAttrType type) { + missingAttribute[type.ordinal()] = true; + } + + public boolean isMissingAttribute() { + for ( int i = 0; i < MissingAttrType.values().length; ++i) { + if (missingAttribute[i]) { + return true; + } + } + return false; + } + + public boolean isMissingAttribute(MissingAttrType type) { + return missingAttribute[type.ordinal()]; + } + + public Result getResult() { + return result; + } + + public void setResult(Result result) { + this.result = result; + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/EvalInfoProvider.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/EvalInfoProvider.java new file mode 100644 index 0000000..99bde7c --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/EvalInfoProvider.java @@ -0,0 +1,185 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation; + +import java.util.List; + +import org.apache.log4j.Logger; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.MatchElement; +import com.sun.xacml.MatchResult; +import com.sun.xacml.PolicyTreeElement; +import com.sun.xacml.combine.CombinerElement; +import com.sun.xacml.combine.CombinerParameter; +import com.sun.xacml.combine.CombiningAlgorithm; +import com.sun.xacml.cond.Evaluatable; +import com.sun.xacml.cond.EvaluationResult; +import com.sun.xacml.cond.Expression; +import com.sun.xacml.cond.Function; +import com.sun.xacml.ctx.Result; +import com.sun.xacml.debug.Locatable; +import com.sun.xacml.debug.RuntimeInfo; + +/** + * This class is automatically loaded and registered when the + * EvaluationEventHub is loaded (as it is required for several + * other classes and analysis techniques, e.g, the Analysis + * Combining Algorithms) + * + */ +public class EvalInfoProvider implements EvaluationEvents { + + + /** + * saves the tree of policyTreeElements + */ + private InfoTree treeElemTree; + + + private InfoTree xacmlTree; + + private static final Logger logger = Logger.getLogger(EvalInfoProvider.class); + + + private boolean evalAllIfUnresolved; + + + public EvalInfoProvider() { + //RootPDPElement root = new RootPDPElement(); + treeElemTree = new InfoTree(); + //treeElemTree.addChild(root, new EvalInfo()); + + xacmlTree = new InfoTree(); + //xacmlTree.addChild(root, new EvalInfo()); + } + + public void clear() { + treeElemTree.clear(); + xacmlTree.clear(); + } + + public boolean isEvalAllIfUnresolved() { + return evalAllIfUnresolved; + } + + public void setEvalAllIfUnresolved(boolean evalAllIfUnresolved) { + this.evalAllIfUnresolved = evalAllIfUnresolved; + } + + + public InfoTree getCurrent() { + return this.xacmlTree.getCurrent(); + } + + public Locatable getCurrentXACMLObject() { + Locatable loc = getCurrent().getElement(); + if ( loc == null ) { + logger.fatal("No runtime information available - " + + "probably you are using the wrong XACML jar " + + "(i.e., not patched with aspectJ)"); + } + return loc; + } + + public RuntimeInfo getCurrentRuntimeInfo() { + return getCurrentXACMLObject().getRuntimeInfo(); + } + + + public InfoTree getCurrentTreeElem() { + return treeElemTree.getCurrent(); + } + + public InfoTree getTreeElemTree() { + return treeElemTree; + } + + public boolean isMissingAttribute() { + return getCurrentTreeElem().getInfo().isMissingAttribute(); + } + + public boolean isCurrentlyAbstract() { + //TODO: check is abstract values got "reduced", e.g., $unkown or #true => result is true, not abstract + return isMissingAttribute(); + } + + + + private void hitTreeElement(PolicyTreeElement target) { + treeElemTree.addChild(target, new EvalInfo()); + } + + private void closeTreeElement(PolicyTreeElement target) { + treeElemTree.close(target); + } + + + + public void beforePolicyTreeElement(PolicyTreeElement target, + EvaluationCtx context) { + hitTreeElement(target); + xacmlTree.addChild(target, new EvalInfo()); + } + + + public void beforeCombiningAlg(CombiningAlgorithm target, + EvaluationCtx context, List parameters, + List inputs) { + xacmlTree.addChild(target, new EvalInfo()); + } + public void beforeEvaluatable(Evaluatable target, EvaluationCtx context) { + xacmlTree.addChild(target, new EvalInfo()); + } + public void beforeFunction(Function target, List inputs, + EvaluationCtx context) { + xacmlTree.addChild(target, new EvalInfo()); + } + public void beforeMatch(MatchElement target, EvaluationCtx context) { + xacmlTree.addChild(target, new EvalInfo()); + } + + + public void afterPolicyTreeElement(PolicyTreeElement target, + EvaluationCtx context, Result result) { + closeTreeElement(target); + xacmlTree.close(target); + } + + public void afterCombiningAlg(CombiningAlgorithm target, + EvaluationCtx context, List parameters, + List inputs, Result result) { + xacmlTree.close(target); + } + + public void afterEvaluatable(Evaluatable target, EvaluationCtx context, + EvaluationResult result) { + xacmlTree.close(target); + } + + public void afterFunction(Function target, List inputs, + EvaluationCtx context, EvaluationResult result) { + xacmlTree.close(target); + } + public void afterMatch(MatchElement target, EvaluationCtx context, + MatchResult result) { + xacmlTree.close(target); + } + + + + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/EvaluationEventHub.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/EvaluationEventHub.java new file mode 100644 index 0000000..befd57a --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/EvaluationEventHub.java @@ -0,0 +1,304 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation; + +import java.util.List; +import java.util.Vector; + +import org.apache.log4j.Logger; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.MatchElement; +import com.sun.xacml.MatchResult; +import com.sun.xacml.PolicyTreeElement; +import com.sun.xacml.combine.CombinerElement; +import com.sun.xacml.combine.CombinerParameter; +import com.sun.xacml.combine.CombiningAlgorithm; +import com.sun.xacml.cond.Evaluatable; +import com.sun.xacml.cond.EvaluationResult; +import com.sun.xacml.cond.Expression; +import com.sun.xacml.cond.Function; +import com.sun.xacml.ctx.Result; + +/** + * + * This class is responsible for retrieving events from within + * the evaluation engine and distribute it to registered classes. + * + * + */ +public class EvaluationEventHub implements EvaluationEvents { + + private List registered = new Vector(); + + private EvalInfoProvider evalInfo; + + private static Logger logger = Logger.getLogger(EvaluationEventHub.class); + + public EvaluationEventHub() { + evalInfo = new EvalInfoProvider(); + this.register(evalInfo); + } + + + /** + * Registers a new listener which will receive notifications about + * the evaluation of events. This notifications are synchron, i.e., + * first, the systems halts as long as the functions are called and, + * second, the order the elements are registered defines how they + * are called: the first registered object is notified as first before + * and as last after the evaluation + * + * + */ + public int register(EvaluationEvents e) { + registered.add(e); + + int pos = -1; + for ( int i = 0; i < registered.size(); ++i ) { + if ( registered.get(i) == e ) { + pos = i; + break; + } + } + logger.debug("Added EvaluationEvents to EvaluationEventHub at position " + pos + " (" + e.getClass() + ")"); + return pos; + } + + public boolean remove(EvaluationEvents e) { + if ( e == evalInfo ) { + return false; + } else { + return registered.remove(e); + } + } + + public void clear() { + for ( int i = 1; i < registered.size(); ++i) { + registered.remove(i); + } + } + + public EvalInfoProvider getEvalInfo() { + return this.evalInfo; + } + + public void clearEvalInfo() { + this.evalInfo.clear(); + } + + + + /* + * BEFORE events + * + */ + + public void beforeEvaluatable(Evaluatable target, EvaluationCtx context) { + for ( int i = 0 ; i < registered.size(); ++i ) { + try { + registered.get(i).beforeEvaluatable(target, context); + } catch (Exception e) { + logger.warn("Evaluation Client (index " + i + ", class " + + registered.get(i).getClass() + " throw an excpetion " + + " when executing beforeEvaluatable (" + + e.getClass() + "): " + e.getMessage()); + e.printStackTrace(); + } + } +// for ( EvaluationEvents e : registered) { +// e.beforeEvaluatable(target, context); +// } + } + + public void beforeFunction(Function target, List inputs, + EvaluationCtx context) { + for ( int i = 0 ; i < registered.size(); ++i ) { + try { + registered.get(i).beforeFunction(target, inputs, context); + } catch (Exception e) { + logger.warn("Evaluation Client (index " + i + ", class " + + registered.get(i).getClass() + " throw an excpetion " + + " when executing beforeFunction (" + + e.getClass() + "): " + e.getMessage()); + e.printStackTrace(); + } + } +// for ( EvaluationEvents e : registered) { +// e.beforeFunction(target, inputs, context); +// } + } + + public void beforePolicyTreeElement(PolicyTreeElement target, + EvaluationCtx context) { + for ( int i = 0 ; i < registered.size(); ++i ) { + try { + registered.get(i).beforePolicyTreeElement(target, context); + } catch (Exception e) { + logger.warn("Evaluation Client (index " + i + ", class " + + registered.get(i).getClass() + " throw an excpetion " + + " when executing beforePolicyTreeElement (" + + e.getClass() + "): " + e.getMessage()); + e.printStackTrace(); + } + } +// for ( EvaluationEvents e : registered) { +// e.beforePolicyTreeElement(target, context); +// } + } + + public void beforeMatch(MatchElement target, EvaluationCtx context) { + + for ( int i = 0 ; i < registered.size(); ++i ) { + try { + registered.get(i).beforeMatch(target, context); + } catch (Exception e) { + logger.warn("Evaluation Client (index " + i + ", class " + + registered.get(i).getClass() + " throw an excpetion " + + " when executing beforeMatch (" + + e.getClass() + "): " + e.getMessage()); + e.printStackTrace(); + } + } +// for ( EvaluationEvents e : registered) { +// e.beforeMatch(target, context); +// } + } + + public void beforeCombiningAlg(CombiningAlgorithm target, EvaluationCtx context, + List parameters, List inputs) { + + for ( int i = 0 ; i < registered.size(); ++i ) { + try { + registered.get(i).beforeCombiningAlg(target, context, parameters, inputs); + } catch (Exception e) { + logger.warn("Evaluation Client (index " + i + ", class " + + registered.get(i).getClass() + " throw an excpetion " + + " when executing beforeCombiningAlg (" + + e.getClass() + "): " + e.getMessage()); + e.printStackTrace(); + } + } + +// for ( EvaluationEvents e : registered) { +// e.beforeCombiningAlg(target, context, parameters, inputs); +// } + } + + + + + + /* + * AFTER events + * + */ + + + public void afterEvaluatable(Evaluatable target, EvaluationCtx context, + EvaluationResult result) { + for ( int i = registered.size() -1 ; i > -1; --i ) { + try { + registered.get(i).afterEvaluatable(target, context, result); + } catch (Exception e) { + logger.warn("Evaluation Client (index " + i + ", class " + + registered.get(i).getClass() + " throw an excpetion " + + " when executing afterEvaluatable (" + + e.getClass() + "): " + e.getMessage()); + e.printStackTrace(); + } + } +// for ( EvaluationEvents e : registered) { +// e.afterEvaluatable(target, context, result); +// } + } + + public void afterFunction(Function target, List inputs, + EvaluationCtx context, EvaluationResult result) { + for ( int i = registered.size() -1 ; i > -1; --i ) { + try { + registered.get(i).afterFunction(target, inputs, context, result); + } catch (Exception e) { + logger.warn("Evaluation Client (index " + i + ", class " + + registered.get(i).getClass() + " throw an excpetion " + + " when executing afterFunction (" + + e.getClass() + "): " + e.getMessage()); + e.printStackTrace(); + } + } +// for ( EvaluationEvents e : registered) { +// e.afterFunction(target, inputs, context, result); +// } + } + + public void afterPolicyTreeElement(PolicyTreeElement target, + EvaluationCtx context, Result result) { + + for ( int i = registered.size() -1 ; i > -1; --i ) { + try { + registered.get(i).afterPolicyTreeElement(target, context, result); + } catch (Exception e) { + logger.warn("Evaluation Client (index " + i + ", class " + + registered.get(i).getClass() + " throw an excpetion " + + " when executing afterPolicyTreeElement (" + + e.getClass() + "): " + e.getMessage()); + e.printStackTrace(); + } + } + +// for ( EvaluationEvents e : registered) { +// e.afterPolicyTreeElement(target, context, result); +// } + } + + public void afterMatch(MatchElement target, EvaluationCtx context, + MatchResult result) { + for ( int i = registered.size() -1 ; i > -1; --i ) { + try { + registered.get(i).afterMatch(target, context, result); + } catch (Exception e) { + logger.warn("Evaluation Client (index " + i + ", class " + + registered.get(i).getClass() + " throw an excpetion " + + " when executing afterMatch (" + + e.getClass() + "): " + e.getMessage()); + e.printStackTrace(); + } + } +// for ( EvaluationEvents e : registered) { +// e.afterMatch(target, context, result); +// } + } + + public void afterCombiningAlg(CombiningAlgorithm target, EvaluationCtx context, + List parameters, List inputs, + Result result) { + for ( int i = registered.size() -1 ; i > -1; --i ) { + try { + registered.get(i).afterCombiningAlg(target, context, parameters, inputs, result); + } catch (Exception e) { + logger.warn("Evaluation Client (index " + i + ", class " + + registered.get(i).getClass() + " throw an excpetion " + + " when executing afterCombiningAlg (" + + e.getClass() + "): " + e.getMessage()); + e.printStackTrace(); + } + } +// for ( EvaluationEvents e : registered) { +// e.afterCombiningAlg(target, context, parameters, inputs, result); +// } + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/EvaluationEventRegistry.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/EvaluationEventRegistry.java new file mode 100644 index 0000000..b4a5d4d --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/EvaluationEventRegistry.java @@ -0,0 +1,134 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation; + +import java.util.List; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.MatchElement; +import com.sun.xacml.MatchResult; +import com.sun.xacml.PolicyTreeElement; +import com.sun.xacml.Target; +import com.sun.xacml.combine.CombinerElement; +import com.sun.xacml.combine.CombinerParameter; +import com.sun.xacml.combine.CombiningAlgorithm; +import com.sun.xacml.cond.Evaluatable; +import com.sun.xacml.cond.EvaluationResult; +import com.sun.xacml.cond.Expression; +import com.sun.xacml.cond.Function; +import com.sun.xacml.ctx.Result; +import com.sun.xacml.debug.RuntimeInfo.ELEMENT_TYPE; + +/** + * currently empty stub class... will in some future provide a more + * or less sophisticated interface for retrieving evaluation events. + * For now, use EvaluationEventHub + * + */ +public class EvaluationEventRegistry implements EvaluationEvents { + + enum EVAL_TIME { + BEFORE, + AFTER, + BOTH + } + + + public EvaluationEventRegistry(EvaluationEventHub eventHub) { + eventHub.register(this); + } + + + + public void subscribe(EVAL_TIME time, ELEMENT_TYPE type) { + + } + + + + + public void afterEvaluatable(Evaluatable target, EvaluationCtx context, + EvaluationResult result) { + // TODO Auto-generated method stub + + } + + public void afterFunction(Function target, List inputs, + EvaluationCtx context, EvaluationResult result) { + // TODO Auto-generated method stub + + } + + public void afterPolicyTreeElement(PolicyTreeElement target, + EvaluationCtx context, Result result) { + // TODO Auto-generated method stub + + } + + public void afterTarget(Target target, EvaluationCtx context, + MatchResult result) { + // TODO Auto-generated method stub + + } + + public void beforeEvaluatable(Evaluatable target, EvaluationCtx context) { + // TODO Auto-generated method stub + + } + + public void beforeFunction(Function target, List inputs, + EvaluationCtx context) { + // TODO Auto-generated method stub + + } + + public void beforePolicyTreeElement(PolicyTreeElement target, + EvaluationCtx context) { + // TODO Auto-generated method stub + + } + + public void beforeTarget(Target target, EvaluationCtx context) { + // TODO Auto-generated method stub + + } + + public void afterCombiningAlg(CombiningAlgorithm target, EvaluationCtx context, + List parameters, List inputs, + Result result) { + // TODO Auto-generated method stub + + } + + public void beforeCombiningAlg(CombiningAlgorithm target, EvaluationCtx context, + List parameters, List inputs) { + // TODO Auto-generated method stub + + } + + public void afterMatch(MatchElement target, EvaluationCtx context, + MatchResult result) { + // TODO Auto-generated method stub + + } + + public void beforeMatch(MatchElement target, EvaluationCtx context) { + // TODO Auto-generated method stub + + } + + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/EvaluationEvents.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/EvaluationEvents.java new file mode 100644 index 0000000..6a27297 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/EvaluationEvents.java @@ -0,0 +1,88 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation; + +import java.util.List; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.MatchElement; +import com.sun.xacml.MatchResult; +import com.sun.xacml.PolicyTreeElement; +import com.sun.xacml.combine.CombinerElement; +import com.sun.xacml.combine.CombinerParameter; +import com.sun.xacml.combine.CombiningAlgorithm; +import com.sun.xacml.cond.Evaluatable; +import com.sun.xacml.cond.EvaluationResult; +import com.sun.xacml.cond.Expression; +import com.sun.xacml.cond.Function; +import com.sun.xacml.ctx.Result; + +/** + * + * This class defines the interface for retrieving events from the evaluation engine. + * Retrieved are "evaluate" and "match" Functions of objects, which implement the + * Locatable Interface. + *
      + * There are 5 types of elements for which events are retrieved, whereas all those "target" + * types implement the com.sun.xacml.finder.Locatable interface + *
        + *
      • PolicyTreeElement: which includes Policy, PolicySet, PolicyReference, Rule
      • + *
      • Evaluatable: which includes AttributeDesignator, AttributeSelector, + * AttributeValue, VariableReference, Condition, Apply
      • + *
      • Target: includes Target, TargetMatch
      • + *
      • Function:
      • includes all registered XACML functions + *
      • Obligation: TODO
      • + *
      + * + */ +public interface EvaluationEvents { + + // POLICY TREE ELEMENT + // including Policy, PolicySet, PolicyReference, Rule + + void beforePolicyTreeElement(PolicyTreeElement target, EvaluationCtx context); + + void afterPolicyTreeElement(PolicyTreeElement target, EvaluationCtx context, Result result); + + + // EVALUATEABLE + + void beforeEvaluatable(Evaluatable target, EvaluationCtx context); + + void afterEvaluatable(Evaluatable target, EvaluationCtx context, EvaluationResult result); + + + // TARGET + + void beforeMatch(MatchElement target, EvaluationCtx context); + + void afterMatch(MatchElement target, EvaluationCtx context, MatchResult result); + + + // FUNCTION + + void beforeFunction(Function target, List inputs, EvaluationCtx context); + + void afterFunction(Function target, List inputs, EvaluationCtx context, EvaluationResult result); + + // COMBINING_ALG + + void beforeCombiningAlg(CombiningAlgorithm target, EvaluationCtx context, List parameters, List inputs); + + void afterCombiningAlg(CombiningAlgorithm target, EvaluationCtx context, List parameters, List inputs, Result result); + + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/ExtToolEncoder.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/ExtToolEncoder.java new file mode 100644 index 0000000..1200594 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/ExtToolEncoder.java @@ -0,0 +1,54 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation; + +import java.io.PrintStream; +import java.net.URI; +import java.util.List; +import java.util.Map; + +import com.sun.xacml.PolicyTreeElement; +import com.sun.xacml.Rule; +import com.sun.xacml.Target; +import com.sun.xacml.TargetMatch; +import com.sun.xacml.cond.Apply; +import com.sun.xacml.cond.Condition; + +/** + * + * This interface provides some functions to print detected XACML elements to a PrintStream. + *
      + * Implementing classes may decide which notation (e.g., präfix) is most suitable for backend tools + * + */ +public interface ExtToolEncoder { + public void printCondition(Condition cond, PrintStream out); + + public void printApply(Apply apply, PrintStream out); + + public void printTargetMatches(Map>> policyMatches, + XACMLTree treeElement, PrintStream out); + + public void printTargetMatch(TargetMatch match, PrintStream out); + + public void printConditionAndMatches(Condition cond, + Map>> policyMatches, + XACMLTree treeElement, PrintStream out); + + public void printRule(Rule rule, PrintStream out, boolean printTarget); + + public void printTarget(Target target, PrintStream out); +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/ExtToolTypeEncoder.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/ExtToolTypeEncoder.java new file mode 100644 index 0000000..3cff9e2 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/ExtToolTypeEncoder.java @@ -0,0 +1,57 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation; + +import java.io.PrintStream; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.attr.AttributeDesignator; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BagAttribute; +import com.sun.xacml.combine.CombiningAlgorithm; +import com.sun.xacml.cond.Apply; +import com.sun.xacml.cond.Function; + +/** + * + * This interface is used to encode different XAML type according to the + * used backend tool + * + */ +public interface ExtToolTypeEncoder { + public String getFunctionEnc(Function func); + + public String getBagEnc(BagAttribute bag); + + public String getAttrValueEnc(AttributeValue val); + + public String getAttrDesignatorEnc(AttributeDesignator attr, AttributeValue attrVal); + + public String getDecision(int decision); + + public String getCombiningAlg(CombiningAlgorithm alg); + + public String getAND(); + + public String getOR(); + + public void printApply(Apply apply, PrintStream out); + + public void setKnownAttrStore(KnownAttrStore attrReslv); + + public String getPolicy(AbstractPolicy policy); + +} \ No newline at end of file diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/HOLEncoder.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/HOLEncoder.java new file mode 100644 index 0000000..772de66 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/HOLEncoder.java @@ -0,0 +1,445 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.net.URI; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import eu.aniketos.securebpmn.xacml.api.autho.AttributeIdentifier; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.attributes.AbstractAttribute; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.attributes.AttributeHelper; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.attr.AttributeDesignator; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BagAttribute; +import com.sun.xacml.attr.TimeAttribute; +import com.sun.xacml.combine.CombiningAlgorithm; +import com.sun.xacml.cond.Apply; +import com.sun.xacml.cond.BagFunction; +import com.sun.xacml.cond.EqualFunction; +import com.sun.xacml.cond.Expression; +import com.sun.xacml.cond.Function; +import com.sun.xacml.cond.HigherOrderFunction; +import com.sun.xacml.cond.LogicalFunction; +import com.sun.xacml.cond.TimeInRangeFunction; +import com.sun.xacml.ctx.Result; + +public class HOLEncoder implements ExtToolTypeEncoder { + + private static HOLEncoder instance = new HOLEncoder(); + private static Map functions; + + private static final String VALUE = "#"; + private static final String VAR = "$"; + + private static final String EQUAL = "=="; + //private static final String NOT_EQUAL = "<>"; + private static final String LESS_OR_EQUAL = "<="; + private static final String MORE_OR_EQUAL = ">="; + //private static final String LESS = "<"; + private static final String MORE = ">"; + + private static final String AND = "AND"; + private static final String OR = "OR"; + + //Higher order functions + private static final String ANYOFANY = "anyOfAny"; + + //bag functions + private static final String BAGSIZE = "bagsize"; + + private static final String time_max = 24*60*60*1000 + ""; + + static { + functions = new HashMap(); + //FunctionInfo(FunctionID functionID, String operator, Notation notation, boolean defaultConstr) + functions.put( + URI.create(EqualFunction.NAME_STRING_EQUAL), + new FunctionInfo(FunctionID.STRING_EQUAL, EQUAL, Notation.INFIX)); + functions.put( + URI.create(EqualFunction.NAME_ANYURI_EQUAL), + new FunctionInfo(FunctionID.ANYURI_EQUAL, EQUAL, Notation.INFIX)); + functions.put( + URI.create(EqualFunction.NAME_BOOLEAN_EQUAL), + new FunctionInfo(FunctionID.BOOLEAN_EQUAL, EQUAL, Notation.INFIX)); + functions.put( + URI.create(EqualFunction.NAME_INTEGER_EQUAL), + new FunctionInfo(FunctionID.INTEGER_EQUAL, EQUAL, Notation.INFIX)); + + functions.put( + URI.create(LogicalFunction.NAME_AND), + new FunctionInfo(FunctionID.AND, AND, Notation.INFIX)); + functions.put( + URI.create(LogicalFunction.NAME_OR), + new FunctionInfo(FunctionID.OR, OR, Notation.INFIX)); + + functions.put( + URI.create("urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"), + new FunctionInfo(FunctionID.ONE_AND_ONLY, "", Notation.PREFIX)); + functions.put( + URI.create("urn:oasis:names:tc:xacml:1.0:function:time-one-and-only"), + new FunctionInfo(FunctionID.ONE_AND_ONLY, "", Notation.PREFIX)); + functions.put( + URI.create("urn:oasis:names:tc:xacml:1.0:function:boolean-one-and-only"), + new FunctionInfo(FunctionID.ONE_AND_ONLY, "", Notation.PREFIX)); + + functions.put( + URI.create(TimeInRangeFunction.NAME), + new FunctionInfo(FunctionID.TIME_IN_RANGE, null, Notation.CUSTOM)); + + // TODO + functions.put( + URI.create(HigherOrderFunction.NAME_ANY_OF_ANY), + new FunctionInfo(FunctionID.ANY_OF_ANY, ANYOFANY, Notation.FUNCTION)); + + functions.put( + URI.create(BagFunction.FUNCTION_NS + "string" + BagFunction.NAME_BASE_BAG_SIZE), + new FunctionInfo(FunctionID.STRING_BAGSIZE, BAGSIZE, Notation.FUNCTION)); + + } + + private enum FunctionID { + STRING_EQUAL, + ANYURI_EQUAL, + BOOLEAN_EQUAL, + INTEGER_EQUAL, + AND, + OR, + TIME_IN_RANGE, + ONE_AND_ONLY, + ANY_OF_ANY, + STRING_BAGSIZE + } + + private enum Notation { + PREFIX, + INFIX, + POSTFIX, + FUNCTION, + CUSTOM + } + + private KnownAttrStore attrReslv; + + public static HOLEncoder getInstance() { + return instance; + } + + public void setKnownAttrStore(KnownAttrStore attrReslv) { + this.attrReslv = attrReslv; + } + + public String getFunctionEnc(Function func) { + if ( functions.containsKey(func.getIdentifier()) ) { + return functions.get(func.getIdentifier()).operator; + } else { + throw new RuntimeException("Function " + func.getIdentifier() + " currently not supported!"); + } + } + +// private void printInfix(Apply apply, Function func, FunctionInfo info, PrintStream out) { +// out.print("("); +// List childs = apply.getChildren(); +// if ( childs.size() != 2) { +// throw new RuntimeException("Infix notation currently only possible for 2 parameters!"); +// } +// printExpression(childs.get(0), out); +// out.print(" " + info.operator + " "); +// printExpression(childs.get(1), out); +// out.print(") "); +// } + + private void printInfix(Apply apply, Function func, FunctionInfo info, PrintStream out) { + out.print("("); + List childs = apply.getChildren(); + if ( childs.size() < 2) { + throw new RuntimeException("Infix notation currently only possible for 2 or more parameters!"); + } + printExpression(childs.get(0), out); + for ( int i = 1; i < childs.size(); ++i ) { + out.print(" " + info.operator + " "); + printExpression(childs.get(i), out); + } + out.print(") "); + } + + private void printPrefix(Apply apply, Function func, FunctionInfo info, PrintStream out) { + out.print(" " + info.operator + " ("); + for ( Expression child : apply.getChildren() ) { + printExpression(child, out); + } + out.print(")"); + } + + /** + * prints functions which are part of an apply element + * @param apply + * @param func + * @param info + * @param out + */ + private void printFunction(Apply apply, Function func, FunctionInfo info, PrintStream out) { + + out.print(" (" + info.operator + " ( "); + boolean first = true; + for ( Expression child : apply.getChildren() ) { + if ( first ) { + first = false; + } else { + out.print(", "); + } + printExpression(child, out); + } + out.print(")"); + } + + /** + * prints functions which are "standaline", i.e., there is a element in the policy + *
      + * mainly/only (? - TODO) used for higher order functions? + * @param func + * @param out + */ + private void printFunction(Function func, PrintStream out) { + FunctionInfo info = getFunctionInfo(func); + + out.print(info.operator); + } + + private void printExpression(Expression expression, PrintStream out) { + if ( expression instanceof BagAttribute ) { + out.print(getBagEnc((BagAttribute)expression)); + } else if ( expression instanceof AttributeValue ) { + out.print(getAttrValueEnc( ( AttributeValue) expression)); + } else if ( expression instanceof AttributeDesignator ) { + AttributeDesignator attr = (AttributeDesignator) expression; + AttributeIdentifier attrId = AttributeHelper.getAttributeIdentifier(attr); + AttributeValue attrValRes = attrReslv.getAttributeValue(attrId); + out.print(getAttrDesignatorEnc(attr, attrValRes)); + } else if ( expression instanceof Apply ) { + printApply ( (Apply) expression, out); + } else if ( expression instanceof Function ) { + printFunction ( (Function)expression, out); + } + else { + throw new RuntimeException("Unexpected element: " + expression); + } + } + + + + public void printApply(Apply apply, PrintStream out) { + Function func = apply.getFunction(); + FunctionInfo info = getFunctionInfo(func); + + switch ( info.notation ) { + case INFIX: + printInfix(apply, func, info, out); + break; + case PREFIX: + printPrefix(apply, func, info, out); + break; + case POSTFIX: + throw new RuntimeException("TODO: currently not implemented"); + case FUNCTION: + printFunction(apply, func, info, out); + break; + case CUSTOM: + switch ( info.functionID ) { + case TIME_IN_RANGE: + printTimeInRange(apply, func, info, out); + break; + default: + throw new RuntimeException("For function " + func.getIdentifier() + " no Custom notation is available"); + } + break; + default: + throw new RuntimeException("Notation " + info.notation + " currently not supported"); + } + } + + + public String getBagEnc(BagAttribute bag) { + if ( bag.size() != 1) { + throw new RuntimeException("BagAttributes with size != 1 currently not supported!"); + } + return getAttrValueEnc( bag.iterator().next()); + } + + public String getAttrValueEnc(AttributeValue val) { + if ( val instanceof BagAttribute) { + return getBagEnc( (BagAttribute) val); + } else if ( val instanceof TimeAttribute ) { + return VALUE + ((TimeAttribute)val).getMilliseconds(); + } else { + return VALUE + val.encode(); + } + } + + public String getAttrDesignatorEnc(AttributeDesignator attr, AttributeValue attrVal) { + if (attrVal != null && ! AttributeHelper.isAbstractAttribute(attrVal) ) { + return getAttrValueEnc(attrVal); + } else { + return VAR + attr.getId(); + } + } + + + public String getAND() { + return AND; + } + + public String getOR() { + // TODO Auto-generated method stub + return OR; + } + + public String getDecision(int decision) { + switch ( decision) { + case Result.DECISION_DENY: + return "DENY"; + case Result.DECISION_PERMIT: + return "PERMIT"; + case Result.DECISION_INDETERMINATE: + return "INDETERMINATE"; + case Result.DECISION_NOT_APPLICABLE: + return "NOT_APPLICABLE"; + } + throw new RuntimeException("Currently not supported decision: " + decision); + } + + public String getCombiningAlg(CombiningAlgorithm alg) { + String name = alg.getIdentifier().toString(); + return name.substring(name.lastIndexOf(":")+1); + } + + + private FunctionInfo getFunctionInfo(Function func) { + FunctionInfo info = functions.get(func.getIdentifier()); + if ( info == null ) { + throw new RuntimeException("Function " + func.getIdentifier() + " currently not supported!"); + } + return info; + } + + + private static class FunctionInfo { + FunctionID functionID; + String operator; + Notation notation; + + FunctionInfo(FunctionID functionID, String operator, Notation notation) { + this.functionID = functionID; + this.operator = operator; + this.notation = notation; + } + } + + /* + * CUSTOM FUNCTION + */ + + /** + * urn:oasis:names:tc:xacml:2.0:function:time-in-range Function: + * + * three values: a, b, c: true, if a is within b and c
      + * two cases: + *
    • + *
        b <= c: a >= b AND a <= c
      + *
        b > c: ( a >= b AND a <= 24h) OR ( a >= 0h AND a <= c )
      + *
    • + * if either b or c are variables, then
      + * (b<=c AND a >= b AND a <= c ) OR ( b>=c AND (( a >= b AND a <= 24h) OR ( a >= 0h AND a <= c )) ) + */ + private void printTimeInRange(Apply apply, Function func, FunctionInfo info, PrintStream out) { + + + List childs = apply.getChildren(); + if ( childs.size() != 3) { + throw new RuntimeException("TimeInRange function only possible for 3 parameters!"); + } + + String[] vars = new String[3]; + for ( int i = 0; i < 3; ++i ) { + if ( childs.get(i) instanceof AttributeValue ) { + vars[i] = getAttrValueEnc( (AttributeValue) childs.get(i)); + } else if ( childs.get(i) instanceof AttributeDesignator ) { + AttributeDesignator attrDsgn = (AttributeDesignator) childs.get(i); + AttributeValue attrVal = attrReslv.getAttributeValue( + AttributeHelper.getAttributeIdentifier(attrDsgn)); + if (attrVal != null && ! (attrVal instanceof AbstractAttribute )) { + vars[i] = getAttrValueEnc(attrVal); + } else { + vars[i] = attrDsgn.getId().toString(); + } + } else if ( childs.get(i) instanceof Apply ) { + ByteArrayOutputStream bOS = new ByteArrayOutputStream(); + PrintStream out2 = new PrintStream(bOS); + printApply( (Apply)childs.get(i), out2); + out2.flush(); + vars[i] = bOS.toString(); + } else { + throw new RuntimeException("Unrecognised type for param " + i + " for TimeInRange function: " + childs.get(i).getClass()); + } + } + + if ( vars[1].startsWith(VAR) || vars[2].startsWith(VAR) ) { + //b or c are variables - case distinction b < c or b > c + out.print("( ( " + vars[1] + LESS_OR_EQUAL + vars[2] + " " + AND + " " + getBsC(vars) + " ) " + + OR + " ( " + vars[1] + MORE + vars[2] + " " + AND + " " + getBsC(vars) + " ) )"); + } else { + int b = Integer.parseInt(vars[1].substring(1)); + int c = Integer.parseInt(vars[2].substring(1)); + if ( b <= c ) { + out.print(getBsC(vars)); + } else { + out.print(getBgC(vars)); + } + } + } + /** + * helper function for printTimeInRange - when second value smaller equal third value + * @param vars + * @return + */ + private String getBsC(String[] vars) { + // b < c: a >= b AND a <= c + return "( " + vars[0] + MORE_OR_EQUAL + vars[1] + " " + AND + " " + vars[0] + LESS_OR_EQUAL + vars[2] + ")"; + } + + /** + * helper function for printTimeInRange - when second value larger third value + * @param vars + * @return + */ + private String getBgC(String[] vars) { + // b > c: ( a >= b AND a <= 24h) + // OR ( a >= 0h AND a <= c ) + return "( ( " + vars[0] + MORE_OR_EQUAL + vars[1] + " " + AND + " " + vars[0] + LESS_OR_EQUAL + time_max + ") " + + OR + " ( " + vars[0] + MORE_OR_EQUAL + "0 " + AND + " " + vars[0] + LESS_OR_EQUAL + vars[2] + ") )"; + } + + public String getPolicy(AbstractPolicy policy) { + return getCombiningAlg(policy.getCombiningAlg()); + } + + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/InfoTree.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/InfoTree.java new file mode 100644 index 0000000..ce14ac4 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/InfoTree.java @@ -0,0 +1,144 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation; + +import java.util.List; +import java.util.Vector; + +import org.apache.log4j.Logger; + +/** + * + * This class allows to create a tree of objects (especially XACML elements) + */ +public class InfoTree { + private InfoTree father; + + private List> childs; + + private T element; + + private I info; + + private InfoTree cur_pointer = this; + + private static Logger logger = Logger.getLogger(InfoTree.class); + + public InfoTree () { + + } + + public InfoTree(T element, I info) { + this.element = element; + this.info = info; + } + + public void addChild(T element, I info) { + if ( cur_pointer == this ) { + if ( childs == null ) { + childs = new Vector>(); + } + InfoTree child = new InfoTree(element, info); + child.father = this; + //child.element = element; + childs.add(child); + cur_pointer = child; + } else { + cur_pointer.addChild(element, info); + } + } + + public boolean close(T element) { + if ( cur_pointer == this ) { + if ( this.element == null ) { + System.out.println("LAST ELEMENT???"); + + } + if ( this.element != null && this.element != element ) { + logger.warn("False cur pointer! " + this.element.toString() + " vs. " + element.toString()); + } + return true; + } else { + if (cur_pointer.close(element)) { + cur_pointer = this; + } + return false; + } + } + + public List> getChilds() { + return childs; + } + + public void clear() { + element = null; + cur_pointer = this; + if (childs != null) { + childs.clear(); + } + } + + public boolean isEmpty() { + if ( element == null && (childs == null || childs.size() == 0 )) { + return true; + } else { + return false; + } + } + + public boolean hasChilds() { + if ( childs != null && childs.size() > 0 ) { + return true; + } else { + return false; + } + } + + public InfoTree getCurrent() { + if (cur_pointer == this ) { + return this; + } else { + return cur_pointer.getCurrent(); + } + } + + public T getElement() { + return this.element; + } + + public I getInfo() { + return this.info; + } + + public InfoTree getFather() { + return father; + } + + /** + * returns true, if the provided treeElement is a superior node of "this" + * @param treeElement + * @return + */ + public boolean isFather(T treeElement) { + if ( this.getFather() == null || this.getFather().element == null ) { + return false; + } else if ( this.getFather().element == element ) { + return true; + } else { + return this.getFather().isFather(treeElement); + } + } +} \ No newline at end of file diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/KnownAttrStore.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/KnownAttrStore.java new file mode 100644 index 0000000..969b855 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/KnownAttrStore.java @@ -0,0 +1,40 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation; + +import eu.aniketos.securebpmn.xacml.api.autho.AttributeIdentifier; + +import com.sun.xacml.attr.AttributeValue; + +/** + * This interface provides a function which allows to retreive + * attributes which are "known" at evaluation time, i.e., where + * a value can be provided for a given AttributeIdentifier. + * + * + */ +public interface KnownAttrStore { + + /** + * returns the given attributeValue or null, if no value is available + * @param attrId + * @return + */ + AttributeValue getAttributeValue(AttributeIdentifier attrId); + + void setAttributeValue(AttributeIdentifier attrId, AttributeValue attr); + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/MissingAttrCapture.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/MissingAttrCapture.java new file mode 100644 index 0000000..dc16b11 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/MissingAttrCapture.java @@ -0,0 +1,205 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation; + +import java.util.List; + +import org.apache.log4j.Logger; + +import eu.aniketos.securebpmn.xacml.api.autho.AttributeIdentifier; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.EvalInfo.MissingAttrType; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.attributes.AttributeHelper; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.MatchElement; +import com.sun.xacml.MatchResult; +import com.sun.xacml.PolicyTreeElement; +import com.sun.xacml.Rule; +import com.sun.xacml.Target; +import com.sun.xacml.attr.AttributeDesignator; +import com.sun.xacml.combine.CombinerElement; +import com.sun.xacml.combine.CombinerParameter; +import com.sun.xacml.combine.CombiningAlgorithm; +import com.sun.xacml.cond.Condition; +import com.sun.xacml.cond.Evaluatable; +import com.sun.xacml.cond.EvaluationResult; +import com.sun.xacml.cond.Expression; +import com.sun.xacml.cond.Function; +import com.sun.xacml.ctx.Result; +import com.sun.xacml.debug.RuntimeInfo; + +/** + * + *
        + *
      • retrieve events from the evaluation
      • + *
      • keep track of all successful resovled attributes
      • + *
      • keep track of missing attributes
      • + *
      + * + */ +public class MissingAttrCapture implements EvaluationEvents { + + private EvalInfoProvider infoProv; + private KnownAttrStore knownAttributes; + + private static final Logger logger = Logger.getLogger(MissingAttrCapture.class); + + + public MissingAttrCapture(EvalInfoProvider infoProv) { + this.knownAttributes = new RuntimeAttrCollector(); + this.infoProv = infoProv; + } + + public MissingAttrCapture(EvalInfoProvider infoProv, KnownAttrStore knownAttributes) { + this.knownAttributes = knownAttributes; + this.infoProv = infoProv; + } + + public KnownAttrStore getKnownAttributes() { + return knownAttributes; + } + +// public MissingAttrCapture() { +// knownAttributes = new HashMap(); +// } +// +// public MissingAttrCapture(Map knownAttributes) { +// this.knownAttributes = knownAttributes; +// } + + + + + public void afterEvaluatable(Evaluatable target, EvaluationCtx context, + EvaluationResult result) { + if ( target instanceof AttributeDesignator ) { + AttributeDesignator attrDsgn = ( AttributeDesignator ) target; + // if this attribute is not known, mark + if (AttributeHelper.containsAbstractValue(result) ) { + + InfoTree current = infoProv.getCurrentTreeElem(); + PolicyTreeElement father = AttributeHelper.getPolicyTreeElement(attrDsgn.getRuntimeInfo()); + // may be removed later on + if ( father != current.getElement()) { + logger.warn("Current element from tree and father PolicyTreeElement do not match! " + + father.toString() + " (" + father.getId() + ") != " + + current.getElement().toString() + " (" + current.getElement().getId() + ")"); + } + // + if ( ! (father instanceof Rule) ) { + logger.error("Currently, only attributes within rules may be missing! " + + "TargetMatches of Policies and PolicySets are not supported!"); + throw new RuntimeException("Currently, only attributes within rules may be missing!"); + } + //TODO set if condition or target match + current.getInfo().setMissingAttribtue(getFatherType(attrDsgn.getRuntimeInfo())); + } + // otherwise, save resolved value + else { + AttributeIdentifier attrId = AttributeHelper.getAttributeIdentifier(attrDsgn); + knownAttributes.setAttributeValue(attrId, result.getAttributeValue()); + } + } + } + + public void afterPolicyTreeElement(PolicyTreeElement target, + EvaluationCtx context, Result result) { + //InfoTree current = tree.getCurrent(); + InfoTree current = infoProv.getCurrentTreeElem(); + //"tell" the upper element (if available) that sub element is missing some attribute + if ( current.getInfo().isMissingAttribute() && current.getFather().getInfo() != null ) { + current.getFather().getInfo().setMissingAttribtue(MissingAttrType.subElement); + } + current.getInfo().setResult(result); + //tree.close(target); + //infoProv.closeElement(target); // moved to evalInfoProvider + } + + private MissingAttrType getFatherType(RuntimeInfo runtimeInfo) { + Object xacml = runtimeInfo.getXACMLObject(); + if ( xacml != null ) { + if ( xacml instanceof Target ) { + return MissingAttrType.Target; + } else if ( xacml instanceof Condition ) { + return MissingAttrType.Condition; + } else { + return getFatherType(runtimeInfo.getCalledFrom()); + } + } else { + throw new RuntimeException("Could not determine calledFrom object from " + runtimeInfo); + } + } + +// private static int foo = 0; +// +// private MissingAttrType getFatherType(Locatable l) { +// +// Locatable l2 = (Locatable) l.getRuntimeInfo().getCallFromXACML(); +// if ( l2 != null ) { +// if ( l2 instanceof Target ) { +// foo =0; +// return MissingAttrType.Target; +// } else if ( l2 instanceof Condition ) { +// foo = 0; +// return MissingAttrType.Condition; +// } else { +// if ( ++foo > 15 ) { +// foo = 0; +// throw new RuntimeException("xxxx"); +// } +// return getFatherType(l2); +// } +// } else { +// throw new RuntimeException("Could not determine calledFrom object from " + l.getClass()); +// } +// } + + // + + public void beforePolicyTreeElement(PolicyTreeElement target, + EvaluationCtx context) { + //tree.addChild(target, new EvalInfo()); + //infoProv.hitElement(target); + } + + public void afterCombiningAlg(CombiningAlgorithm target, + EvaluationCtx context, List parameters, + List inputs, Result result) {} + public void afterFunction(Function target, List inputs, + EvaluationCtx context, EvaluationResult result) {} + public void afterMatch(MatchElement target, EvaluationCtx context, + MatchResult result) {} + + public void beforeCombiningAlg(CombiningAlgorithm target, + EvaluationCtx context, List parameters, + List inputs) {} + public void beforeEvaluatable(Evaluatable target, EvaluationCtx context) {} + public void beforeFunction(Function target, List inputs, + EvaluationCtx context) {} + public void beforeMatch(MatchElement target, EvaluationCtx context) {} + +// if ( target instanceof Rule ) { +// // print match and/or condition (depends, both if not knowing) + +// } else { +// // remove later +// if ( ! ( target instanceof Policy || target instanceof PolicySet)) { +// throw new RuntimeException(); +// } +// // +// } + + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/PraefixEncoder.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/PraefixEncoder.java new file mode 100644 index 0000000..e032cef --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/PraefixEncoder.java @@ -0,0 +1,219 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation; + +import java.io.PrintStream; +import java.net.URI; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; + +import eu.aniketos.securebpmn.xacml.api.autho.AttributeIdentifier; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.attributes.AttributeHelper; + +import com.sun.xacml.PolicyTreeElement; +import com.sun.xacml.Rule; +import com.sun.xacml.Target; +import com.sun.xacml.TargetMatch; +import com.sun.xacml.TargetMatchGroup; +import com.sun.xacml.TargetSection; +import com.sun.xacml.attr.AttributeDesignator; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.cond.Apply; +import com.sun.xacml.cond.Condition; +import com.sun.xacml.cond.Evaluatable; +import com.sun.xacml.cond.Expression; +import com.sun.xacml.cond.Function; + +public class PraefixEncoder implements ExtToolEncoder { + + private ExtToolTypeEncoder typeEnc; + private KnownAttrStore attrResolver; + + private static Logger logger = Logger.getLogger(PraefixEncoder.class); + + public PraefixEncoder(ExtToolTypeEncoder typeEnc, KnownAttrStore attrResolver) { + this.typeEnc = typeEnc; + this.attrResolver = attrResolver; + } + + + public void printApply(Apply apply, PrintStream out) { + typeEnc.printApply(apply, out); + } + + public void printRule(Rule rule, PrintStream out, boolean printTarget) { + boolean enclosingAnd = printTarget && rule.getCondition() != null; + if (enclosingAnd ) { + out.print(typeEnc.getAND() + "("); + } + + + if ( printTarget ) { + printTarget(rule.getTarget(), out); + } + + if ( rule.getCondition() != null ) { + if ( printTarget ) { + out.print(typeEnc.getAND() + "("); + } + printCondition(rule.getCondition(), out); + if ( printTarget ) { + out.print(")"); + } + } + if (enclosingAnd ) { + out.print(")"); + } + } + + + public void printCondition(Condition cond, PrintStream out) { + Expression expr = cond.getExpression(); + if ( ! ( expr instanceof Apply )) { + throw new RuntimeException("Currently expression for Conditions not being an Apply are not support"); + } + printApply( (Apply) expr, out); + } + + public void printTarget(Target target, PrintStream out) { + if ( target.getTargetSections().size() > 0 ) { + if ( target.getTargetSections().size() > 1 ) { + out.print(typeEnc.getAND() + "("); + } + for ( TargetSection section : target.getTargetSections() ) { + printTargetSection(section, out); + } + if ( target.getTargetSections().size() > 1 ) { + out.print(") "); + } + } + } + + private void printTargetSection(TargetSection section, PrintStream out) { + if ( section.getMatchGroups().size() > 0 ) { + if ( section.getMatchGroups().size() > 1 ) { + out.print(typeEnc.getOR() + "("); + } + for ( TargetMatchGroup group : section.getMatchGroups()) { + printTargetGroup(group, out); + } + if ( section.getMatchGroups().size() > 1 ) { + out.print(") "); + } + } + + } + + private void printTargetGroup(TargetMatchGroup group, PrintStream out) { + if ( group.getMatches().size() > 0 ) { + if ( group.getMatches().size() > 1 ) { + out.print(typeEnc.getAND() + "("); + } + for ( TargetMatch match : group.getMatches()) { + printTargetMatch(match, out); + } + if ( group.getMatches().size() > 1 ) { + out.print(") "); + } + } + } + + + /** + * recursively print AND combined target matches of all enclosing PolicyTreeElements + * @param treeElement + * @param out + */ + public void printTargetMatches(Map>> policyMatches, + XACMLTree treeElement, PrintStream out) { + printTargetMatches(policyMatches, treeElement, out, true); + } + + private boolean printTargetMatches(Map>> policyMatches, + XACMLTree treeElement, PrintStream out, boolean isFirst) { + // print in format + // AND (treeElement.category1.match OR rule.category1.match) AND (treeElement.category2.match OR ...) + + if (treeElement.getFather() != null && treeElement.getFather().getElement() != null) { + isFirst = printTargetMatches(policyMatches, treeElement.getFather(), out, isFirst); + } + + PolicyTreeElement element = treeElement.getElement(); + Map> matches = policyMatches.get(element); + + for ( URI category : matches.keySet()) { + if ( isFirst ) { + isFirst = false; + } else { + out.print(typeEnc.getAND()); + } + out.print(" ( "); + List matches2 = matches.get(category); + for ( int i = 0; i < matches2.size(); ++i ) { + if ( i > 0 ) { + out.print(" "+ typeEnc.getOR() + " "); + } + printTargetMatch(matches2.get(i), out); + } + out.print(" ) "); + } + return isFirst; + } + + /** + * print target match + * @param match + * @param out + */ + public void printTargetMatch(TargetMatch match, PrintStream out) { + AttributeValue attrVal = match.getMatchValue(); + Function func = match.getMatchFunction(); + Evaluatable eval = match.getMatchEvaluatable(); + AttributeDesignator attr = null; + if ( ! (eval instanceof AttributeDesignator) ) { + logger.error("Currently, only AttributeDesignators are supported for TargetMatches"); + throw new RuntimeException("Currently, only AttributeDesignators are supported for TargetMatches"); + } else { + attr = (AttributeDesignator) eval; + } + AttributeIdentifier attrId = AttributeHelper.getAttributeIdentifier(attr); + AttributeValue attrValRes = attrResolver.getAttributeValue(attrId); + + out.print(typeEnc.getFunctionEnc(func) + + "(" + typeEnc.getAttrValueEnc(attrVal) + " " + + typeEnc.getAttrDesignatorEnc(attr, attrValRes) + ") "); + } + + + public void printConditionAndMatches(Condition cond, + Map>> policyMatches, + XACMLTree treeElement, PrintStream out) { + + boolean isFirst = printTargetMatches(policyMatches, treeElement, out, true); + + if ( ! isFirst ) { + out.print(typeEnc.getAND() + "( "); + } + + printCondition(cond, out); + + if ( ! isFirst ) { + out.print(")"); + } + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/PrettyPrinter.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/PrettyPrinter.java new file mode 100644 index 0000000..0d2fa8a --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/PrettyPrinter.java @@ -0,0 +1,135 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation; + +import java.util.List; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.MatchElement; +import com.sun.xacml.MatchResult; +import com.sun.xacml.PolicyTreeElement; +import com.sun.xacml.combine.CombinerElement; +import com.sun.xacml.combine.CombinerParameter; +import com.sun.xacml.combine.CombiningAlgorithm; +import com.sun.xacml.cond.Apply; +import com.sun.xacml.cond.Evaluatable; +import com.sun.xacml.cond.EvaluationResult; +import com.sun.xacml.cond.Expression; +import com.sun.xacml.cond.Function; +import com.sun.xacml.ctx.Result; +import com.sun.xacml.debug.Locatable; +import com.sun.xacml.debug.RuntimeInfo; + +/** + * + * Simple class which receives all events from the EvaluationEventHub + * and prints them in a readable form. + * + */ +public class PrettyPrinter implements EvaluationEvents { + + private int depth = 0; + + private static String[] foo; + + private static final String ret = "ret: ", call = "call: "; + + + static { + foo = new String[64]; + + foo[0] = ""; + for ( int i = 1; i < 64 ; ++i) { + foo[i] = foo[i-1] + " "; + } + } + + public void reset() { + depth = 0; + } + + public void afterEvaluatable(Evaluatable target, EvaluationCtx context, + EvaluationResult result) { + --depth; + RuntimeInfo src = target.getRuntimeInfo(); + System.out.println(foo[depth] + ret + target.getClass().getSimpleName() + (src != null ? src.getLocationMsgRuntime() : " (no src)")); + } + + public void afterFunction(Function target, List inputs, + EvaluationCtx context, EvaluationResult result) { + --depth; + RuntimeInfo src = target.getRuntimeInfo(); + System.out.println(foo[depth] + ret + target.getClass().getSimpleName() + (src != null ? src.getLocationMsgRuntime() : " (no src)")); + } + + public void afterPolicyTreeElement(PolicyTreeElement target, + EvaluationCtx context, Result result) { + --depth; + RuntimeInfo src = ((Locatable) target).getRuntimeInfo(); + System.out.println(foo[depth] + ret + target.getClass().getSimpleName() + (src != null ? src.getLocationMsgRuntime() : " (no src)")); + } + + public void afterMatch(MatchElement target, EvaluationCtx context, + MatchResult result) { + --depth; + RuntimeInfo src = ((Locatable) target).getRuntimeInfo(); + System.out.println(foo[depth] + ret + target.getClass().getSimpleName() + (src != null ? src.getLocationMsgRuntime() : " (no src)")); + } + + public void beforeEvaluatable(Evaluatable target, EvaluationCtx context) { + RuntimeInfo src = target.getRuntimeInfo(); + System.out.println(foo[depth] + call + target.getClass().getSimpleName() + " " + + ( target instanceof Apply ? ((Apply)target).getFunction().getIdentifier() : target.getType() )+ + (src != null ? src.getLocationMsgRuntime() : " (no src)")); + ++depth; + } + + public void beforeFunction(Function target, List inputs, + EvaluationCtx context) { + RuntimeInfo src = target.getRuntimeInfo(); + System.out.println(foo[depth] + call + target.getClass().getSimpleName() + " " + target.getIdentifier() + (src != null ? src.getLocationMsgRuntime() : " (no src)")); + ++depth; + } + + public void beforePolicyTreeElement(PolicyTreeElement target, + EvaluationCtx context) { + RuntimeInfo src = ((Locatable) target).getRuntimeInfo(); + System.out.println(foo[depth] + call + target.getClass().getSimpleName() + " " + target.getId() + (src != null ? src.getLocationMsgRuntime() : " (no src)")); + ++depth; + } + + public void beforeMatch(MatchElement target, EvaluationCtx context) { + RuntimeInfo src = ((Locatable) target).getRuntimeInfo(); + System.out.println(foo[depth] + call + target.getClass().getSimpleName() + (src != null ? src.getLocationMsgRuntime() : " (no src)")); + ++depth; + } + + public void afterCombiningAlg(CombiningAlgorithm target, EvaluationCtx context, + List parameters, List inputs, + Result result) { + --depth; + RuntimeInfo src = target.getRuntimeInfo(); + System.out.println(foo[depth] + ret + target.getClass().getSimpleName() + (src != null ? src.getLocationMsgRuntime() : " (no src)")); + } + + public void beforeCombiningAlg(CombiningAlgorithm target, EvaluationCtx context, + List parameters, List inputs) { + RuntimeInfo src = target.getRuntimeInfo(); + System.out.println(foo[depth] + call + target.getClass().getSimpleName() + (src != null ? src.getLocationMsgRuntime() : " (no src)")); + ++depth; + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/ReportGenerator.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/ReportGenerator.java new file mode 100644 index 0000000..3525ecf --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/ReportGenerator.java @@ -0,0 +1,117 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import org.apache.log4j.Logger; + +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.EvalInfo.MissingAttrType; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.PolicyTreeElement; +import com.sun.xacml.Rule; +import com.sun.xacml.ctx.Result; + +public class ReportGenerator { + + private static final Logger logger = Logger.getLogger(ReportGenerator.class); + + private ExtToolTypeEncoder typeEnc = HOLEncoder.getInstance(); + private InfoTree tree; + //private KnownAttrStore attrProv; + private ExtToolEncoder enc; + + private int depth; + private static String[] spaces; + static { + spaces = new String[16]; + spaces[0] = ""; + for (int i = 1; i < 16; ++i ) { + spaces[i] = spaces[i-1] + " "; + } + } + + public ReportGenerator(KnownAttrStore attrProv, InfoTree tree) { + typeEnc.setKnownAttrStore(attrProv); + //this.attrProv = attrProv; + this.tree = tree; + this.enc = new PraefixEncoder(typeEnc, attrProv); + } + + public String reportMissingAttr() { + + ByteArrayOutputStream bOS = new ByteArrayOutputStream(); + PrintStream out = new PrintStream(bOS); + + depth = 0; + //InfoTree tree = infoProv.getTree(); + if ( tree.getChilds() != null ) { + for ( InfoTree child : tree.getChilds() ) { + report(child, enc, out); + } + } + out.flush(); + return bOS.toString(); + } + + private void report(InfoTree tree, ExtToolEncoder enc, PrintStream out) { + PolicyTreeElement elem = tree.getElement(); + EvalInfo info = tree.getInfo(); + if ( info.isMissingAttribute() ) { + // for rules, we print the condition (with the missing attribute) + if ( elem instanceof Rule ) { + Rule rule = (Rule) elem; + out.print(spaces[depth]); + enc.printRule(rule, out, info.isMissingAttribute(MissingAttrType.Target)); + out.println(" -> " + typeEnc.getDecision(rule.getEffect())); + } + // for policies, we print the used comibing alg + all sub elements + else if ( elem instanceof AbstractPolicy ) { + AbstractPolicy policy = (AbstractPolicy) elem; + out.println(spaces[depth] + typeEnc.getCombiningAlg(policy.getCombiningAlg()) + " ("); + + ++depth; + for ( InfoTree child : tree.getChilds() ) { + report(child, enc, out); + } + --depth; + out.println(spaces[depth] + ")"); + } + else { + logger.warn("Unkown PolicyTreeElement: " + elem.getClass()); + } + } else { + // did this element match? + if ( isMatch(info.getResult()) ) { + out.println(spaces[depth] + "true -> " + typeEnc.getDecision(info.getResult().getDecision())); + } else { + out.println(spaces[depth] + typeEnc.getDecision(info.getResult().getDecision())); + } + //if no attribute was missing, we take the given decision + } + } + + private boolean isMatch(Result result) { + if ( result.getDecision() == Result.DECISION_PERMIT || result.getDecision() == Result.DECISION_DENY) { + return true; + } else { + return false; + } + + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/RuntimeAttrCollector.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/RuntimeAttrCollector.java new file mode 100644 index 0000000..1e15d5a --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/RuntimeAttrCollector.java @@ -0,0 +1,53 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation; + +import java.util.HashMap; +import java.util.Map; + +import eu.aniketos.securebpmn.xacml.api.autho.AttributeIdentifier; + +import com.sun.xacml.attr.AttributeValue; + +/** + * this is a simple implementation of the KnownAttrProvider interface + * which does not require a backend to resolve known attributes but collects + * them at runtime. This is only intended for testing and development + *
      + */ +public class RuntimeAttrCollector implements KnownAttrStore { + + /** + * saves all attributes which are are "known", i.e., where a fix value for + * this evaluation is given. + */ + private Map knownAttributes = + new HashMap(); + + public AttributeValue getAttributeValue(AttributeIdentifier attrId) { + return knownAttributes.get(attrId); + } + + public void setAttributeValue(AttributeIdentifier attrId, + AttributeValue attr) { + if ( knownAttributes.containsKey(attrId)) { + // TODO make check? compare + } else { + knownAttributes.put(attrId, attr); + } + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/XACMLTree.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/XACMLTree.java new file mode 100644 index 0000000..be145cf --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/XACMLTree.java @@ -0,0 +1,134 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation; + +import java.util.List; +import java.util.Vector; + +import org.apache.log4j.Logger; + +/** + * + * This class allows to create a tree of objects (especially XACML elements) + * + */ +public class XACMLTree { + private XACMLTree father; + + private List> childs; + + private T element; + + private XACMLTree cur_pointer = this; + + private static Logger logger = Logger.getLogger(XACMLTree.class); + + public XACMLTree() { + + } + + public XACMLTree(T element) { + this.element = element; + } + + public void addChild(T element) { + if ( cur_pointer == this ) { + if ( childs == null ) { + childs = new Vector>(); + } + XACMLTree child = new XACMLTree(element); + child.father = this; + //child.element = element; + childs.add(child); + cur_pointer = child; + } else { + cur_pointer.addChild(element); + } + } + + public boolean close(T element) { + if ( cur_pointer == this ) { + if ( this.element != element ) { + logger.warn("False cur pointer! " + this.element.toString() + " vs. " + element.toString()); + } + return true; + } else { + if (cur_pointer.close(element)) { + cur_pointer = this; + } + return false; + } + } + + public List> getChilds() { + return childs; + } + + public void clear() { + element = null; + cur_pointer = this; + if (childs != null) { + childs.clear(); + } + } + + public boolean isEmpty() { + if ( element == null && (childs == null || childs.size() == 0 )) { + return true; + } else { + return false; + } + } + + public boolean hasChilds() { + if ( childs != null && childs.size() > 0 ) { + return true; + } else { + return false; + } + } + + public XACMLTree getCurrent() { + if (cur_pointer == this ) { + return this; + } else { + return cur_pointer.getCurrent(); + } + } + + public T getElement() { + return this.element; + } + + public XACMLTree getFather() { + return father; + } + + /** + * returns true, if the provided treeElement is a superior node of "this" + * @param treeElement + * @return + */ + public boolean isFather(T treeElement) { + if ( this.getFather() == null || this.getFather().element == null ) { + return false; + } else if ( this.getFather().element == element ) { + return true; + } else { + return this.getFather().isFather(treeElement); + } + } +} \ No newline at end of file diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/attributes/AbstractAttribute.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/attributes/AbstractAttribute.java new file mode 100644 index 0000000..b5c3645 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/attributes/AbstractAttribute.java @@ -0,0 +1,26 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.attributes; + +/** + * + * Used to identify in the system injected abstract values. + *
      + * Used by AttributeHelper class to create and identify abstract values + */ +public interface AbstractAttribute { + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/attributes/AbstractAttributeResolver.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/attributes/AbstractAttributeResolver.java new file mode 100644 index 0000000..dfb4d50 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/attributes/AbstractAttributeResolver.java @@ -0,0 +1,65 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.attributes; + +import org.apache.log4j.Logger; + +import eu.aniketos.securebpmn.xacml.api.autho.AttributeIdentifier; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.PolicyTreeElement; +import com.sun.xacml.Rule; +import com.sun.xacml.attr.BagAttribute; +import com.sun.xacml.debug.RuntimeInfo; + + + +/** + * This class can be used to register at XXX and will return abstract + * values of attributes, i.e., enforcing an abstract evaluation of the policy. + *
      + * NOTE This class will return a value if the missing attributes is part + * of a rule, i.e., if the attribute is not part of a match from a policy or policyset. + * + * For attributes within rules, it will always return an (abstract) value. + * If an attribute should be treated as missing, another attribute resolver has to return an + * empty bag before! + * + * + */ +public class AbstractAttributeResolver implements AnalysisAttributeResolver { + + private static Logger logger = Logger.getLogger(AbstractAttributeResolver.class); + + public BagAttribute resolveAttribute(AttributeIdentifier attrId, + EvaluationCtx context, RuntimeInfo runtimeInfo) { + PolicyTreeElement father = AttributeHelper.getPolicyTreeElement(runtimeInfo); + if ( ! (father instanceof Rule) && logger.isDebugEnabled() ) { + logger.debug("Currently, only attributes within rules may be missing! " + + "TargetMatches of Policies and PolicySets are not supported!"); + return null; + } + if (logger.isDebugEnabled()) { + logger.debug("return abstract value for attribute " + + attrId.getAttributeId() + " type " + attrId.getAttributeType()); + } + + + return AttributeHelper.createSingleBag( + AttributeHelper.getAbstractAttribute(attrId.getAttributeType())); + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/attributes/AnalysisAttributeResolver.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/attributes/AnalysisAttributeResolver.java new file mode 100644 index 0000000..d583a67 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/attributes/AnalysisAttributeResolver.java @@ -0,0 +1,50 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.attributes; + + +import eu.aniketos.securebpmn.xacml.api.autho.AttributeIdentifier; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.attr.BagAttribute; +import com.sun.xacml.debug.RuntimeInfo; + +public interface AnalysisAttributeResolver { + + /** + * may return three different "types" of results + *
        + *
      • null, indicating that this object cannot resolve the attribute. + * the next attributeResolver in the list will be queried
      • + *
      • an empty bag, indicating that the resolution of the attribute + * is simulated to fail: the empty bag is returned to the + * evaluation engine, no further attributeResolver will be + * queried
      • + *
      • a bag with one or several attribute values. the bag is returned + * to the evaluation engine, no further attributeResolver will be + * queried
      • + *
      + * + * @param attrId + * @param context + * @param resolver + * @return + */ + BagAttribute resolveAttribute(AttributeIdentifier attrId, + EvaluationCtx context, RuntimeInfo runtimeInfo); + + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/attributes/AttributeHelper.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/attributes/AttributeHelper.java new file mode 100644 index 0000000..d8a02ea --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/attributes/AttributeHelper.java @@ -0,0 +1,175 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.attributes; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import org.apache.log4j.Logger; + + +import eu.aniketos.securebpmn.xacml.api.autho.AttributeIdentifier; + +import com.sun.xacml.PolicyTreeElement; +import com.sun.xacml.attr.AttributeDesignator; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BagAttribute; +import com.sun.xacml.attr.BooleanAttribute; +import com.sun.xacml.attr.IntegerAttribute; +import com.sun.xacml.attr.StringAttribute; +import com.sun.xacml.attr.TimeAttribute; +import com.sun.xacml.attr.TypeIdentifierConstants; +import com.sun.xacml.cond.EvaluationResult; +import com.sun.xacml.debug.RuntimeInfo; + +/** + * This class contains some helper functions which help to handle + * all kinds of tasks regarding to XACML attributes + * + * + */ +public class AttributeHelper { + + private static Map abstractAttributes; + + private static Logger logger = Logger.getLogger(AttributeHelper.class); + + static { + abstractAttributes = new HashMap(); + + abstractAttributes.put(TypeIdentifierConstants.STRING_URI, + new TestStringAttribute("__test_value__")); + abstractAttributes.put(TypeIdentifierConstants.INTEGER_URI, + new TestIntegerAttribute(Integer.MIN_VALUE + 42)); + abstractAttributes.put(TypeIdentifierConstants.TIME_URI, + new TestTimeAttribute(new Date(42))); + abstractAttributes.put(TypeIdentifierConstants.BOOLEAN_URI, + new TestBooleanAttribute(false)); + + } + + /** + * returns attributes which can be used for abstract evaluation, i.e., + * those values are returned by the attribute resolver and can be identified + * by the special combining algs and for analysis purposes as "abstract" values + * using the isAbstractAttribute function + * @param attributeType + * @return + */ + public static AttributeValue getAbstractAttribute(URI attributeType) { + if ( abstractAttributes.containsKey(attributeType) ) { + return abstractAttributes.get(attributeType); + } else { + throw new RuntimeException("missing default value for dataType " + attributeType); + } + } + + /** + * returns if the attribute is an abstract attribute, i.e., was injected + * into the engine as retrieved from the getAbstractAttribute function + * @param value + * @return + */ + public static boolean isAbstractAttribute(AttributeValue value) { + if ( value instanceof AbstractAttribute ) { + return true; + } else if ( value instanceof BagAttribute ) { + for ( AttributeValue val : ((BagAttribute) value).iterable() ) { + if ( val instanceof AbstractAttribute) { + return true; + } + } + } + return false; + } + + /** + * returns if the result contains an abstract attribute, i.e., was injected + * into the engine as retrieved from the getAbstractAttribute function + * @param result + * @return + */ + public static boolean containsAbstractValue(EvaluationResult result) { + if ( result != null && result.getAttributeValue() != null ) { + return isAbstractAttribute(result.getAttributeValue()); + } else { + return false; + } + } + + public static AttributeIdentifier getAttributeIdentifier(AttributeDesignator attrDsgn) { + return new AttributeIdentifier(attrDsgn.getCategory(), attrDsgn.getType(), + attrDsgn.getId(), attrDsgn.getIssuer()); + } + + + /** + * helper functions which creates a bag around a singe value + * @param value + * @return + */ + public static BagAttribute createSingleBag(AttributeValue value) { + ArrayList list = new ArrayList(); + list.add(value); + return new BagAttribute(value.getType(), list); + } + + /** + * returns the next PolicyTreeElement for an XACML element (requiring its RuntimeInfo + * object); for example, when having an attributeDesignator, one can decide if + * this is used within a rule or within a policy + * @param runtimeInfo + * @return + */ + public static PolicyTreeElement getPolicyTreeElement(RuntimeInfo runtimeInfo) { + if ( runtimeInfo.getXACMLObject() instanceof PolicyTreeElement ) { + return (PolicyTreeElement) runtimeInfo.getXACMLObject(); + } else { + if ( runtimeInfo.getCalledFrom() == null ) { + logger.warn("Could not find encapsulating PolicyTreeElement: reached most upper element without finding a PolicyTreeElement"); + return null; + } + return getPolicyTreeElement(runtimeInfo.getCalledFrom()); + } + } + + static class TestStringAttribute extends StringAttribute implements AbstractAttribute { + TestStringAttribute(String value) { + super(value); + } + } + + static class TestIntegerAttribute extends IntegerAttribute implements AbstractAttribute { + TestIntegerAttribute(int value) { + super(value); + } + } + + static class TestTimeAttribute extends TimeAttribute implements AbstractAttribute { + TestTimeAttribute(Date date) { + super(date); + } + } + + static class TestBooleanAttribute extends BooleanAttribute implements AbstractAttribute { + TestBooleanAttribute(boolean value) { + super(value); + } + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/attributes/KnownAttributeResolver.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/attributes/KnownAttributeResolver.java new file mode 100644 index 0000000..6f748cf --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/java/eu/aniketos/securebpmn/xacml/pdp/runtimeEvaluation/attributes/KnownAttributeResolver.java @@ -0,0 +1,96 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.attributes; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.log4j.Logger; + +import eu.aniketos.securebpmn.xacml.api.autho.AttributeIdentifier; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BagAttribute; +import com.sun.xacml.debug.RuntimeInfo; + + +/** + * This class can be used to resolve attributes at analysis time + * to specific values, e.g., as provided by the user beforehand + * + */ +public class KnownAttributeResolver implements AnalysisAttributeResolver { + + private static final Logger logger = Logger.getLogger(KnownAttributeResolver.class); + + private Map attributeValues = + new HashMap(); + + + + public BagAttribute resolveAttribute(AttributeIdentifier attrId, + EvaluationCtx context, RuntimeInfo resolver) { + + if ( attributeValues.containsKey(attrId)) { + BagAttribute attr = attributeValues.get(attrId); + if ( logger.isDebugEnabled() ) { + logger.debug("return " + attr.size() + " values for attribute " + + attrId.getAttributeId() + " type " + attrId.getAttributeType()); + } + return attr; + } else { + return null; + } + } + + /** + * Overwrites all existing attributes! + * + * @param attributeValues as returned by the designator module, i.e., must be a + * BagAttribute! may be null to unset all attributeValues + */ + public void setAttributeBagValues(Map attributeValues) { + if ( attributeValues == null ) { + this.attributeValues.clear(); + } + this.attributeValues = attributeValues; + } + + /** + * Overwrites all existing attributes! + * + * @param attributeValues as single value, i.e., must NOT be a BagAttribute + */ + public void setAttributeValues(Map attributeValues) { + this.attributeValues.clear(); + if ( attributeValues != null ) { + for ( AttributeIdentifier attrId : attributeValues.keySet()) { + this.attributeValues.put(attrId, + AttributeHelper.createSingleBag(attributeValues.get(attrId))); + } + } + } + + public void addAttributeValue(AttributeIdentifier key, AttributeValue value) { + this.attributeValues.put(key, AttributeHelper.createSingleBag(value)); + } + + public void clear() { + this.attributeValues.clear(); + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/resources/policy-config.xml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/resources/policy-config.xml new file mode 100644 index 0000000..2000e1f --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/resources/policy-config.xml @@ -0,0 +1,20 @@ + + + + + + + + conf:useLines:true + + + + + + + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/cxf-servlet.xml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/cxf-servlet.xml new file mode 100644 index 0000000..53f04f1 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -0,0 +1,23 @@ + + + + + + + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/log4j.properties b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/log4j.properties new file mode 100644 index 0000000..583b05d --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/log4j.properties @@ -0,0 +1,13 @@ +log4j.rootLogger=INFO, logfile + +log4j.appender.logfile=org.apache.log4j.FileAppender +log4j.appender.logfile.layout=org.apache.log4j.PatternLayout +log4j.appender.logfile.layout.ConversionPattern=%d %-5p %c{1} %m%n +log4j.appender.logfile.File=${catalina.base}/logs/pdp.log + +log4j.logger.eu.aniketos.securebpmn.xacml=DEBUG +log4j.logger.com.sun.xacml=DEBUG + +log4j.logger.org.apache.commons.httpclient.HttpMethodDirector=WARN + +# thread[%-5.15t]%n diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/policies/test4.xacml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/policies/test4.xacml new file mode 100644 index 0000000..edc702c --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/policies/test4.xacml @@ -0,0 +1,114 @@ + + + + + + + breakglass.prototype.MedicalRecord + + + + + + + + Default policy (no exception level) for MedicalRecord + + + + + + + + + + + + + + update + + + + + + read + + + + + + delete + + + + + + + + + + + + + 00:00:00Z + 23:59:59Z + + + + + + + + + + + + + + + helmut + + + + + + + + + + + + + + + + + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/policy-config.xml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/policy-config.xml new file mode 100644 index 0000000..6354a3a --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/policy-config.xml @@ -0,0 +1,21 @@ + + + + + + + + file:policies/test4.xacml + conf:useLines:true + + + + + + + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/svn-config.xml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/svn-config.xml new file mode 100644 index 0000000..6d52328 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/svn-config.xml @@ -0,0 +1,8 @@ + + + + + + -1 + false + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/web.xml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 0000000..3bf0c74 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,20 @@ + + + + pdp + pdp + + pdp + pdp + Policy Decision Point + org.apache.cxf.transport.servlet.CXFServlet + 1 + + + pdp + /* + + + 60 + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/abstractEval/abstractEval-config.xml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/abstractEval/abstractEval-config.xml new file mode 100644 index 0000000..3a90e58 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/abstractEval/abstractEval-config.xml @@ -0,0 +1,28 @@ + + + + + + + + file:abstractEval_policy2011.xacml + file:abstractEval_andortest.xacml + file:abstractEval_xacmlv1test.xacml + + + + + + + + + + + + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/abstractEval/abstractEval_andortest.xacml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/abstractEval/abstractEval_andortest.xacml new file mode 100644 index 0000000..246616e --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/abstractEval/abstractEval_andortest.xacml @@ -0,0 +1,56 @@ + + + + + Simple policy to test the behaviour of the modified logical functions + defined in eu.aniketos.securebpmn.xacml.xacml.cond.AnalysisLogicalFunction + + + + + + + AndOrTest + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/abstractEval/abstractEval_policy2011.xacml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/abstractEval/abstractEval_policy2011.xacml new file mode 100644 index 0000000..658805d --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/abstractEval/abstractEval_policy2011.xacml @@ -0,0 +1,103 @@ + + + + + This is the policy as it was used for the POLICY2011 publication: + A Framework for Managing and Analyzing Changes of Security Policies + http://www.brucker.ch/bibliography/download/2011/brucker.ea-framework-2011.pdf + + Update: the combining alg of the policy has to be permit-overrides + + + + + + + HealthRecord + + + + + + + + + + + + Nurse + + + + + + + + + + + + + + 20:00:00Z + 06:00:00Z + + + + + + + + + + + read + + + + + + + + + + + + + + + + + + + + + Doctor + + + + + + + + + + + + + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/abstractEval/abstractEval_xacmlv1test.xacml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/abstractEval/abstractEval_xacmlv1test.xacml new file mode 100644 index 0000000..a07d9d6 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/abstractEval/abstractEval_xacmlv1test.xacml @@ -0,0 +1,54 @@ + + + + + Simple policy to test the behaviour of the modified logical functions + defined in eu.aniketos.securebpmn.xacml.xacml.cond.AnalysisLogicalFunction + + + + + + + AndOrTestv1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/abstractEval/roles.config b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/abstractEval/roles.config new file mode 100644 index 0000000..7859c91 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/abstractEval/roles.config @@ -0,0 +1,5 @@ +carol:Nurse;Employee +alice:Nurse;Employee +marvin:Nurse;Employee +bob:Doctor;Nurse;Employee +dave:Doctor;Nurse;Employee diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/analysis-config.xml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/analysis-config.xml new file mode 100644 index 0000000..33d9d2a --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/analysis-config.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + conf:useLines:true + file:policy2.xacml + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/becker/nhs-becker-healthrecord.xacml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/becker/nhs-becker-healthrecord.xacml new file mode 100644 index 0000000..f914811 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/becker/nhs-becker-healthrecord.xacml @@ -0,0 +1,228 @@ + + + + + + + + + + urn:nhs:becker:health-record + + + + + + + + + Policy for role Clinicians + + + + + + clinician + + + + + + + allow read, if subject is owner and patient gave one-off-consent (S5.3.3) + + + + + + read + + + + + + + + + + + + + + + + + + + + + + + deny non treating clinicians + + + + + + + + + + + + + + + + + + + + + + + + add a new item S5.1.1 + get a list of all records (only IDs) S5.2.3 + + + + + + + + add + + + + + get-record-item-list + + + + + + + + + + + allow read if subjects match, not sealed by patient (and treating clinician) (S5.3.4) + or, if sealed, allow access only if + + + + + + + read + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Policy for role Patient + + + + + + patient + + + + + + + + Allow patients to add comments to their own health record + + + + + + nhs:becker:health-record:comment + + + + + + + + add + + + + + + + + + + + + + + + + + + + final deny policy/rule + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/becker/nhs-becker-p_reg.xacml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/becker/nhs-becker-p_reg.xacml new file mode 100644 index 0000000..7fca213 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/becker/nhs-becker-p_reg.xacml @@ -0,0 +1,11 @@ + + + + nhs:becker:health-record + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/becker/nhs-becker.xacml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/becker/nhs-becker.xacml new file mode 100644 index 0000000..cdbaa28 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/becker/nhs-becker.xacml @@ -0,0 +1,23 @@ + + + + + + + + + urn:nhs:becker + + + + + + nhs:becker:p_reg + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/becker/nhs_agents.xacml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/becker/nhs_agents.xacml new file mode 100644 index 0000000..3c73233 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/becker/nhs_agents.xacml @@ -0,0 +1,41 @@ + + + + + + + + + nhs:becker:agent-relationship + + + + + + + + + + + + + patient + + + + + + + + + + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/becker/nhs_relationship.xacml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/becker/nhs_relationship.xacml new file mode 100644 index 0000000..98fb674 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/becker/nhs_relationship.xacml @@ -0,0 +1,200 @@ + + + + + + + + + nhs:becker:relationship + + + + + + + + + + + + + clinician + + + + + + + + + + + + + + + request-consent-to-treatment + + + + + + request-consent-to-group-treatment + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + cancel-consent-to-treatment + + + + + + + + + + + + + + + + + + + + + + + + + + + + patient + + + + + + + + + + + + + consent-to-treatment + + + + + + cancel-consent-to-treatment + + + + + + + + + + + + + + + + + + + + + + + + + agent + + + + + + + + + + + + + consent-to-treatment + + + + + + cancel-consent-to-treatment + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/AnalysisPDPTest.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/AnalysisPDPTest.java new file mode 100644 index 0000000..6017b5f --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/AnalysisPDPTest.java @@ -0,0 +1,183 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Properties; +import java.util.Vector; + +import org.apache.log4j.PropertyConfigurator; + +import eu.aniketos.securebpmn.xacml.api.SecurityError; +import eu.aniketos.securebpmn.xacml.api.autho.AuthoAttribute; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.EvaluationEventHub; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.MissingAttrCapture; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.PrettyPrinter; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.ReportGenerator; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.attributes.AbstractAttributeResolver; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.attributes.KnownAttributeResolver; +import eu.aniketos.securebpmn.xacml.AnalysisConfig; +import eu.aniketos.securebpmn.xacml.AnalysisCtx; +import eu.aniketos.securebpmn.xacml.support.XACMLDecoder; +import eu.aniketos.securebpmn.xacml.support.XACMLEncoder; +import eu.aniketos.securebpmn.xacml.support.attr.EvaluationIdAttribute; + +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.Constants; +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; +import com.sun.xacml.attr.TypeIdentifierConstants; +import com.sun.xacml.ctx.RequestCtx; +import com.sun.xacml.ctx.ResponseCtx; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * code to test the PDPServer as it is used for analysis purposes; + * configuration is loaded from a local file + *
      + * Note: Only works when pdp project is build with analysis-pdp.pom.xml + * + */ +public class AnalysisPDPTest extends TestCase { + + + private PDPServer pdp; + + private KnownAttributeResolver knownAttrs; + private AnalysisConfig conf; + private EvaluationEventHub eventHub; + private MissingAttrCapture attrCapt; + + public static void main(String[] args) throws IOException, ParsingException, UnknownIdentifierException, SecurityError, URISyntaxException { + //when using the PDPServer not within tomcat + Properties log4jProps = new Properties(); + log4jProps.load(new BufferedInputStream(new FileInputStream(new File("src/test/log4j.properties")))); + PropertyConfigurator.configure(log4jProps); + + AnalysisPDPTest test = new AnalysisPDPTest(); + + test.setup(); + test.exec(); + } + + + private void setup() throws FileNotFoundException, ParsingException, UnknownIdentifierException, SecurityError, URISyntaxException { + ConfigurationStore config = new ConfigurationStore(new File("src/test/productive-config.xml")); + conf = new AnalysisConfig(config.getDefaultPDPConfig()); + + knownAttrs = new KnownAttributeResolver(); + conf.addAnalysisAttributeResolver(knownAttrs); + conf.addAnalysisAttributeResolver(new AbstractAttributeResolver()); + + //create PDP + pdp = new PDPServer(conf); + + //for analysis/evaluation create required classes + eventHub = new EvaluationEventHub(); + + // keep track of missing and resovled attributes + attrCapt = new MissingAttrCapture(eventHub.getEvalInfo()); + eventHub.register(attrCapt); + + // print the call stack + eventHub.register(new PrettyPrinter()); + } + + + + + + + private void exec() throws SecurityError, URISyntaxException, ParsingException { + List attributes = new Vector(); + attributes.add( + new AuthoAttribute( + Constants.SUBJECT_CAT, + Constants.SUBJECT_ID, + TypeIdentifierConstants.STRING_URI, + "root")); + attributes.add( + new AuthoAttribute( + Constants.SUBJECT_CAT, + URI.create("urn:subject:department"), + TypeIdentifierConstants.STRING_URI, + "test1")); +// attributes.add( +// new AuthoAttribute( +// Constants.RESOURCE_CAT, +// URI.create("urn:patient:department"), +// TypeIdentifierConstants.STRING_URI, +// "test1")); + + attributes.add( + new AuthoAttribute( + Constants.SUBJECT_CAT, + URI.create("subject-roles"), + TypeIdentifierConstants.STRING_URI, + "Nurse")); + + //urn:nhs:becker:health-record MedicalRecord + RequestCtx request = XACMLDecoder.decodeRequestCtx(null, new URI("urn:nhs:becker:health-record"), "read", attributes); + + String requestString = XACMLEncoder.encodeRequestCtx(request); + System.out.println("REQUEST:\n" + requestString); + + ResponseCtx resp = pdp.analyze(new AnalysisCtx(request, conf, + EvaluationIdAttribute.INVALID, eventHub)); + + String responseString = XACMLEncoder.encodeResponseCtx(resp); + + //String responseString = pdp.evaluateXACML(requestString); + System.out.println("RESPONE:\n" + responseString); //XACMLEncoder.encodeResponseCtx(response)); + + ReportGenerator repGen = new ReportGenerator(attrCapt.getKnownAttributes(), + eventHub.getEvalInfo().getTreeElemTree()); + + System.out.println("REPORT:::"); + System.out.println( repGen.reportMissingAttr()); + + + } + + + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AnalysisPDPTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/AppTest.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/AppTest.java new file mode 100644 index 0000000..45a816d --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/AppTest.java @@ -0,0 +1,102 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Properties; + +import org.apache.log4j.PropertyConfigurator; + +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + public static void main(String[] args) throws IOException, ParsingException, UnknownIdentifierException { + Properties log4jProps = new Properties(); + log4jProps.load(new BufferedInputStream(new FileInputStream(new File("src/test/log4j.properties")))); + PropertyConfigurator.configure(log4jProps); + // //AppTest test = new AppTest("pdpServer test"); + //test.testApp(); + foo(); + } + + private static void foo() throws FileNotFoundException, ParsingException, UnknownIdentifierException { + //PDPServer pdpServer = new PDPServer(new File("src/main/webapp/WEB-INF/policy-config.xml"), "src/main/webapp/webapp/WEB-INF/"); + + + } +// private static final String SVN_URL = "https://projects.brucker.ch/soknos-dev/svn/trunk/examples/versionedPDP_data"; +// private static final String USERNAME = "pdp"; +// private static final String PASSWORD = "HJeSnelw"; + +// private static void bar() { +// +//// +//// Properties log4jProps = new Properties(); +//// try { +//// log4jProps.load(new BufferedInputStream(new FileInputStream(new File(PDPServer.LOG4J)))); +//// PropertyConfigurator.configure(log4jProps); +//// logger.info("Loaded log4j configuration from " + PDPServer.LOG4J); +//// } catch (IOException e) { +//// logger.error("Could not load log4j configuration from " + PDPServer.LOG4J + " IOException: " + e.getMessage()); +//// System.err.println("Could not load log4j configuration from log4j.properties IOException: " + e.getMessage()); +//// } +// +// new SVNPolicyFinderModule(SVN_URL, USERNAME, PASSWORD, -1); +// } + /** + * Rigourous Test :-) + */ + public void testApp() + { + + assertTrue( true ); + } + + + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/PDPState.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/PDPState.java new file mode 100644 index 0000000..7ff60c0 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/PDPState.java @@ -0,0 +1,60 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp; + +import eu.aniketos.securebpmn.xacml.pdpstate.DemoPDPStateMgt; +import eu.aniketos.securebpmn.xacml.pdpstate.PDPStateManagement; + +public class PDPState { + + private static PDPStateManagement pdpStateMgt; + private static DemoPDPStateMgt demoPdpStateMgt; + + /** + * @param args + */ + public static void main(String[] args) { + // TODO Auto-generated method stub + + } + + public static final String ALICE = "Alice", + BOB = "Bob", + NURSE = "nurse", + CLINICAN = "clinician"; + + + + public static void setupDemoRoles() { + init(); + + demoPdpStateMgt.addRole(ALICE, NURSE); + demoPdpStateMgt.addRole(BOB, CLINICAN); + demoPdpStateMgt.addRole(BOB, NURSE); + } + + + private static void init() { + if (pdpStateMgt == null ) { + pdpStateMgt = PDPStateManagement.getInstance(); + demoPdpStateMgt = new DemoPDPStateMgt(); + } + + } + + + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/PlainPDPTest.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/PlainPDPTest.java new file mode 100644 index 0000000..89c82d2 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/PlainPDPTest.java @@ -0,0 +1,139 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Properties; +import java.util.Vector; + +import org.apache.log4j.PropertyConfigurator; + +import eu.aniketos.securebpmn.xacml.api.SecurityError; +import eu.aniketos.securebpmn.xacml.api.autho.AuthoAttribute; +import eu.aniketos.securebpmn.xacml.support.XACMLDecoder; +import eu.aniketos.securebpmn.xacml.support.XACMLEncoder; + +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.Constants; +import com.sun.xacml.PDP; +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; +import com.sun.xacml.attr.TypeIdentifierConstants; +import com.sun.xacml.ctx.RequestCtx; +import com.sun.xacml.ctx.ResponseCtx; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + + +/** + * tests the plain (com.sun.xacml) PDP + * + */ +public class PlainPDPTest extends TestCase { + + private PDP pdp; + + public static void main(String[] args) throws FileNotFoundException, IOException, ParsingException, UnknownIdentifierException, SecurityError, URISyntaxException { + Properties log4jProps = new Properties(); + log4jProps.load(new BufferedInputStream(new FileInputStream(new File("src/test/log4j.properties")))); + PropertyConfigurator.configure(log4jProps); + + PlainPDPTest test = new PlainPDPTest(); + test.setup(); + test.foo(); + } + + private void setup() throws FileNotFoundException, ParsingException, UnknownIdentifierException { + ConfigurationStore config = new ConfigurationStore( + new FileInputStream(new File("src/test/productive-config.xml")), "src/test/"); + pdp = new PDP(config.getDefaultPDPConfig()); + } + + + + +// private static void bar() throws FileNotFoundException, ParsingException, UnknownIdentifierException, SecurityError, URISyntaxException { +// +// +// ConfigurationStore config = new ConfigurationStore( +// new FileInputStream(new File("src/test/productive-config.xml")), "src/test/"); +// PDP pdp = new PDP(config.getDefaultPDPConfig()); + +// PDPServer pdp = new PDPServer(new File("src/test/productive-config.xml"), "src/test/"); +//// +//// +//// exec(pdp); +// +// +// +// +// +// } + + private void foo() throws FileNotFoundException, ParsingException, UnknownIdentifierException, SecurityError, URISyntaxException { + + List attributes = new Vector(); + attributes.add( + new AuthoAttribute( + Constants.SUBJECT_CAT, + Constants.SUBJECT_ID, + TypeIdentifierConstants.STRING_URI, + "root")); + +// attributes.add( +// new AuthoAttribute( +// Constants.RESOURCE_CAT, +// URI.create("urn:owner"), +// TypeIdentifierConstants.STRING_URI, +// "helmut")); + + RequestCtx request = XACMLDecoder.decodeRequestCtx(null, new URI("MedicalRecord"), "read", attributes); + + + System.out.println("REQUEST:\n" + XACMLEncoder.encodeRequestCtx(request)); + + ResponseCtx response = pdp.evaluate(request); + System.out.println("RESPONE:\n" + XACMLEncoder.encodeResponseCtx(response)); + + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( PlainPDPTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + + assertTrue( true ); + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/ProductiveSVNTest.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/ProductiveSVNTest.java new file mode 100644 index 0000000..62ad7d8 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/ProductiveSVNTest.java @@ -0,0 +1,75 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.URISyntaxException; +import java.util.Properties; + +import org.apache.log4j.PropertyConfigurator; + +import eu.aniketos.securebpmn.xacml.api.SecurityError; +import eu.aniketos.securebpmn.xacml.SVNPDPConfig; + +import com.sun.xacml.PDPConfig; +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; + +import junit.framework.Test; +import junit.framework.TestSuite; + +public class ProductiveSVNTest extends ProductiveTest { + + public static void main(String[] args) throws FileNotFoundException, IOException, ParsingException, UnknownIdentifierException, SecurityError, URISyntaxException { + + Properties log4jProps = new Properties(); + log4jProps.load(new BufferedInputStream(new FileInputStream(new File("src/test/log4j.properties")))); + PropertyConfigurator.configure(log4jProps); + + ProductiveSVNTest test = new ProductiveSVNTest(); + test.setup(); + test.foo(); + + } + + private void setup() throws FileNotFoundException, ParsingException, UnknownIdentifierException, SecurityError { + PDPConfig conf = SVNPDPConfig.getSVNPDPConfig(new File("src/main/webapp/WEB-INF/svn-config.xml")); + pdp = new PDPServer(conf); + + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( ProductiveSVNTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + + assertTrue( true ); + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/ProductiveTest.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/ProductiveTest.java new file mode 100644 index 0000000..2f0ba83 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/ProductiveTest.java @@ -0,0 +1,122 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Properties; +import java.util.Vector; + +import org.apache.log4j.PropertyConfigurator; + +import eu.aniketos.securebpmn.xacml.api.SecurityError; +import eu.aniketos.securebpmn.xacml.api.autho.AuthoAttribute; +import eu.aniketos.securebpmn.xacml.api.autho.AuthoResult; +import eu.aniketos.securebpmn.xacml.api.idm.IdInfo; + + +import com.sun.xacml.Constants; +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; +import com.sun.xacml.attr.TypeIdentifierConstants; + + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +public class ProductiveTest extends TestCase { + + protected PDPServer pdp; + + public static void main(String[] args) throws UnknownIdentifierException, ParsingException, IOException, SecurityError, URISyntaxException { + Properties log4jProps = new Properties(); + log4jProps.load(new BufferedInputStream(new FileInputStream(new File("src/test/log4j.properties")))); + PropertyConfigurator.configure(log4jProps); + + ProductiveTest test = new ProductiveTest(); + test.setup(); + test.foo(); + } + + private void setup() throws UnknownIdentifierException, ParsingException, FileNotFoundException { + pdp = new PDPServer(new File("src/test/productive-config.xml")); + + } + + protected void foo() throws FileNotFoundException, ParsingException, UnknownIdentifierException, SecurityError, URISyntaxException { + + List attributes = new Vector(); + attributes.add( + new AuthoAttribute( + Constants.SUBJECT_CAT, + Constants.SUBJECT_ID, + TypeIdentifierConstants.STRING_URI, + "root")); + + attributes.add( + new AuthoAttribute( + Constants.SUBJECT_CAT, + URI.create("urn:subject:department"), + TypeIdentifierConstants.STRING_URI, + "test1")); + attributes.add( + new AuthoAttribute( + Constants.RESOURCE_CAT, + URI.create("urn:patient:department"), + TypeIdentifierConstants.STRING_URI, + "test1")); + +// RequestCtx request = XACMLDecoder.decodeRequestCtx(null, new URI("MedicalRecord"), "read", attributes); +// +// +// System.out.println("REQUEST:\n" + XACMLEncoder.encodeRequestCtx(request)); + + AuthoResult result = pdp.evaluate(new IdInfo("root", null, null), "MedicalRecord", "read", attributes); + + //ResponseCtx response = pdp.evaluate(request); + System.out.println("RESPONE:\n" + result); + + pdp.unload(); + + } + + + + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( ProductiveTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/abtractEval/AndOr.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/abtractEval/AndOr.java new file mode 100644 index 0000000..0f0b77c --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/abtractEval/AndOr.java @@ -0,0 +1,205 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.abtractEval; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Properties; +import java.util.Vector; + +import org.apache.log4j.PropertyConfigurator; + +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.Constants; +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; +import com.sun.xacml.attr.TypeIdentifierConstants; +import com.sun.xacml.ctx.RequestCtx; +import com.sun.xacml.ctx.ResponseCtx; + +import eu.aniketos.securebpmn.xacml.api.SecurityError; +import eu.aniketos.securebpmn.xacml.api.autho.AuthoAttribute; +import eu.aniketos.securebpmn.xacml.api.idm.IdInfo; +import eu.aniketos.securebpmn.xacml.pdp.PDPServer; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.EvaluationEventHub; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.MissingAttrCapture; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.PrettyPrinter; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.ReportGenerator; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.attributes.AbstractAttributeResolver; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.attributes.KnownAttributeResolver; +import eu.aniketos.securebpmn.xacml.AnalysisConfig; +import eu.aniketos.securebpmn.xacml.AnalysisCtx; +import eu.aniketos.securebpmn.xacml.support.XACMLDecoder; +import eu.aniketos.securebpmn.xacml.support.XACMLEncoder; +import eu.aniketos.securebpmn.xacml.support.attr.EvaluationIdAttribute; + +public class AndOr { + + /* + * TODO modify the current infrastructure => do not evaluate or treat the result as + * abstract if a non-abstract true was found + */ + + + private PDPServer pdp; + + private KnownAttributeResolver knownAttrs; + private AnalysisConfig conf; + private EvaluationEventHub eventHub; + private MissingAttrCapture attrCapt; + + /** + * @param args + * @throws IOException + * @throws FileNotFoundException + * @throws URISyntaxException + * @throws SecurityError + * @throws UnknownIdentifierException + * @throws ParsingException + */ + public static void main(String[] args) throws FileNotFoundException, IOException, ParsingException, UnknownIdentifierException, SecurityError, URISyntaxException { + Properties log4jProps = new Properties(); + log4jProps.load(new BufferedInputStream(new FileInputStream(new File("src/test/log4j.properties")))); + PropertyConfigurator.configure(log4jProps); + + + AndOr test = new AndOr(); + test.setup(); + + test.testv1(); + //test.testv2(); + //test.testRoleAssignment(); + } + + + private void testRoleAssignment() throws SecurityError, URISyntaxException, ParsingException { + RequestCtx request = XACMLDecoder.decodeRequestCtx( + new IdInfo("admin@aniketos.eu"), + new URI("urn:runEx:role:assignment"), + "add", null); + analyze(request); + + } + + + + private void testv2() throws SecurityError, URISyntaxException, ParsingException { + List attributes = new Vector(); + + //add some attribute directly to the request + attributes.add( + new AuthoAttribute( + Constants.SUBJECT_CAT, + URI.create("urn:test:true"), + TypeIdentifierConstants.BOOLEAN_URI, + "true")); + + attributes.add( + new AuthoAttribute( + Constants.SUBJECT_CAT, + URI.create("urn:test:false"), + TypeIdentifierConstants.BOOLEAN_URI, + "false")); + + RequestCtx request = XACMLDecoder.decodeRequestCtx( + new IdInfo("foo", null, null), + new URI("AndOrTest"), + "bar", attributes); + + analyze(request); + } + + private void testv1() throws SecurityError, URISyntaxException, ParsingException { + List attributes = new Vector(); + + //add some attribute directly to the request + attributes.add( + new AuthoAttribute( + Constants.SUBJECT_CAT, + URI.create("urn:test:true"), + TypeIdentifierConstants.BOOLEAN_URI, + "true")); + + attributes.add( + new AuthoAttribute( + Constants.SUBJECT_CAT, + URI.create("urn:test:false"), + TypeIdentifierConstants.BOOLEAN_URI, + "false")); + + RequestCtx request = XACMLDecoder.decodeRequestCtx( + new IdInfo("foo", null, null), + new URI("AndOrTestv1"), + "bar", attributes); + + analyze(request); + } + + + private void setup() throws FileNotFoundException, ParsingException, UnknownIdentifierException, SecurityError, URISyntaxException { + ConfigurationStore config = new ConfigurationStore(new File("src/test/abstractEval/abstractEval-config.xml")); + //ConfigurationStore config = new ConfigurationStore(new File("src/test/runningExample/pdp-config.xml")); + conf = new AnalysisConfig(config.getDefaultPDPConfig()); + + // first add attribute resolvers which will resolve known attributes + // can/should be replaced for workbench version with versioned policy state module + knownAttrs = new KnownAttributeResolver(); + conf.addAnalysisAttributeResolver(knownAttrs); + + //only if no attribute can be found, use abstract value + conf.addAnalysisAttributeResolver(new AbstractAttributeResolver()); + + //create PDP + pdp = new PDPServer(conf); + + //for analysis/evaluation create required classes + eventHub = new EvaluationEventHub(); + + // keep track of missing and resovled attributes + attrCapt = new MissingAttrCapture(eventHub.getEvalInfo()); + eventHub.register(attrCapt); + + // print the call stack + eventHub.register(new PrettyPrinter()); + } + + private void analyze(RequestCtx request) throws ParsingException { + // print XACML request + String requestString = XACMLEncoder.encodeRequestCtx(request); + System.out.println("XACML REQUEST:\n" + requestString); + + // evaluate request + ResponseCtx resp = pdp.analyze(new AnalysisCtx(request, conf, + EvaluationIdAttribute.INVALID, eventHub)); + + // print XACML response + String responseString = XACMLEncoder.encodeResponseCtx(resp); + System.out.println("RESPONE:\n" + responseString); + + ReportGenerator repGen = new ReportGenerator(attrCapt.getKnownAttributes(), + eventHub.getEvalInfo().getTreeElemTree()); + + System.out.println("REPORT:::"); + System.out.println( repGen.reportMissingAttr()); + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/abtractEval/HolTestGen.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/abtractEval/HolTestGen.java new file mode 100644 index 0000000..6abfe87 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/abtractEval/HolTestGen.java @@ -0,0 +1,288 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.abtractEval; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Properties; +import java.util.Vector; + +import org.apache.log4j.PropertyConfigurator; + +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.Constants; +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; +import com.sun.xacml.attr.TypeIdentifierConstants; +import com.sun.xacml.ctx.RequestCtx; +import com.sun.xacml.ctx.ResponseCtx; + +import eu.aniketos.securebpmn.xacml.api.SecurityError; +import eu.aniketos.securebpmn.xacml.api.autho.AuthoAttribute; +import eu.aniketos.securebpmn.xacml.api.idm.IdInfo; +import eu.aniketos.securebpmn.xacml.pdp.PDPServer; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.EvaluationEventHub; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.MissingAttrCapture; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.PrettyPrinter; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.ReportGenerator; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.attributes.AbstractAttributeResolver; +import eu.aniketos.securebpmn.xacml.pdp.runtimeEvaluation.attributes.KnownAttributeResolver; +import eu.aniketos.securebpmn.xacml.AnalysisConfig; +import eu.aniketos.securebpmn.xacml.AnalysisCtx; +import eu.aniketos.securebpmn.xacml.support.XACMLDecoder; +import eu.aniketos.securebpmn.xacml.support.XACMLEncoder; +import eu.aniketos.securebpmn.xacml.support.attr.EvaluationIdAttribute; + +public class HolTestGen { + + private PDPServer pdp; + + private KnownAttributeResolver knownAttrs; + private AnalysisConfig conf; + private EvaluationEventHub eventHub; + private MissingAttrCapture attrCapt; + + + public static void main(String[] args) throws FileNotFoundException, IOException, ParsingException, UnknownIdentifierException, SecurityError, URISyntaxException { + Properties log4jProps = new Properties(); + log4jProps.load(new BufferedInputStream(new FileInputStream(new File("src/test/log4j.properties")))); + PropertyConfigurator.configure(log4jProps); + + HolTestGen test = new HolTestGen(); + + test.setup(); + + // missing time + test.carol_read_notime(); + test.clear(); + + +// // missing patient department and time +// test.carol_read_noPatDepTime(); +// test.clear(); + + } + + private void clear() { + eventHub.clearEvalInfo(); + knownAttrs.clear(); + } + + + private void setup() throws FileNotFoundException, ParsingException, UnknownIdentifierException, SecurityError, URISyntaxException { + ConfigurationStore config = new ConfigurationStore(new File("src/test/abstractEval/abstractEval-config.xml")); + conf = new AnalysisConfig(config.getDefaultPDPConfig()); + + // first add attribute resolvers which will resolve known attributes + // can/should be replaced for workbench version with versioned policy state module + knownAttrs = new KnownAttributeResolver(); + conf.addAnalysisAttributeResolver(knownAttrs); + + //only if no attribute can be found, use abstract value + conf.addAnalysisAttributeResolver(new AbstractAttributeResolver()); + + //create PDP + pdp = new PDPServer(conf); + + //for analysis/evaluation create required classes + eventHub = new EvaluationEventHub(); + + // keep track of missing and resovled attributes + attrCapt = new MissingAttrCapture(eventHub.getEvalInfo()); + eventHub.register(attrCapt); + + // print the call stack + eventHub.register(new PrettyPrinter()); + } + + private void carol_read_notime() throws SecurityError, URISyntaxException, ParsingException { + List attributes = new Vector(); + + //add some attribute directly to the request + attributes.add( + new AuthoAttribute(Constants.SUBJECT_CAT, URI.create("urn:subject:department"), TypeIdentifierConstants.STRING_URI, + "test1")); + + attributes.add( + new AuthoAttribute(Constants.RESOURCE_CAT, URI.create("urn:patient:department"), TypeIdentifierConstants.STRING_URI, + "test1")); + + // as the roleFindermodule is removed due to analysis mode, add also the role + attributes.add( + new AuthoAttribute(Constants.SUBJECT_CAT, URI.create("subject-roles"), TypeIdentifierConstants.STRING_URI, + "Nurse")); + + RequestCtx request = XACMLDecoder.decodeRequestCtx( + new IdInfo("carol", null, null), + new URI("HealthRecord"), + "read", attributes); + + analyze(request); + } + + private void carol_read_noPatDep() throws SecurityError, URISyntaxException, ParsingException { + List attributes = new Vector(); + + //add some attribute directly to the request + attributes.add( + new AuthoAttribute( + Constants.SUBJECT_CAT, + URI.create("urn:subject:department"), + TypeIdentifierConstants.STRING_URI, + "test1")); + + attributes.add( + new AuthoAttribute( + Constants.ENVIRONMENT_CAT, + URI.create("urn:oasis:names:tc:xacml:1.0:environment:current-time"), + TypeIdentifierConstants.TIME_URI, + "12:00:00Z")); + + + // as the roleFindermodule is removed due to analysis mode, add also the role + attributes.add( + new AuthoAttribute(Constants.SUBJECT_CAT, URI.create("subject-roles"), TypeIdentifierConstants.STRING_URI, + "Nurse")); + + RequestCtx request = XACMLDecoder.decodeRequestCtx( + new IdInfo("carol", null, null), + new URI("HealthRecord"), + "read", attributes); + + analyze(request); + } + + private void carol_read_noPatDepTime() throws SecurityError, URISyntaxException, ParsingException { + List attributes = new Vector(); + + //add some attribute directly to the request + attributes.add( + new AuthoAttribute( + Constants.SUBJECT_CAT, + URI.create("urn:subject:department"), + TypeIdentifierConstants.STRING_URI, + "test1")); + + + // as the roleFindermodule is removed due to analysis mode, add also the role + attributes.add( + new AuthoAttribute(Constants.SUBJECT_CAT, URI.create("subject-roles"), TypeIdentifierConstants.STRING_URI, + "Nurse")); + + RequestCtx request = XACMLDecoder.decodeRequestCtx( + new IdInfo("carol", null, null), + new URI("HealthRecord"), + "read", attributes); + + analyze(request); + } + + private void analyze(RequestCtx request) throws ParsingException { + // print XACML request + String requestString = XACMLEncoder.encodeRequestCtx(request); + System.out.println("XACML REQUEST:\n" + requestString); + + // evaluate request + ResponseCtx resp = pdp.analyze(new AnalysisCtx(request, conf, + EvaluationIdAttribute.INVALID, eventHub)); + + // print XACML response + String responseString = XACMLEncoder.encodeResponseCtx(resp); + System.out.println("RESPONE:\n" + responseString); + + ReportGenerator repGen = new ReportGenerator(attrCapt.getKnownAttributes(), + eventHub.getEvalInfo().getTreeElemTree()); + + System.out.println("REPORT:::"); + System.out.println( repGen.reportMissingAttr()); + } + + + + + + + + + private void exec() throws SecurityError, URISyntaxException, ParsingException { + List attributes = new Vector(); + attributes.add( + new AuthoAttribute( + Constants.SUBJECT_CAT, + Constants.SUBJECT_ID, + TypeIdentifierConstants.STRING_URI, + "root")); + attributes.add( + new AuthoAttribute( + Constants.SUBJECT_CAT, + URI.create("urn:subject:department"), + TypeIdentifierConstants.STRING_URI, + "test1")); +// attributes.add( +// new AuthoAttribute( +// Constants.RESOURCE_CAT, +// URI.create("urn:patient:department"), +// TypeIdentifierConstants.STRING_URI, +// "test1")); + + attributes.add( + new AuthoAttribute( + Constants.SUBJECT_CAT, + URI.create("subject-roles"), + TypeIdentifierConstants.STRING_URI, + "Nurse")); + + //urn:nhs:becker:health-record MedicalRecord + RequestCtx request = XACMLDecoder.decodeRequestCtx(null, new URI("urn:nhs:becker:health-record"), "read", attributes); + + String requestString = XACMLEncoder.encodeRequestCtx(request); + System.out.println("REQUEST:\n" + requestString); + + ResponseCtx resp = pdp.analyze(new AnalysisCtx(request, conf, + EvaluationIdAttribute.INVALID, eventHub)); + + String responseString = XACMLEncoder.encodeResponseCtx(resp); + + //String responseString = pdp.evaluateXACML(requestString); + System.out.println("RESPONE:\n" + responseString); //XACMLEncoder.encodeResponseCtx(response)); + + ReportGenerator repGen = new ReportGenerator(attrCapt.getKnownAttributes(), + eventHub.getEvalInfo().getTreeElemTree()); + + System.out.println("REPORT:::"); + System.out.println( repGen.reportMissingAttr()); + + + } + + + public HolTestGen() { + + } + + public void testApp() + { + + } + + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/runEx/DenyPoliciesExample.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/runEx/DenyPoliciesExample.java new file mode 100644 index 0000000..555113b --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/runEx/DenyPoliciesExample.java @@ -0,0 +1,74 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runEx; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Properties; + +import org.apache.log4j.PropertyConfigurator; + +import eu.aniketos.securebpmn.xacml.pdp.PDPServer; +import eu.aniketos.securebpmn.xacml.pdpstate.PDPStateManagement; + +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; + +public class DenyPoliciesExample { + + private static PDPServer pdp; + private static PDPStateManagement pdpStateMgt; + + private static final String nurse = "nurse", + physician = "physician"; + + /** + * @param args + * @throws IOException + * @throws FileNotFoundException + * @throws ParsingException + * @throws UnknownIdentifierException + */ + public static void main(String[] args) throws FileNotFoundException, IOException, ParsingException, UnknownIdentifierException { + + Properties log4jProps = new Properties(); + log4jProps.load(new BufferedInputStream(new FileInputStream(new File("src/test/log4j.properties")))); + PropertyConfigurator.configure(log4jProps); + + init(); + setupSzenario(); + + } + + private static void setupSzenario() { + //pdpStateMgt.addRole("", ") + } + + + private static void init() throws ParsingException, UnknownIdentifierException { + ConfigurationStore config = new ConfigurationStore(new File("src/test/runningExample/pdp-config-denyPolicies.xml")); + + + pdp = new PDPServer(config.getDefaultPDPConfig()); + pdpStateMgt = PDPStateManagement.getInstance(); + } + + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/runEx/RunningExample.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/runEx/RunningExample.java new file mode 100644 index 0000000..0cd65ab --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/runEx/RunningExample.java @@ -0,0 +1,73 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.runEx; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.Properties; + +import org.apache.log4j.PropertyConfigurator; + +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; + +import eu.aniketos.securebpmn.xacml.pdp.PDPServer; +import eu.aniketos.securebpmn.xacml.pdpstate.PDPStateManagement; + +public class RunningExample { + + private static PDPServer pdp; + private static PDPStateManagement pdpStateMgt; + + private static final String nurse = "nurse", + physician = "physician"; + + /** + * @param args + * @throws IOException + * @throws FileNotFoundException + * @throws ParsingException + * @throws UnknownIdentifierException + */ + public static void main(String[] args) throws FileNotFoundException, IOException, ParsingException, UnknownIdentifierException { + + Properties log4jProps = new Properties(); + log4jProps.load(new BufferedInputStream(new FileInputStream(new File("src/test/log4j.properties")))); + PropertyConfigurator.configure(log4jProps); + + init(); + setupSzenario(); + + } + + private static void setupSzenario() { + //pdpStateMgt.addRole("", ") + } + + + private static void init() throws ParsingException, UnknownIdentifierException { + ConfigurationStore config = new ConfigurationStore(new File("src/test/runningExample/pdp-config.xml")); + + + pdp = new PDPServer(config.getDefaultPDPConfig()); + pdpStateMgt = PDPStateManagement.getInstance(); + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/state/PDPStateMgt.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/state/PDPStateMgt.java new file mode 100644 index 0000000..8df17d9 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/java/eu/aniketos/securebpmn/xacml/pdp/state/PDPStateMgt.java @@ -0,0 +1,215 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdp.state; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.net.URI; +import java.util.Date; +import java.util.List; +import java.util.Properties; +import java.util.Vector; + +import org.apache.log4j.PropertyConfigurator; + +import eu.aniketos.securebpmn.xacml.api.SecurityError; +import eu.aniketos.securebpmn.xacml.api.autho.AttributeIdentifier; +import eu.aniketos.securebpmn.xacml.api.autho.AuthoAttribute; +import eu.aniketos.securebpmn.xacml.api.autho.AuthoResult; +import eu.aniketos.securebpmn.xacml.api.idm.IdInfo; +import eu.aniketos.securebpmn.xacml.pdp.PDPServer; +import eu.aniketos.securebpmn.xacml.pdpstate.DemoPDPStateMgt; +import eu.aniketos.securebpmn.xacml.pdpstate.PDPStateManagement; + +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; + +public class PDPStateMgt { + + private static long start, setup; + + private static PDPServer pdp; + private static PDPStateManagement pdpStateMgt; + private static DemoPDPStateMgt demoMgt; + + private static final String ADMIN_USER = "admin@aniketos.eu", + ADMIN_ROLE = "admin"; + + private static AttributeIdentifier resource_subject = new AttributeIdentifier( + URI.create("urn:oasis:names:tc:xacml:3.0:attribute-category:resource"), + URI.create("http://www.w3.org/2001/XMLSchema#string"), + URI.create("urn:custom:resource:subject-id"), null); + + private static AttributeIdentifier resource_role = new AttributeIdentifier( + URI.create("urn:oasis:names:tc:xacml:3.0:attribute-category:resource"), + URI.create("http://www.w3.org/2001/XMLSchema#string"), + URI.create("urn:custom:resource:role"), null); + + /** + * @param args + * @throws IOException + * @throws FileNotFoundException + * @throws UnknownIdentifierException + * @throws ParsingException + */ + public static void main(String[] args) throws FileNotFoundException, IOException, ParsingException, UnknownIdentifierException { + start = new Date().getTime(); + Properties log4jProps = new Properties(); + log4jProps.load(new BufferedInputStream(new FileInputStream(new File("src/test/log4j.properties")))); + PropertyConfigurator.configure(log4jProps); + + init(); + demoSetup(); + setup = new Date().getTime(); + + System.out.println("STARTUP TIME: " + ( setup - start)); + + test1(); + long test1 = new Date().getTime(); + + System.out.println("TEST TIME: " + (test1 - setup)); + +// +// test2(); +// long test2 = new Date().getTime(); +// +// System.out.println("TEST TIME2: " + (test2 - test1)); + + List roles = demoMgt.getRoles("helmut@aniketos.eu"); + System.out.print("roles for helmut@aniketos.eu: "); + for(String s : roles ) { + System.out.print(s +", "); + } + System.out.println(""); + } + + private static void init() throws ParsingException, UnknownIdentifierException { + //ConfigurationStore config = new ConfigurationStore(new File("src/test/runningExample/pdp-config.xml")); + ConfigurationStore config = new ConfigurationStore(new File("src/test/runningExample/pdp-config-denyPolicies.xml")); + + + pdp = new PDPServer(config.getDefaultPDPConfig()); + + + pdpStateMgt = PDPStateManagement.getInstance(); + demoMgt = new DemoPDPStateMgt(); + + } + + private static void demoSetup() { + demoMgt.addRole(ADMIN_USER, ADMIN_ROLE); + + List roles = demoMgt.getRoles(ADMIN_USER); + System.out.print("### TEST ### roles for " + ADMIN_USER + ": "); + for(String s : roles ) { + System.out.print(s +", "); + } + System.out.println(""); + + demoMgt.addActivePolicy("preg"); + List polices = demoMgt.getActivePolicies(); + System.out.print("### TEST ### active policies: "); + for(String s : polices ) { + System.out.print(s +", "); + } + System.out.println(""); + } + + + private static void test1() { + + List roles = demoMgt.getRoles("helmut@aniketos.eu"); + System.out.print("### TEST ### roles for helmut@aniketos.eu: "); + for(String s : roles ) { + System.out.print(s +", "); + } + System.out.println(""); + + List attributes = new Vector(); + attributes.add(new AuthoAttribute(resource_subject, "helmut@aniketos.eu")); + attributes.add(new AuthoAttribute(resource_role, "employee")); + + try { + AuthoResult res = pdp.evaluate(new IdInfo(ADMIN_USER), "urn:runEx:role:assignment", "add", attributes); + System.out.println("result: " + res.toString()); + + long evalId = Long.parseLong(res.getObligations().get(0).getParameters().iterator().next().getValue()); + System.out.println("evalId: " + evalId); + +// try { +// Thread.sleep(1000); +// } catch (InterruptedException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } + + pdp.notifyStateChange(evalId); + } catch (SecurityError e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + roles = demoMgt.getRoles("helmut@aniketos.eu"); + System.out.print("### TEST ### roles for helmut@aniketos.eu: "); + for(String s : roles ) { + System.out.print(s +", "); + } + System.out.println(""); + + } + + + private static void test2() { + + List attributes = new Vector(); + attributes.add(new AuthoAttribute(resource_subject, "helmut@aniketos.eu")); + attributes.add(new AuthoAttribute(resource_role, "anotherRole")); + + try { + AuthoResult res = pdp.evaluate(new IdInfo(ADMIN_USER), "urn:runEx:role:assignment", "add", attributes); + System.out.println("result: " + res.toString()); + + long evalId = Long.parseLong(res.getObligations().get(0).getParameters().iterator().next().getValue()); + System.out.println("evalId: " + evalId); + +// try { +// Thread.sleep(1000); +// } catch (InterruptedException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } + + pdp.notifyStateChange(evalId); + } catch (SecurityError e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + +// List roles = demoMgt.getRoles("helmut@aniketos.eu"); +// System.out.print("roles for helmut@aniketos.eu: "); +// for(String s : roles ) { +// System.out.print(s +", "); +// } +// System.out.println(""); + + } + + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/log4j.properties b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/log4j.properties new file mode 100644 index 0000000..93cfe2e --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/log4j.properties @@ -0,0 +1,19 @@ +log4j.rootLogger=INFO, console + +log4j.appender.logfile=org.apache.log4j.FileAppender +log4j.appender.logfile.layout=org.apache.log4j.PatternLayout +log4j.appender.logfile.layout.ConversionPattern=%d [%t] %-5p %c - %m%n +log4j.appender.logfile.File=${catalina.base}/logs/pdp.log + +log4j.appender.console=org.apache.log4j.ConsoleAppender +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern=%-5p %c - %m%n + +# %d [%t] + +log4j.logger.eu.aniketos.securebpmn.xacml=DEBUG +log4j.logger.com.sun.xacml=DEBUG + +log4j.logger.org.apache.commons.httpclient.HttpMethodDirector=WARN + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/pdpState-config.xml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/pdpState-config.xml new file mode 100644 index 0000000..5c3cb3c --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/pdpState-config.xml @@ -0,0 +1,32 @@ + + + + + + + + + conf:useLines:true + folder:healthcare + + + + + + + + + + + + + + + + eu.aniketos.securebpmn.xacml.log.LogServer + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/policy1.xacml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/policy1.xacml new file mode 100644 index 0000000..0b3a68c --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/policy1.xacml @@ -0,0 +1,82 @@ + + + + + + + MedicalRecord + + + + + + + + + + + + + + + read + + + + + + + + + + + 18:00:00Z + 06:00:00Z + + + + + + + + + + + read + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/policy2.xacml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/policy2.xacml new file mode 100644 index 0000000..525b333 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/policy2.xacml @@ -0,0 +1,188 @@ + + + + + + + MedicalRecord + + + + + + + + + + + + + + + + read + + + + + + + + + + + + + 06:00:00Z + 18:00:00Z + + + + + + + + + + + read + + + + + + + + + + + + 1 + + + + + + 1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + read + + + + + + + + + + + + + + + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/policy3.xacml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/policy3.xacml new file mode 100644 index 0000000..7f8f9c8 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/policy3.xacml @@ -0,0 +1,94 @@ + + + + + + + MedicalRecord + + + + + + + + + + + + Nurse + + + + + + + + + + + + + + 18:00:00Z + 06:00:00Z + + + + + + + + + + + read + + + + + + + + + + + + + + + + + + + + + Doctor + + + + + + + + + + + + + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/productive-config.xml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/productive-config.xml new file mode 100644 index 0000000..0f6f813 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/productive-config.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + conf:useLines:true + file:nhs-becker.xacml + file:nhs-becker-p_reg.xacml + file:nhs-becker-healthrecord.xacml + + + + + + + + + + + + + + + + + eu.aniketos.securebpmn.xacml.log.LogServer + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/roles.config b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/roles.config new file mode 100644 index 0000000..b1b32f9 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/roles.config @@ -0,0 +1,5 @@ +burli:Role1;MasterGuru;UseCaseCaptain +maxi:fuzzi;Ruzzi;bulli +root:Role1;MasterGuru;Nurse;asdfburli:Role1;MasterGuru;UseCaseCaptain +maxi:fuzzi;Ruzzi;bulli + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/test1.xacml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/test1.xacml new file mode 100644 index 0000000..7636b0b --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/test1.xacml @@ -0,0 +1,116 @@ + + + + + + + + + + breakglass.prototype.MedicalRecord + + + + + + + + + + + Default policy (no exception level) for MedicalRecord + + + + + + + + + + + + + + + + + + + UserRole + + + + + + + + breakglass.prototype.MedicalRecord + + + + + + + + read + + + + + + update + + + + + + delete + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/test2.xacml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/test2.xacml new file mode 100644 index 0000000..9863d2e --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/test2.xacml @@ -0,0 +1,220 @@ + + + + + + + + + + breakglass.prototype.MedicalRecord + + + + + + + + + + + Default policy (no exception level) for MedicalRecord + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +false1 + + + + + + +false2 + + + + + + + + + + + + + + + + + helmut + + + + + + + + update + + + + + + read + + + + + + delete + + + + + + + + + + + + + + + + + + + + + update + + + + + + read + + + + + + delete + + + + + + + + + + + + + + + + + + + + + + helmut + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/test3.xacml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/test3.xacml new file mode 100644 index 0000000..871963a --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/test3.xacml @@ -0,0 +1,214 @@ + + + + + + + + + + MedicalRecord + + + + + + + + + + + Default policy (no exception level) for MedicalRecord + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +false1 + + + + + + +false2 + + + + + + + + + + + + + + + + + helmut + + + + + + + + update + + + + + + read + + + + + + delete + + + + + + + + + + + + + + + + + + + + + update + + + + + + read + + + + + + delete + + + + + + + + + + + + + + + + + + + + + + helmut + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/test4.xacml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/test4.xacml new file mode 100644 index 0000000..edc702c --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdp/src/test/test4.xacml @@ -0,0 +1,114 @@ + + + + + + + breakglass.prototype.MedicalRecord + + + + + + + + Default policy (no exception level) for MedicalRecord + + + + + + + + + + + + + + update + + + + + + read + + + + + + delete + + + + + + + + + + + + + 00:00:00Z + 23:59:59Z + + + + + + + + + + + + + + + helmut + + + + + + + + + + + + + + + + + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/pom.xml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/pom.xml new file mode 100644 index 0000000..8dd9ae5 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/pom.xml @@ -0,0 +1,71 @@ + + + 4.0.0 + + eu.aniketos.securebpmn.xacml + eu.aniketos.securebpmn.xacml.parent + 1.0 + ../eu.aniketos.securebpmn.xacml.parent/pom.xml + + eu.aniketos.securebpmn.xacml.pdpstate + 0.1 + jar + SecureBPMN XACML - PDP State + http://maven.apache.org + + UTF-8 + + + ${artifactId} + + + + 2.3.2 + org.apache.maven.plugins + maven-compiler-plugin + + 1.5 + 1.5 + + + + + + + junit + junit + [4.8,) + test + + + log4j + log4j + [1.2,) + + + org.hibernate + hibernate-core + 3.5.4-Final + + + hsqldb + hsqldb + [1,) + + + eu.aniketos.securebpmn.xacml + eu.aniketos.securebpmn.xacml.api + 0.1 + + + eu.aniketos.securebpmn.xacml + eu.aniketos.securebpmn.xacml.support + 1.0 + + + eu.aniketos.securebpmn.xacml + com.sun.xacml + 0.1 + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/DemoPDPStateMgt.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/DemoPDPStateMgt.java new file mode 100644 index 0000000..b556700 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/DemoPDPStateMgt.java @@ -0,0 +1,168 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdpstate; + +import java.util.List; +import java.util.Map; +import java.util.Vector; + +import org.apache.log4j.Logger; + +import eu.aniketos.securebpmn.xacml.api.autho.AuthoAttribute; +import eu.aniketos.securebpmn.xacml.pdpstate.db.AttributeDBIdentifier; + +/** + * + * This class allows to modify the PDP State directly, i.e., + * without creating an access control request, getting an + * urn:custom:notifyPDPState obligation and sending it to + * the PDPServer.
      + * It is intended as class for setting demos, but can also be used + * to implement simple scenarios where, e.g., the assignment of roles + * is not considered and not policies are therefore available + * + */ +public class DemoPDPStateMgt { + + /* + * to modify the pdpState; + */ + private PDPState pdpState; + private Map dependencies; + + private static final String ROLEASSIGNMENT = "urn:runEx:role:assignment"; + private AttributeDBIdentifier roleIdentifier, role_dep1; + + private static final String POLICIES = "urn:runEx:activePolicies"; + private AttributeDBIdentifier policyIdentifier; + + private static DemoPDPStateMgt instance; + + private static final Logger logger = Logger.getLogger(DemoPDPStateMgt.class); + + + public static DemoPDPStateMgt getInstance() { + return instance; + } + + public DemoPDPStateMgt() { + instance = this; + dependencies = PDPStateManagement.getInstance().getDependencies(); + pdpState = PDPState.getInstance(); + + Dependency roleAssignment = dependencies.get(ROLEASSIGNMENT); + if ( roleAssignment == null ) { + logger.error("Could not find role assignment definition in the " + + "configuration of PDPStateManagement; you have to define " + + "the role assignment with key " + ROLEASSIGNMENT + " in " + + "the configuration file " + PDPStateManagement.CONFFILE_NAME); + throw new RuntimeException("Missing configuration for dependency " + ROLEASSIGNMENT); + } else { + roleIdentifier = roleAssignment.getAttributeIdentifier(); + role_dep1 = roleAssignment.getDependingAttributeIdentifier(0); + } + + Dependency policiesAssignment = dependencies.get(POLICIES); + if ( policiesAssignment == null ) { + logger.error("Could not find policy assignment definition in the " + + "configuration of PDPStateManagement; you have to define " + + "the role assignment with key " + POLICIES + " in " + + "the configuration file " + PDPStateManagement.CONFFILE_NAME); + throw new RuntimeException("Missing configuration for dependency " + POLICIES); + } else { + policyIdentifier = policiesAssignment.getAttributeIdentifier(); + } + + } + + + public List getRoles(String subjectId) { + List contextAttrs = new Vector(); + contextAttrs.add(new AuthoAttribute(role_dep1, subjectId)); + return pdpState.getAttribute(roleIdentifier, contextAttrs); + } + + public void addRole(String subjectId, String role) { + List contextAttrs = new Vector(); + contextAttrs.add(new AuthoAttribute(role_dep1, subjectId)); + AuthoAttribute roleAttr = new AuthoAttribute(roleIdentifier, role); + // use default dates assigned by PDPState: now for from, ever for to + pdpState.addAssignment(roleAttr, null, null, contextAttrs); + } + + public void removeRole(String subjectId, String role) { + List contextAttrs = new Vector(); + contextAttrs.add(new AuthoAttribute(role_dep1, subjectId)); + AuthoAttribute roleAttr = new AuthoAttribute(roleIdentifier, role); + + pdpState.endAssignment(roleAttr, null, contextAttrs); + } + + public List getActivePolicies() { + return pdpState.getAttribute(policyIdentifier, null); + } + + public void addActivePolicy(String policyId) { + AuthoAttribute policyAttr = new AuthoAttribute(policyIdentifier, policyId); + pdpState.addAssignment(policyAttr, null, null, null); + } + + public void removeActivePolicy(String policyId) { + AuthoAttribute policyAttr = new AuthoAttribute(policyIdentifier, policyId); + pdpState.endAssignment(policyAttr, null, null); + } + +// public List getRoles(String subjectId) { +// List contextAttrs = new Vector(); +// contextAttrs.add(new AuthoAttribute(role_dep1, subjectId)); +// return pdpState.getAttribute(roleIdentifier, contextAttrs); +// } + +// public List getQualifications(String subjectId) { +// //TODO +// return null; +//} +// +//public void addQualifications(String subjectId, String qualification) { +// //TODO qualification +//} +// +//public void removeQualification(String subjectId, String qualification) { +// //TODO +//} +// +//public void createResource(URI resource, String creator) { +// +//} +// +//public String getCreator(URI resource) { +// return null; +//} +// +//public List getDepartments(String subjectId) { +// //TODO +// return null; +//} +// +//public void addDepartment(String subjectId, String department) { +// //TODO qualification +//} +// +//public void removeDepartment(String subjectId, String department) { +// //TODO +//} + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/Dependency.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/Dependency.java new file mode 100644 index 0000000..8215ef4 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/Dependency.java @@ -0,0 +1,327 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdpstate; + +import java.io.BufferedReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.StringTokenizer; +import java.util.Vector; + +import org.apache.log4j.Logger; + +import eu.aniketos.securebpmn.xacml.api.SecurityError; +import eu.aniketos.securebpmn.xacml.api.ErrorType; +import eu.aniketos.securebpmn.xacml.api.ReasonType; +import eu.aniketos.securebpmn.xacml.api.autho.AttributeIdentifier; +import eu.aniketos.securebpmn.xacml.api.autho.AuthoAttribute; +import eu.aniketos.securebpmn.xacml.api.autho.DesignatorAttribute; +import eu.aniketos.securebpmn.xacml.api.log.AccessControlRequest; +import eu.aniketos.securebpmn.xacml.pdpstate.db.AttributeDBIdentifier; +import eu.aniketos.securebpmn.xacml.pdpstate.db.AttributeType; +import eu.aniketos.securebpmn.xacml.pdpstate.db.ContextAttribute; +import eu.aniketos.securebpmn.xacml.pdpstate.db.HibernateUtil; + +/** + * + * This class stores the types of known assignments and how to retrieve + * the required information from an XACML request. For example, consider a role + * assignment. The configuration might look like this:
      + * dependency:runEx:role:assignment
      + * urn:custom:subject:role -> urn:oasis:names:tc:xacml:1.0:subject:subject-id
      + * urn:custom:subject:role -> attribute:urn:custom:resource:role
      + * urn:oasis:names:tc:xacml:1.0:subject:subject-id -> urn:custom:resource:subject-id
      + *
      + * This config says: + *
        + *
      • define a dependency for the resource (in the XACML policy) runEx:role:assignment
      • + *
      • to retrieve a role, one needs the subject-id (those are keys + * which have to be defined in the configuration file first)
      • + *
      • the attributes for role (urn:custom:subject:role) can be retrieved by getting + * all attribute:urn:custom:resource:role attributes from the XACML request
      • + *
      • the attribute for subject-Id (urn:oasis:names:tc:xacml:1.0:subject:subject-id) can be retrieved + * by getting all urn:custom:resource:subject-id attribues from the XACML request
      • + *
      + * + */ +public class Dependency { + + /** + * resource for which this assignment is valid (as defined in the configuration file) + * e.g., urn:role:assignment + */ + private String resourceKey; + + + private AttributeType type; + + /** + * all pdpStateDependencies have to be retrieved from an XACML request; + * this map defines which attribute has to be retrieved from the XACML request (value) + * and assigned to which attribute stored in the db (key). + * + * Note that the attributes in the XACML have to be different, e.g., when + * assigning a role, one cannot use the role attribute to define the to be assigned roles, + * i.e., the roles have to treated as resource; so is the subject-id for the role assignment. + */ + private Map requestDependencies; + + + private static Logger logger = Logger.getLogger(Dependency.class); + + + public Dependency(String key, AttributeType type, + Map requestDependencies) { + this.resourceKey = key; + this.type = type; + this.requestDependencies = requestDependencies; + } + + + public List getDependingAttributes() { + return type.getCtxTypes(); + } + + public AttributeDBIdentifier getDependingAttributeIdentifier(int index) { + return type.getCtxTypes().get(index).getAttrId(); + } + + public AttributeDBIdentifier getAttributeIdentifier() { + return type.getAttrType(); + } + + public String getResourceKey() { + return resourceKey; + } + + /** + * creates a new Assignment based on the configuration file and assures that + * there are no conflicting definitions within the database. + * + * @param resource + * @param reader + * @param attributes + * @return + * @throws IOException + * @throws SyntaxError + */ + public static Dependency readAssignment(String resource, BufferedReader reader, + Map attributes, HibernateUtil dbUtil) throws IOException, SyntaxError { + // get the dependency definition line, e.g., urn:custom:subject:role -> urn:oasis:names:tc:xacml:1.0:subject:subject-id + String dependency = reader.readLine(); + int m = dependency.indexOf("->"); + if ( m == -1 ) { + throw new SyntaxError("Missing assignment -> "); + } + // get the attribute for which the dependency is defined - key points to a attribute: definition + String key = dependency.substring(0, m).trim(); + AttributeDBIdentifier dbKey = attributes.get(key); + if ( dbKey == null ) { + logger.error("Creating Dependency " + resource +", but Attribute with key " + key + " is not defined so far"); + throw new SyntaxError("Attribute with key " + key + " is not defined so far"); + } + if (logger.isDebugEnabled() ) { + logger.debug("Creating Dependency " + resource + " for attribute " + key + " -> " + dbKey.toString()); + } + + // read all dependencies for this attribute and create or get AttributeType based on those definitions + List dependencies = new Vector(); //bullshit, but cannot cast from List to List + // also keep track of all defined dependencies, as they are needed afterwards + List dependencyKeys = new Vector(); + dependencyKeys.add(key); + boolean noDependency = false; + StringTokenizer tokenizer = new StringTokenizer(dependency.substring(m + 2), ","); + while (tokenizer.hasMoreTokens()) { + String token = tokenizer.nextToken().trim(); + if ( ! (token.length() == 0) ) { + if ( dependencies.size() == 0 && "null".equals(token) ) { + // some attributes may not depend on any other attribute, but they have to define this, i.e., write attributeKey -> null + noDependency = true; + } else { + AttributeDBIdentifier dependent = attributes.get(token); + if ( dependent == null ) { + logger.error("Creating Dependency " + resource +", but Attribute with key " + dependent + " is not defined so far"); + throw new SyntaxError("Attribute with key " + dependent + " is not defined so far"); + } else { +// dependencies_delete.add(dependent); + dependencies.add(dependent); + dependencyKeys.add(token); + if ( logger.isDebugEnabled() ) { + logger.debug("Found dependency to attribute " + token + ", referencing to " + dependent.toString()); + } + + } + } + } + } + if ( dependencies.size() == 0 && ! noDependency) { + logger.error("For dependency " + resource + " (attribute " + key + " no dependencies are defined"); + throw new SyntaxError("No dependency is defined"); + } + + AttributeType type = dbUtil.addAttributeType(dbKey, dependencies); + if ( type == null ) { + logger.warn("Could not retrieve AttributeType for configuration of assignment " + dbKey + ": different definition already exists"); + throw new SyntaxError("Invalid configuration: Different definition already exists"); + } else if (logger.isDebugEnabled() ) { + logger.debug("Got AttributeType with id " + type.getId() + " for dependency:" + resource); + } + /* ok, we got the AttributeType definition for this dependency, now + * we have to get the information which element from a XACML request has to be retrieved + * to update the PDPState accordingly + */ + Map requestDependencies = new HashMap(); + for ( String dep : dependencyKeys ) { + String confLine = readValueLine(reader); + m = confLine.indexOf("->"); + String dbAttr, requAttr; + dbAttr = confLine.substring(0, m).trim(); + requAttr = confLine.substring(m + 2, confLine.length()).trim(); + + if ( ! dbAttr.equals(dep)) { + throw new SyntaxError("Invalid assignment: expected assignment for " + dep + " (line: " + confLine + ")"); + } else { + AttributeDBIdentifier requDBAttr = attributes.get(requAttr); + if ( requDBAttr == null ) { + throw new SyntaxError("Attribute with key " + requAttr + " is not defined so far"); + } else { + requestDependencies.put(attributes.get(dbAttr), requDBAttr); + if ( logger.isDebugEnabled() ) { + logger.debug("XACML request attr " + requAttr + " is mapped to " + dbAttr + " (" + requDBAttr + " -> " + attributes.get(dbAttr) + ")"); + } + } + } + } + return new Dependency(resource, type, requestDependencies); + } + + private static String readValueLine(BufferedReader reader) throws IOException, SyntaxError { + String line = reader.readLine().trim(); + if ( line.startsWith("#") ) { + return readValueLine(reader); + } else { + return line; + } + } + + private List getValues(AccessControlRequest request, AttributeDBIdentifier attr) { + List values = new Vector(); + + for ( DesignatorAttribute designAttr : request.getDesignatorAttributes()) { + if ( designAttr.getAttrId().equals(attr)) { + values.addAll(designAttr.getValues()); + // break; // should be ok, as only one entry for one attr should be there.. anyhow + } + } + for ( AuthoAttribute authoAttr : request.getAttributes()) { + if ( authoAttr.getAttributeIdentifier().equals(attr)) { + values.add(authoAttr.getValue()); + } + } + return values; + } + + + /** + * This functions receives an executed and recorded AccessControlRequest and + * reads all needed values from the xacml request and stores the according + * state changes to the PDPState + * @param request + * @param pdpState + * @throws SecurityError + */ + public void writeStateChange(AccessControlRequest request, PDPState pdpState) throws SecurityError { + + // get the values we should assign from the request + List assignValues = getValues(request, requestDependencies.get(type.getAttrType())); + if ( assignValues.size() == 0 ) { + logger.error("Nothing found in the request " + request.getEvaluationId().longValue()); + throw new SecurityError(ErrorType.CONFIGURATION_ERROR, ReasonType.PDE_ENGINE_ERROR, + "Request " + request.getEvaluationId() + " did not contain the required information"); + } + + if ( logger.isDebugEnabled() ) { + StringBuffer message = new StringBuffer("Found " + assignValues.size() + " value(s) ("); + for (String value : assignValues ) { + message.append(value + ", "); + } + message.append(") to write to the PDP state for " + this.resourceKey + " (" + this.type.getCtxTypes().size() + " depending ctx Attribute(s))"); + logger.debug(message.toString()); + } + + // depending on the number of context attributes, we have to retrieve those values from the request + // and create the according assignment for the PDP state + if ( type.getCtxTypes().size() == 0 ) { + for ( String value : assignValues ) { + //pdpState.addAssignment(type, value, null, null, null); + pdpState.addAssignment(new AuthoAttribute(type.getAttrType(), value), null, null, null); + } + logger.info("Added " + assignValues.size() + " assignments for " + type.getAttrType() + " to the PDPState"); + } else if ( type.getCtxTypes().size() == 1 ) { + // we have the AttributeType which tells us how much context Attributes we need; + // from this, we can get the attribute identifier which identifies the attributes in the xacml request + AttributeDBIdentifier ctxAttrType = requestDependencies.get(type.getCtxTypes().get(0).getAttrId()); + // get the according values + List ctxValues = getValues(request, ctxAttrType); + // if there are no values, there is something wrong; terminate + if ( ctxValues == null || ctxValues.size() == 0 ) { + logger.error("Could not find values for contextAttribute " + ctxAttrType + " in the request"); + throw new SecurityError(ErrorType.CONFIGURATION_ERROR, ReasonType.PDE_ENGINE_ERROR, + "Request " + request.getEvaluationId() + " did not contain the required information"); + } else if ( logger.isDebugEnabled() ) { + StringBuffer message = new StringBuffer("Found " + ctxValues.size() + " value(s) ("); + for (String value : ctxValues ) { + message.append(value + ", "); + } + message.append(") for " + ctxAttrType.toString()); + logger.debug(message.toString()); + } + + for ( String value: assignValues ) { + AuthoAttribute valueAttr = new AuthoAttribute(type.getAttrType(), value); + for ( String ctxValue : ctxValues ) { + List ctxAttr = new Vector(); + ctxAttr.add(new AuthoAttribute(type.getCtxTypes().get(0).getAttrId(), ctxValue)); + pdpState.addAssignment(valueAttr, null, null, ctxAttr); + } + } + logger.info("Added " + (assignValues.size()*ctxValues.size()) + " assignments for " + type.getAttrType() + " to the PDPState"); + } else { + // here, we do for now only allow one value for every context attribute + List ctxAttrs = new Vector(); + List ctxValues; + + for ( ContextAttribute ctxAttr : type.getCtxTypes() ) { + ctxValues = getValues(request, ctxAttr.getAttrId()); + if ( ctxValues.size() != 1) { + logger.error("Expected 1 value for " + ctxAttr.getAttrId() + " in request " + + request.getEvaluationId() + ", but found " + ctxValues.size()); + throw new SecurityError(ErrorType.CONFIGURATION_ERROR, ReasonType.PDE_ENGINE_ERROR, + "Request " + request.getEvaluationId() + " did not contain the required information"); + } else { + ctxAttrs.add(new AuthoAttribute(ctxAttr.getAttrId(), ctxValues.get(0))); + } + } + + for ( String value : assignValues ) { + pdpState.addAssignment(new AuthoAttribute(type.getAttrType(), value), null, null, ctxAttrs); + } + logger.info("Added " + assignValues.size() + " assignments for " + type.getAttrType() + " to the PDPState"); + } + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/InvalidAssignmentException.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/InvalidAssignmentException.java new file mode 100644 index 0000000..b83f63b --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/InvalidAssignmentException.java @@ -0,0 +1,51 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdpstate; + +public class InvalidAssignmentException extends RuntimeException { + + private static final long serialVersionUID = -387842157062192483L; + + public enum Reason { + OVERLAPPING_ASSIGNMENT, //there already exists an assignment + INVALID_DATE_NO_TIMEFRAME, //the dates do not spawn a time frame, i.e, from is after to + INVALID_DATE_MODIFICATION_OF_PAST, //it is not allowed to do assignments in the past + NO_ASSIGNMENT_AVAILABLE, // for the defined contraints (type, time) no such assignment is available + INVALID_STATE // worst case - invalid state... + } + + private Reason reason; + private String message; + + public InvalidAssignmentException(Reason reason) { + this.reason = reason; + } + + public InvalidAssignmentException(Reason reason, String message) { + this.reason = reason; + this.message = message; + } + + public Reason getReason() { + return reason; + } + + public String getMessage() { + //TODO generate default message according to reason + return message; + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/PDPState.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/PDPState.java new file mode 100644 index 0000000..e99b5b6 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/PDPState.java @@ -0,0 +1,490 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdpstate; + +import java.io.BufferedInputStream; +import java.io.File; +import java.security.InvalidParameterException; +import java.sql.Timestamp; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Vector; + +import javax.xml.parsers.DocumentBuilderFactory; + +import org.apache.log4j.Logger; +import org.hibernate.Query; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; +import org.hibernate.cfg.Configuration; +import org.w3c.dom.Document; + +import eu.aniketos.securebpmn.xacml.api.autho.AttributeIdentifier; +import eu.aniketos.securebpmn.xacml.api.autho.AuthoAttribute; +import eu.aniketos.securebpmn.xacml.pdpstate.InvalidAssignmentException.Reason; +import eu.aniketos.securebpmn.xacml.pdpstate.db.AttributeAssignment; +import eu.aniketos.securebpmn.xacml.pdpstate.db.AttributeType; +import eu.aniketos.securebpmn.xacml.pdpstate.db.ContextAttribute; +import eu.aniketos.securebpmn.xacml.pdpstate.db.ContextAttributeAssignment; +import eu.aniketos.securebpmn.xacml.pdpstate.db.HibernateUtil; + +/** + * + * Manages the state of the PDP as it can be retrieved from the PDPStateModule. + * + * Changes have to be done through this class ans especially through the HibernateUtil, + * as here some caching is implemented. Bypassing this caching mechanism will result in + * strange errors. + * + */ +public class PDPState { + + private static PDPState instance; + public static final String CONFFILE_NAME = "hibernate.pdpState.cfg.xml"; + + private SessionFactory factory; + private HibernateUtil hibernateUtil; + + private static final Logger logger = Logger.getLogger(PDPState.class); + + private static final String ATTRTYPE = "attrType", + VALIDAT = "validAt", + VALIDFROM = "validFrom", + VALIDTO = "validTo", + VALUE = "value", + CTXATTRTYP0 = "ctxAttrTypeNull", + CTXATTR0 = "ctxAttrNull", + CTXATTRTYP1 = "ctxAttrTypeOne", + CTXATTR1 = "ctxAttrOne"; + + public static PDPState getInstance() { + if ( instance == null ) { + createInstance(); + } + return instance; + } + + private static synchronized void createInstance() { + if ( instance == null ) { + instance = new PDPState(); + } + } + + private PDPState() { + logger.debug("Starting PDPState Server: Creating SessionFactory"); + factory = buildSessionFactory(); + factory.openSession(); + + logger.debug("Creating HibernateUtil"); + hibernateUtil = HibernateUtil.createHibernateUtil(factory); + + } + + private SessionFactory buildSessionFactory() { + try { + + File confFile = new File(CONFFILE_NAME); + if ( ! confFile.exists() ) { + // try with conf before... + confFile = new File("conf/" +CONFFILE_NAME); + } + if ( ! confFile.exists() ) { + // try from mvn default test location + confFile = new File("src/test/resources/" +CONFFILE_NAME); + } + + if ( confFile.exists()) { + logger.debug("Reading PDPState hibernate configuration from " + confFile.getAbsolutePath()); + return new Configuration().configure(confFile).buildSessionFactory(); + } + else { + logger.warn("Reading PDPState hibernate configuration from jar; You might define a more accurate " + CONFFILE_NAME); + BufferedInputStream bIs = new BufferedInputStream(this.getClass().getResourceAsStream( "/" + CONFFILE_NAME)); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setValidating(false); // do not validate with DTD (and, therefore, do not die offline with an unkown host exception + factory.setFeature("http://xml.org/sax/features/namespaces", false); + factory.setFeature("http://xml.org/sax/features/validation", false); + factory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false); + factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); + Document confDoc = factory.newDocumentBuilder().parse(bIs).getDocumentElement().getOwnerDocument(); + return new Configuration().configure(confDoc).buildSessionFactory(); + } + } + catch (Throwable ex) { + ex.printStackTrace(); + logger.error("Initial SessionFactory creation failed." + ex.getClass().getName() + " - " + ex.getMessage()); + throw new ExceptionInInitializerError(ex); + } + } + + + public HibernateUtil getHibernateUtil() { + return this.hibernateUtil; + } + + /** + * adds a new attribute type. values in AuthoAttribute are ignored + * @param attributeId + * @param contextInformation + */ + public AttributeType addAttributeType(AuthoAttribute attribute, List contextAttributes) { + + List contextIds = null; + if ( contextAttributes != null && contextAttributes.size() > 0 ) { + contextIds = new Vector(); + for (AuthoAttribute attr : contextAttributes ) { + contextIds.add(attr.getAttributeIdentifier()); + } + } + return hibernateUtil.addAttributeType(attribute.getAttributeIdentifier(), contextIds); + } + + public List getAttribute(AttributeIdentifier attrId, List contextAttrValues) { + return getAttribute(attrId, contextAttrValues, new java.util.Date()); + } + + public List getAttribute(AttributeIdentifier attrId, List contextAttrValues, Date validAt) { + return getAttribute(attrId, contextAttrValues, new Timestamp(validAt.getTime())); + } + + + public List getAttribute(AttributeIdentifier attrId, List contextAttrValues, Timestamp validAt) { + AttributeType attrType = hibernateUtil.getAttributeType(attrId); + List contextDBAttrs = transformCtxAttr(attrType, contextAttrValues); + return getAttribute(attrType, contextDBAttrs, validAt); + } + + /** + * WARNING: This function performs NO sanity checks, thus, you may get weird behavior + * if you provide unchecked and inconsistent parameters. + *
      + * + * @param attrType + * @param contextDBAttrs + * @param validAt + * @return + */ + public List getAttribute(AttributeType attrType, List contextDBAttrs) { + return getAttribute(attrType, contextDBAttrs, new Timestamp(new java.util.Date().getTime())); + } + + + + /** + * WARNING: This function performs NO sanity checks, thus, you may get weird behavior + * if you provide unchecked and inconsistent parameters. + *
      + * + * @param attrType + * @param contextDBAttrs + * @param validAt + * @return + */ + @SuppressWarnings("unchecked") // needed for List list = query.list(); + public List getAttribute(AttributeType attrType, + List contextDBAttrs, Timestamp validAt) { + + Session session = factory.getCurrentSession(); + Transaction t = session.beginTransaction(); + Query query = null; + + //if ( attrType.getCtxTypes().size() == 0 ) { + if ( contextDBAttrs == null || contextDBAttrs.size() == 0 ) { + //no context attributes are required, easy case! + query = session.getNamedQuery("getAttribute0"); + } else if ( contextDBAttrs.size() == 1 ) { + //only one context attribute is required + query = session.getNamedQuery("getAttribute1"); + query.setParameter(CTXATTRTYP0, contextDBAttrs.get(0).getCtxAttribute()); + query.setParameter(CTXATTR0, contextDBAttrs.get(0).getValue()); + } else if ( contextDBAttrs.size() == 2 ) { + query = session.getNamedQuery("getAttribute2"); + query.setParameter(CTXATTRTYP0, contextDBAttrs.get(0).getCtxAttribute()); + query.setParameter(CTXATTR0, contextDBAttrs.get(0).getValue()); + query.setParameter(CTXATTRTYP1, contextDBAttrs.get(1).getCtxAttribute()); + query.setParameter(CTXATTR1, contextDBAttrs.get(1).getValue()); + } else { + throw new RuntimeException("Only two constraining attributes are supported"); + } + query.setParameter(ATTRTYPE, attrType); + query.setParameter(VALIDAT, validAt); + + List list = query.list(); + t.commit(); + return list; + } + + public List getAssignmentIds(AttributeIdentifier attrId, String value, + List contextAttrValues, + Date validFrom, Date validTo) { + return getAssignmentIds(attrId, value, contextAttrValues, new Date(validFrom.getTime()), new Date(validTo.getTime())); + } + + + public List getAssignmentIds(AttributeIdentifier attrId, String value, + List contextAttrValues, Timestamp validFrom, Timestamp validTo) { + AttributeType attrType = hibernateUtil.getAttributeType(attrId); + List contextDBAttrs = transformCtxAttr(attrType, contextAttrValues); + return getAssignmentIds(attrType, value, contextDBAttrs, validFrom, validTo); + } + + @SuppressWarnings("unchecked") + public List getAssignmentIds(AttributeType attrType, String value, + List contextDBAttrs, Date validFrom, Date validTo) { + /* Task: get all IDs which are within the boundaries defined by :validFrom and :validTo + * Idea: + * exclude those which are not within the boundaries, i.e., one of (OR) + * 1) both a.validFrom and a.validTo lie before :validFrom + * 2) both a.validFrom and a.validTo lie after :validTo + * thus, + * NOT ( ( a.validFrom < :validFrom AND a.validTo < :validTo) OR + * ( a.validFrom > :validFrom AND a.validTo > :validTo) ) + * resolving the NOT: + * (a.validFrom >= :validFrom OR a.validTo >= :validTo) AND + * (a.validFrom <= :validFrom OR a.validTo <= :validTo) + * + * TODO make version from arni + * a.validFrom <= :validTo AND a.validTo >= :validFrom + */ + + Session session = factory.getCurrentSession(); + Transaction t = session.beginTransaction(); + Query query = null; + + if ( contextDBAttrs == null || contextDBAttrs.size() == 0 ) { + query = session.getNamedQuery("getAssignmentIds0"); + } else if ( contextDBAttrs.size() == 1) { + query = session.getNamedQuery("getAssignmentIds1"); + query.setParameter(CTXATTRTYP0, contextDBAttrs.get(0).getCtxAttribute()); + query.setParameter(CTXATTR0, contextDBAttrs.get(0).getValue()); + } else if ( contextDBAttrs.size() == 2) { + query = session.getNamedQuery("getAssignmentIds2"); + query.setParameter(CTXATTRTYP0, contextDBAttrs.get(0).getCtxAttribute()); + query.setParameter(CTXATTR0, contextDBAttrs.get(0).getValue()); + query.setParameter(CTXATTRTYP1, contextDBAttrs.get(1).getCtxAttribute()); + query.setParameter(CTXATTR1, contextDBAttrs.get(1).getValue()); + }else { + throw new RuntimeException("Only two constraining attributes are supported"); + } + query.setParameter(ATTRTYPE, attrType); + query.setParameter(VALIDFROM, validFrom); + query.setParameter(VALIDTO, validTo); + query.setParameter(VALUE, value); + + List list = query.list(); + t.commit(); + return list; + } + + public AttributeAssignment addAssignment(AuthoAttribute attribute, + Date validFrom, Date validTo, List contextAttributes) { + return addAssignment(attribute, + validFrom == null ? null : new Timestamp(validFrom.getTime()), + validTo == null ? null : new Timestamp(validTo.getTime()), contextAttributes); + //return addAssignment(attribute, new Date(validFrom.getTime()), new Date(validTo.getTime()), contextAttributes); + } + + public AttributeAssignment addAssignment(AuthoAttribute attribute, + Timestamp validFrom, Timestamp validTo, List contextAttributes) + throws InvalidAssignmentException { + AttributeType attrType = hibernateUtil.getAttributeType(attribute.getAttributeIdentifier()); + if ( attrType == null ) { + logger.info("AttributeType is not jet known by PDPState. Creating new AttributeType for attribute " + attribute.getAttributeIdentifier()); + attrType = addAttributeType(attribute, contextAttributes); + } + // transform input to values with db IDs + List contextDBAttrs = transformCtxAttr(attrType, contextAttributes); + return addAssignment(attrType, attribute.getValue(), validFrom, validTo, contextDBAttrs); + } + + + public AttributeAssignment addAssignment(AttributeType attrType, + String value, Timestamp validFrom, Timestamp validTo, + List contextDBAttrs) { + + AttributeAssignment assignment = new AttributeAssignment(); + assignment.setValue(value); + assignment.setValidFrom(validFrom); + assignment.setValidTo(validTo); + + if ( assignment.getValidFrom().after(assignment.getValidTo()) ) { + throw new InvalidAssignmentException(Reason.INVALID_DATE_NO_TIMEFRAME); + } + if ( new Date(new java.util.Date().getTime() - 60*1000).after(assignment.getValidFrom())) { + throw new InvalidAssignmentException(Reason.INVALID_DATE_MODIFICATION_OF_PAST); + } + + logger.info("Adding assignment with value \"" + value + "\" for " + attrType.getAttrType().toString()); + logger.debug("Checking that there is no existing attribute in the defined time period"); + List assignedIds = getAssignmentIds(attrType, value, contextDBAttrs, validFrom, validTo); + if ( assignedIds != null && assignedIds.size() > 0 ) { + String message = "There are already " + assignedIds.size() + " assignment(s) within the defined scope and time frame"; + logger.error(message); + throw new RuntimeException(message); + } + + assignment.setAttrType(attrType); + assignment.setCtxAttrAssignments(contextDBAttrs); + + if ( contextDBAttrs != null ) { + for ( ContextAttributeAssignment attr : contextDBAttrs ) { + attr.setAttrAssignment(assignment); + } + } + + Session session = factory.getCurrentSession(); + Transaction tx = session.beginTransaction(); + session.save(assignment); + tx.commit(); + + return assignment; + } + + public void endAssignment(AuthoAttribute attribute, Date validTo, + List contextAttrValues) { + endAssignment(attribute, validTo == null ? null : new Date(validTo.getTime()), contextAttrValues); + } + + public void endAssignment(AuthoAttribute attribute, Timestamp validTo, + List contextAttrValues) { + AttributeType attrType = hibernateUtil.getAttributeType(attribute.getAttributeIdentifier()); + List contextDBAttrs = transformCtxAttr(attrType, contextAttrValues); + endAssignment(attrType, attribute.getValue(), validTo, contextDBAttrs); + } + + + public void endAssignment(AttributeType attrType, + String value, Timestamp validTo, + List contextDBAttrs){ + if ( validTo == null ) { + //per default, end assignment with now + validTo = new Timestamp(new java.util.Date().getTime()); + } else if ( new Date(new java.util.Date().getTime() - 1000).after(validTo)) { + logger.error("It is not permitted to end an assignment in the past"); + throw new InvalidAssignmentException(Reason.INVALID_DATE_MODIFICATION_OF_PAST); + } + + //Date now = new Date(new java.util.Date().getTime()); + List ids = getAssignmentIds(attrType, value, contextDBAttrs, validTo, validTo); + + if ( ids.size() == 0 ) { + logger.error("There is no assignment which could be ended"); + throw new InvalidAssignmentException(Reason.NO_ASSIGNMENT_AVAILABLE); + } else if (ids.size() > 1) { + logger.fatal("There are several assignments valid at one time: TODO log details"); + throw new InvalidAssignmentException(Reason.INVALID_STATE); + } + + Session session = factory.getCurrentSession(); + Transaction tx = session.beginTransaction(); + //TODO check before in the same session? + AttributeAssignment attrAssign = (AttributeAssignment) session.get(AttributeAssignment.class, ids.get(0)); + attrAssign.setValidTo(validTo); + session.update(attrAssign); + tx.commit(); + } + + public String replaceValue() { + //TODO for assignment where only one value at one point in time is valid + // e.g. active policy version + // + + //return old value + + return null; + } + + + + /** + * This function does mainly two things: first, the attribute definitions which are contained in + * contextAttributes are transfered to a List of ContextAttributeAssignment (i.e., containing + * a reference to the actual ContextAttribute). Second, a sanity check is done, i.e., if the attributes + * defined by contextAttributes match to the required contextAttributes defined for the + * attributeType + * @param attributeType + * @param contextAttributes + * @return + */ + protected List transformCtxAttr(AttributeType attributeType, List contextAttributes) { + + // check if meta info defined by AttributeType defines same size of contextAttributes as provided + if ( (attributeType.getCtxTypes() == null ? 0 : attributeType.getCtxTypes().size()) + != (contextAttributes == null ? 0 : contextAttributes.size())) { + String message = "AttributeType for " + attributeType.getAttrType() + " defines " + + (attributeType.getCtxTypes() == null ? 0 : attributeType.getCtxTypes().size()) + " context attributes, but received " + + (contextAttributes == null ? 0 : contextAttributes.size()); + logger.error("Invalid Assignment: " + message); + throw new InvalidParameterException(message); + } + + AttributeAssignment assignment = new AttributeAssignment(); + + if ( contextAttributes != null && contextAttributes.size() > 0 ) { + List contextDBAttrs = new Vector(); + + //in most cases there will be only one ctx Attribute; implement "fast way" + if ( contextAttributes.size() == 1 ) { + AuthoAttribute provAttr = contextAttributes.get(0); + ContextAttribute ctxAttr = attributeType.getCtxTypes().get(0); + //check if required IDs match + if ( provAttr.getAttributeIdentifier().hashCode() != + ctxAttr.getAttrId().hashCode()) { + String message = "AttributeType for " + attributeType.getAttrType() + " defines " + + "another required context attribute (" + ctxAttr.getAttrId() + + ") than provided (" + provAttr.getAttributeIdentifier(); + logger.error("Invalid Assignment: " + message); + throw new InvalidParameterException(message); + } else { + contextDBAttrs.add(new ContextAttributeAssignment(provAttr.getValue(), ctxAttr, assignment)); + return contextDBAttrs; + } + } else { + Map tmpMap = new HashMap(); + for ( ContextAttribute ctxAttr : attributeType.getCtxTypes() ) { + tmpMap.put(ctxAttr.getAttrId(), ctxAttr); + } + for ( AuthoAttribute attrValue : contextAttributes ) { + if ( tmpMap.containsKey(attrValue.getAttributeIdentifier()) ) { + ContextAttribute ctxAttr = tmpMap.get(attrValue.getAttributeIdentifier()); + contextDBAttrs.add(new ContextAttributeAssignment(attrValue.getValue(), ctxAttr, assignment)); + } else { + String message = "AttributeType " + attributeType.getAttrType() + + " does not require the context attribute " + attrValue.getAttributeIdentifier(); + logger.error("Invalid Assignment: " + message); + throw new InvalidParameterException(message); + } + } + return contextDBAttrs; + } + } else { + return null; + } + } + +// session.createQuery("SELECT a.id FROM " + +// AttributeAssignment.class.getName() + " AS a " + +// " INNER JOIN a.ctxAttrAssignments as c " + +// " WHERE a.attrType = :attrType " + +// " AND ( ( a.validFrom >= :validFrom OR a.validTo >= :validTo ) AND " + +// " ( a.validFrom <= :validFrom OR a.validTo <= :validTo ) ) " + +// " AND a.value = :value " + +// " AND c.ctxAttribute = :ctxAttrTypeNull " + +// " AND c.value = :ctxAttrNull"); +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/PDPStateManagement.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/PDPStateManagement.java new file mode 100644 index 0000000..6774423 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/PDPStateManagement.java @@ -0,0 +1,239 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdpstate; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import org.apache.log4j.Logger; +import org.apache.log4j.PropertyConfigurator; + +import eu.aniketos.securebpmn.xacml.api.SecurityError; +import eu.aniketos.securebpmn.xacml.api.ErrorType; +import eu.aniketos.securebpmn.xacml.api.ReasonType; +import eu.aniketos.securebpmn.xacml.api.autho.AttributeIdentifier; +import eu.aniketos.securebpmn.xacml.api.autho.IPDPStateManagement; +import eu.aniketos.securebpmn.xacml.api.log.AccessControlRequest; +import eu.aniketos.securebpmn.xacml.pdpstate.db.AttributeDBIdentifier; +import eu.aniketos.securebpmn.xacml.pdpstate.db.HibernateUtil; + +public class PDPStateManagement implements IPDPStateManagement { + + private static PDPStateManagement instance; + + private PDPState pdpState; + private HibernateUtil dbUtil; + //private IPDP pdp; + + private Map attributes = new HashMap(); + + private Map dependencies = new HashMap(); + //private Map dependencies_remove = new HashMap(); + + + private static Logger logger = Logger.getLogger(PDPStateManagement.class); + + private static final String ATTRIBUTE = "attribute:", + DEPENDENCY = "dependency:"; + public static final String CONFFILE_NAME = "pdpStateDependencies.conf"; + + public static PDPStateManagement getInstance() { + if ( instance == null ) { + instance = new PDPStateManagement(); + } + return instance; + } + + public static void main(String[] args) throws FileNotFoundException, IOException { + Properties log4jProps = new Properties(); + log4jProps.load(new BufferedInputStream(new FileInputStream(new File("src/test/log4j.properties")))); + PropertyConfigurator.configure(log4jProps); + PDPStateManagement.getInstance(); + } + + private PDPStateManagement() { + pdpState = PDPState.getInstance(); + dbUtil = pdpState.getHibernateUtil(); + + try { + // check if there is a conf file on the class path + File confFile = new File(CONFFILE_NAME); + if ( ! confFile.exists() ) { + // try with conf before... + confFile = new File("conf/" +CONFFILE_NAME); + } + if ( ! confFile.exists() ) { + // try from mvn default test location + confFile = new File("src/test/resources/" +CONFFILE_NAME); + } + + if ( confFile.exists()) { + logger.info("Reading PDPStateManagement configuration from " + confFile.getAbsolutePath()); + readConfig(confFile); + } + else { + logger.warn("Reading PDPStateManagement configuration from jar; You might define a more accurate " + CONFFILE_NAME); + readConfig(this.getClass().getResourceAsStream("/" + CONFFILE_NAME)); + } + } catch (IOException e) { + logger.error("Could not configuration file from PDPStateManagement: " + e.getMessage()); + throw new RuntimeException(e); + } + } + + public Map getDependencies() { + return Collections.unmodifiableMap(dependencies); + } + + public void updatePDPState(AccessControlRequest request) throws SecurityError { + + //get resource and action + URI resource = request.getResource(); + Dependency assign = dependencies.get(resource.toString()); + + if ( assign == null ) { + logger.error("For the resource (" + resource + ") defined in log " + request.getEvaluationId() + " no assignment is defined"); + throw new SecurityError(ErrorType.CONFIGURATION_ERROR, ReasonType.PDE_ENGINE_ERROR, "Cannot update the PDPState: missing assignment definition"); + } else { + assign.writeStateChange(request, pdpState); + } + } + + private void readConfig(File confFile) throws IOException { + readConfig(new FileInputStream(confFile)); + } + + private void readConfig(InputStream stream) throws IOException { + BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); + + + String key = null; + AttributeDBIdentifier attrId = null; + + String line = null; + while ( (line = reader.readLine()) != null ) { + line = line.trim(); + if ( ! (line.startsWith("#") || line.length() == 0 ) ) { + if ( line.startsWith(ATTRIBUTE) ) { + key = line.substring(ATTRIBUTE.length(), line.length()); + try { + attrId = readAttribute(reader); + if ( attributes.containsKey(key)) { + logger.warn("Overwriting attribute definition with key " + key); + } + attributes.put(key, attrId); + } catch (URISyntaxException e) { + logger.warn("Could not read attribute with key " + key + ": URISyntaxException: " + e.getMessage()); + } catch (SyntaxError e) { + logger.warn("Could not read attribute with key " + key + ": Syntax Error: " + e.getMessage()); + } + } else if ( line.startsWith(DEPENDENCY)) { + key = "null"; + try { + key = line.substring(DEPENDENCY.length(), line.length()).trim(); + Dependency assign = Dependency.readAssignment(key, reader, attributes, dbUtil); + if (dependencies.containsKey(key)) { + logger.warn("Overwriting dependency definition with key " + key); + } + this.dependencies.put(key, assign); + } catch (SyntaxError e) { + logger.warn("Could not read dependency with key " + key + ": SyntaxError: " + e.getMessage()); + } + } else { + logger.warn("Ignoring misplace line " + line); + } + } + } + } + + + private AttributeDBIdentifier readAttribute(BufferedReader reader) throws IOException, URISyntaxException, SyntaxError { + URI category, attributeId, dataType, issuer; + category = readValueLine(reader); + dataType = readValueLine(reader); + attributeId = readValueLine(reader); + issuer = readValueLine(reader); + + AttributeIdentifier attr = new AttributeIdentifier(category, dataType, attributeId, issuer); + return dbUtil.getAttributeDBIdentifier(attr); + } + + private URI readValueLine(BufferedReader reader) throws IOException, URISyntaxException, SyntaxError { + String line = reader.readLine().trim(); + if ( line.startsWith("#") ) { + return readValueLine(reader); + } + if ( "null".equals(line)) { + return null; + } + if ( line.length() == 0 || line.startsWith(ATTRIBUTE) || line.startsWith(DEPENDENCY)) { + throw new SyntaxError("Invalid line after attribute declaration: " + line); + } + return new URI(line); + } + +// private void addDependency(String dependency) throws SyntaxError { +// int m = dependency.indexOf("->"); +// if ( m == -1 ) { +// throw new SyntaxError("Missing assignment -> "); +// } +// String key = dependency.substring(0, m).trim(); +// AttributeDBIdentifier dbKey = attributes.get(key); +// +// +// if ( dbKey == null ) { +// throw new SyntaxError("Attribute with key " + key + " is not defined so far"); +// } +// List dependencies = new Vector(); +// StringTokenizer tokenizer = new StringTokenizer(dependency.substring(m + 2), ","); +// while (tokenizer.hasMoreTokens()) { +// String token = tokenizer.nextToken().trim(); +// if ( ! (token.length() == 0) ) { +// // some attributes may not depend on any other attribute +// if ( dependencies.size() == 0 && "null".equals(token) ) { +// this.dependenciesString.put(key, dependencies); +// this.dependencies.put(dbKey, dependencies); +// return; +// } +// AttributeDBIdentifier dependent = attributes.get(token); +// if ( dependent == null ) { +// throw new SyntaxError("Attribute with key " + dependent + " is not defined so far"); +// } else { +// dependencies.add(dependent); +// } +// } +// } +// if ( dependencies.size() == 0 ) { +// throw new SyntaxError("No dependency is defined"); +// } +// this.dependenciesString.put(key, dependencies); +// this.dependencies.put(dbKey, dependencies); +//} +// +// +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/SyntaxError.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/SyntaxError.java new file mode 100644 index 0000000..fc7e7f9 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/SyntaxError.java @@ -0,0 +1,31 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + + +package eu.aniketos.securebpmn.xacml.pdpstate; + +/** + * + * Local exception which allows Dependency throw errors about illegal + * syntax to PDPStateAssignment + * + */ +class SyntaxError extends Exception { + private static final long serialVersionUID = -6261081989869542809L; + public SyntaxError(String string) { + super(string); + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/AttributeAssignment.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/AttributeAssignment.java new file mode 100644 index 0000000..29aad60 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/AttributeAssignment.java @@ -0,0 +1,121 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdpstate.db; + +import java.sql.Timestamp; +import java.util.List; + + +/** + * This class represents a instantiation of the AttributeType meta-data class. + * + */ +public class AttributeAssignment { + + /** + * DB generated ID + */ + protected long id = -1; + + /** + * value for which it is valid, e.g., nurse + */ + protected String value; + + /** + * beginning with which date the assignment is valid, per default -infinite + */ + protected Timestamp validFrom; + + /** + * up to when the assignment is valid, per default +infinite + */ + protected Timestamp validTo; + + /** + * which attributeType is instantiated; there, the meta data are stored, e.g., + * that this is an assignment of an attribute "role". + */ + protected AttributeType attrType; + + /** + * a list of attached attributes which are required from the context + * e.g., the subject-id with value "carol@myhospital.com" + */ + protected List ctxAttrAssignments; + + public AttributeAssignment() { + this.setValidFrom(null); + this.setValidTo(null); + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public Timestamp getValidFrom() { + return validFrom; + } + + public void setValidFrom(Timestamp validFrom) { + this.validFrom = validFrom; + if ( this.validFrom == null ) { + this.validFrom = new Timestamp(new java.util.Date().getTime()); + } + } + + public Timestamp getValidTo() { + return validTo; + } + + public void setValidTo(Timestamp validTo) { + this.validTo = validTo; + if ( this.validTo == null ) { + this.validTo = new Timestamp(Long.MAX_VALUE); + } + } + + public AttributeType getAttrType() { + return attrType; + } + + public void setAttrType(AttributeType attributeType) { + this.attrType = attributeType; + } + + public List getCtxAttrAssignments() { + return ctxAttrAssignments; + } + + public void setCtxAttrAssignments( + List ctxAttrAssignments) { + this.ctxAttrAssignments = ctxAttrAssignments; + } + + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/AttributeDBIdentifier.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/AttributeDBIdentifier.java new file mode 100644 index 0000000..5e99779 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/AttributeDBIdentifier.java @@ -0,0 +1,73 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdpstate.db; + +import java.net.URI; + +import eu.aniketos.securebpmn.xacml.api.autho.AttributeIdentifier; + +/** + * This class contains meta-data for the PDPState. + *
      + * allows to identify and reference an attribute as it is used within XACML; + * for the PDPState, this is more or less meta data information; i.e., all different + * types of attributes are listed here. + * + * this is the same implementation as for the LogServer; may be merged if both + * implementation are moved to one jar + * + */ +public class AttributeDBIdentifier extends AttributeIdentifier { + + protected int id = -1; + + public AttributeDBIdentifier(URI category, URI attributeType, URI attributeId, URI issuer) { + super(category, attributeType, attributeId, issuer); + } + + public AttributeDBIdentifier(AttributeIdentifier attrId) { + super(attrId.getCategory(), attrId.getAttributeType(), attrId.getAttributeId(), attrId.getIssuer()); + } + + protected AttributeDBIdentifier() { + + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + + public void setCategory(URI categrory) { + super.category = categrory; + } + + public void setAttributeType(URI attributeType) { + super.attributeType = attributeType; + } + + public void setAttributeId(URI attributeId) { + super.attributeId = attributeId; + } + + public void setIssuer(URI issuer) { + super.issuer = issuer;; + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/AttributeType.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/AttributeType.java new file mode 100644 index 0000000..adac661 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/AttributeType.java @@ -0,0 +1,83 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdpstate.db; + +import java.util.List; + + + +/** + * This class contains meta-data for the PDPState. + *
      + * The "main" metaData class for the PDPState; here, all known + * assignments are stored. This is needed to keep the database in + * a consistent and non-redundant state and to allow the PDPStateModule + * to retrieve the context information from the PDP in an easy way + * + */ +public class AttributeType { + + /** + * DB generated ID + */ + protected int id = -1; + + /** + * The type of attribute which can be resolved by this attributeType, + * e.g, role + */ + protected AttributeDBIdentifier attrType; + + /** + * List of required attributes which are required to determine the + * assigned value (may be empty, e.g., in case of active policies), + * example: subject-id for attrTyp role + */ + protected List ctxTypes; + + public AttributeType(AttributeDBIdentifier attrType, List ctxTypes) { + this.attrType = attrType; + this.ctxTypes = ctxTypes; + } + + + //empty constructor for hibernate + public AttributeType() {} + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public AttributeDBIdentifier getAttrType() { + return attrType; + } + + public void setAttrType(AttributeDBIdentifier attrType) { + this.attrType = attrType; + } + + public List getCtxTypes() { + return ctxTypes; + } + + public void setCtxTypes(List ctxTypes) { + this.ctxTypes = ctxTypes; + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/ContextAttribute.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/ContextAttribute.java new file mode 100644 index 0000000..e8b176a --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/ContextAttribute.java @@ -0,0 +1,75 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdpstate.db; + + +/** + * This class contains meta-data for the PDPState. + *
      + * It is (more or less) the technical implementation of the n:m mapping + * from AttributeType to AttributeDBIdentifier; however, it is referenced + * from ContextAttributeAssignment (mainly out of consistency and data + * space reasons) and therefore implemented as disting class + * + */ +public class ContextAttribute { + + /** + * DB generated ID + */ + protected int id = -1; + + /** + * defines the required attributeId + */ + protected AttributeDBIdentifier attrId; + + /** + * the AttributeType it is assigned to + */ + protected AttributeType attrType; + + public ContextAttribute() {} + + public ContextAttribute(AttributeDBIdentifier attrId, AttributeType attrType) { + this.attrId = attrId; + this.attrType = attrType; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public AttributeDBIdentifier getAttrId() { + return attrId; + } + + public void setAttrId(AttributeDBIdentifier attrId) { + this.attrId = attrId; + } + + public AttributeType getAttrType() { + return attrType; + } + + public void setAttrType(AttributeType attrType) { + this.attrType = attrType; + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/ContextAttributeAssignment.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/ContextAttributeAssignment.java new file mode 100644 index 0000000..dd2fd50 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/ContextAttributeAssignment.java @@ -0,0 +1,123 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + + +package eu.aniketos.securebpmn.xacml.pdpstate.db; + +/** + * This class represents an assignment of a context attribute + * to an attribute assignment; one could also see ContextAttributeAssignments + * as constraints when a attributeAssignment is valid. + */ +public class ContextAttributeAssignment { + + /** + * DB generated ID + */ + protected long id = -1; + + /** + * the assigned value, e.g, nurse@hospital.de + */ + protected String value; + + /** + * the context attribute which is instaniated + */ + protected ContextAttribute ctxAttribute; + + /** + * the attribute assignment which is "constrained" with this + * context attribute assignment + */ + protected AttributeAssignment attrAssignment; + + public ContextAttributeAssignment() {} + + public ContextAttributeAssignment(String value, ContextAttribute ctxAttribute, AttributeAssignment attrAssignment) { + this.value = value; + this.ctxAttribute = ctxAttribute; + this.attrAssignment = attrAssignment; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public ContextAttribute getCtxAttribute() { + return ctxAttribute; + } + + public void setCtxAttribute(ContextAttribute ctxAttribute) { + this.ctxAttribute = ctxAttribute; + } + public AttributeAssignment getAttrAssignment() { + return attrAssignment; + } + + public void setAttrAssignment(AttributeAssignment attrAssignment) { + this.attrAssignment = attrAssignment; + } + + + + +// protected AttributeDBIdentifier attrType; +// +// public ContextAttributeAssignment(AttributeDBIdentifier attrType, String value) { +// this.attrType = attrType; +// this.value = value; +// } +// +// //empty constructor for hibernate +// public ContextAttributeAssignment() {} +// +// public Long getId() { +// return id; +// } +// +// public void setId(Long id) { +// this.id = id; +// } +// +// public AttributeDBIdentifier getAttrType() { +// return attrType; +// } +// +// public void setAttrType(AttributeDBIdentifier attrType) { +// this.attrType = attrType; +// } +// +// public String getValue() { +// return value; +// } +// +// public void setValue(String value) { +// this.value = value; +// } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/HibernateUtil.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/HibernateUtil.java new file mode 100644 index 0000000..b9b61fd --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/db/HibernateUtil.java @@ -0,0 +1,210 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdpstate.db; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Vector; + +import org.apache.log4j.Logger; +import org.hibernate.Query; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.Transaction; + +import eu.aniketos.securebpmn.xacml.api.autho.AttributeIdentifier; + +/** + * loads and caches the meta data tables + * + */ +public class HibernateUtil { + + private static final Logger logger = Logger.getLogger(HibernateUtil.class); + private SessionFactory sessionFactory; + + private Map attrIds = null; + private Map attrTypeIds = null; + + private static HibernateUtil instance; + + + /** + * not that the HibernateUtil has to be instanciated first + * @return + */ + public static HibernateUtil getInstance() { + return instance; + } + + public synchronized static HibernateUtil createHibernateUtil(SessionFactory factory) { + if ( instance != null ) { + logger.warn("HibernateUtil instance already exists"); + } + instance = new HibernateUtil(factory); + return instance; + } + + private HibernateUtil(SessionFactory factory) { + this.sessionFactory = factory; + attrIds = new HashMap(); + attrTypeIds = new HashMap(); + + Session session = sessionFactory.getCurrentSession(); + Transaction tx = session.beginTransaction(); + + Query query = session.createQuery("from " + AttributeDBIdentifier.class.getName()); + List l = query.list(); + for ( Object val : l) { + AttributeDBIdentifier i = (AttributeDBIdentifier) val; + attrIds.put(i, i); + logger.debug("loaded AttrID " + i + ": " + i.getId()); + } + + query = session.createQuery("from " + AttributeType.class.getName()); + l = query.list(); + for ( Object val : l ) { + AttributeType i = ( AttributeType ) val; + attrTypeIds.put(i.getAttrType(), i); + logger.debug("loaded AttrType " + i.getAttrType() + ": " + i.getId()); + } + tx.commit(); + logger.info("Created HibernateUtil: " + attrIds.size() + " AttributeIdentifier(s), " + attrTypeIds.size() + " AttributeType(s)"); + } + + /** + * returns an attribute Identifier containing the ID from the database and therefore + * useable for database write and update operations + * @param attrId + * @return + */ + public AttributeDBIdentifier getAttributeDBIdentifier(AttributeIdentifier attrId) { + if ( attrIds.containsKey(attrId) ) { + return attrIds.get(attrId); + } else { + return addAttributeIdentifier(attrId); + } + } + /** + * returns if an attribute is already stored in the database + * @param attrId + * @return + */ + public boolean contains(AttributeIdentifier attrId) { + return attrTypeIds.containsKey(attrId); + } + + /** + * add an attribute identifier to the database;
      + * + * this function checks first if the attribute is already stored, i.e., it + * can be called without the need to check if the attribute is already there. + * @param attrId + * @return + */ + public synchronized AttributeDBIdentifier addAttributeIdentifier(AttributeIdentifier attrId) { + if ( attrIds.containsKey(attrId) ) { + return attrIds.get(attrId); + } else { + AttributeDBIdentifier dbid = new AttributeDBIdentifier(attrId); + Session session = sessionFactory.getCurrentSession(); + Transaction tx = session.beginTransaction(); + session.save(dbid); + + tx.commit(); + logger.debug("Inserted AttrId " + dbid.getId() + " " + attrId); + attrIds.put(attrId, dbid); + return dbid; + } + } + + /** + * checks if already some meta data (i.e., the AttributeType) for an + * attribute identifier is known by the database + * @param attrId + * @return + */ + public AttributeType getAttributeType(AttributeIdentifier attrId) { + return attrTypeIds.get(attrId); + } + + /** + * add an attribute type to the database;
      + * + * this function checks first if the attribute type is already stored, i.e., it + * can be called without the need to check if the attribute type is already there. + * @param attrId + * @param contextAttr + * @return + */ + public synchronized AttributeType addAttributeType(AttributeIdentifier attrId, List contextAttr) { + if ( attrTypeIds.containsKey(attrId) ) { + // this type is already defined, check if the given and the existing definition match + AttributeType type = attrTypeIds.get(attrId); + + if ( type.getCtxTypes().size() != contextAttr.size() ) { + logger.warn("Existing AttributeType " + attrId + " does not match provided type definition (different context attribute count)"); + return null; + } + if ( type.getCtxTypes().size() == 1 ) { + if ( ! type.getCtxTypes().get(0).getAttrId().equals(contextAttr.get(0)) ) { + logger.warn("Existing AttributeType " + attrId + " does not match provided type definition (contextAttr type does not match)"); + return null; + } + } else if ( type.getCtxTypes().size() > 1 ) { + for ( ContextAttribute attr : type.getCtxTypes()) { + if ( ! contextAttr.contains(attr.getAttrType())) { + logger.warn("Existing AttributeType " + attrId + " does not match provided type definition (contextAttr type do not match)"); + return null; + } + } + } + return type; + } else { +// List contextDBAttrs = null; +// if ( contextAttr != null && contextAttr.size() > 0 ) { +// contextDBAttrs = new Vector(); +// for ( AttributeIdentifier id : contextAttr ) { +// contextDBAttrs.add(getAttributeDBIdentifier(id)); +// } +// } + + AttributeType attrType = new AttributeType(); + attrType.setAttrType(getAttributeDBIdentifier(attrId)); + + List contextDBAttrs = null; + if ( contextAttr != null && contextAttr.size() > 0 ) { + contextDBAttrs = new Vector(); + System.out.println("addAttributeType: " + attrType.getAttrType().getId() + ", " + attrType.getAttrType().toString()); + for ( AttributeIdentifier id : contextAttr ) { + contextDBAttrs.add( new ContextAttribute(getAttributeDBIdentifier(id), attrType)); + } + } + attrType.setCtxTypes(contextDBAttrs); + + Session session = sessionFactory.getCurrentSession(); + Transaction tx = session.beginTransaction(); + + session.save(attrType); + + tx.commit(); + logger.debug("Inserted AttrId " + attrType.getId() + " " + attrType); + attrTypeIds.put(attrId, attrType); + return attrType; + } + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/xacml/PDPStateModule.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/xacml/PDPStateModule.java new file mode 100644 index 0000000..3ade76a --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/java/eu/aniketos/securebpmn/xacml/pdpstate/xacml/PDPStateModule.java @@ -0,0 +1,157 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + + +package eu.aniketos.securebpmn.xacml.pdpstate.xacml; + +import java.net.URI; +import java.sql.Timestamp; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Vector; + +import org.apache.log4j.Logger; + +import eu.aniketos.securebpmn.xacml.api.autho.AttributeIdentifier; +import eu.aniketos.securebpmn.xacml.pdpstate.PDPState; +import eu.aniketos.securebpmn.xacml.pdpstate.db.AttributeDBIdentifier; +import eu.aniketos.securebpmn.xacml.pdpstate.db.AttributeType; +import eu.aniketos.securebpmn.xacml.pdpstate.db.ContextAttribute; +import eu.aniketos.securebpmn.xacml.pdpstate.db.ContextAttributeAssignment; +import eu.aniketos.securebpmn.xacml.pdpstate.db.HibernateUtil; +import eu.aniketos.securebpmn.xacml.support.finder.IPDPStateEvaluationContext; + +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; +import com.sun.xacml.attr.AttributeFactory; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BagAttribute; +import com.sun.xacml.cond.EvaluationResult; +import com.sun.xacml.finder.AttributeFinderModule; + +/** + * PDPState modules uses the backend database to check if it is responsible; + * if yes, it retrieves the information which attributes have to be resolved + * from the context form the database (which is more or less configuration and meta data). + * After retrieving the required data from the context, the actual assignments + * are queried from the database, the result is returned to the PDP + * + */ +public class PDPStateModule extends AttributeFinderModule { + + private static PDPState pdpState = PDPState.getInstance(); + private static HibernateUtil dbUtil = pdpState.getHibernateUtil(); + + private static final Logger logger = Logger.getLogger(PDPStateModule.class); + + protected ConfigurationStore conf; + + public boolean isDesignatorSupported() { + return true; + } + + public void setConfigurationStore(ConfigurationStore conf) { + this.conf = conf; + } + + @Override + public EvaluationResult findAttribute(URI category, URI attributeType, + URI attributeId, URI issuer, + EvaluationCtx context) { + + AttributeIdentifier attrId = new AttributeIdentifier(category, attributeType, attributeId, issuer); + logger.debug("Got request for " + attrId.toString()); + + // check if we could have some value for this attribute + if ( dbUtil.contains(attrId)) { + //we are responsible, get what is there + AttributeType attrType = dbUtil.getAttributeType(attrId); + if ( logger.isDebugEnabled() ) { + logger.debug("Found AttributeType (id " + attrType.getId() + ") with " + + ( attrType.getCtxTypes() == null ? "0" : attrType.getCtxTypes().size()) + + " dependencies"); + } + + //check if we have to resolve some context information and if yes, resolve it + List contextAttrs = attrType.getCtxTypes(); + List contextAttrValues = null; + if ( contextAttrs != null && contextAttrs.size() > 0 ) { + contextAttrValues = new Vector(); + + for ( ContextAttribute contextAttr : contextAttrs ) { + AttributeDBIdentifier id = contextAttr.getAttrId(); + EvaluationResult result = context.getAttribute(id.getCategory(), id.getAttributeType(), + id.getAttributeId(), id.getIssuer()); + + if ( !result.getAttributeValue().isBag() || + ((BagAttribute) result.getAttributeValue()).size() != 1 ) { + logger.error("Did not retreive a bag with one (" +((BagAttribute) result.getAttributeValue()).size() + + ") entry after attribute search! " + + "PDPStateModule allows only one value of dependent context attributes"); + //TODO throw indeterminate message + return new EvaluationResult(BagAttribute.createEmptyBag(attributeType)); + } else { + AttributeValue attrVal = ((BagAttribute) result.getAttributeValue()).iterator().next(); + //X1 contextAttrValues.add(new ContextAttributeAssignment(contextAttr, attrVal.toString())); + // the + contextAttrValues.add(new ContextAttributeAssignment(attrVal.encode(), contextAttr, null)); + logger.debug("Resolved " +attrVal.encode() + " for attribute " + id.toString() + " from the context"); + } + } + } + // check if we have a specific context which tells us the exact point in time for which + // the attributes have to be resolved + Date queryTime = null; + if ( context instanceof IPDPStateEvaluationContext ) { + queryTime = ((IPDPStateEvaluationContext)context).getExecTime(); + } else { + queryTime = new Date(); + } + // execute query on pdpState + List values = pdpState.getAttribute(attrType, contextAttrValues, new Timestamp(queryTime.getTime())); + if ( logger.isDebugEnabled() ) { + StringBuffer buff = new StringBuffer("Found " + values.size() + " value(s): "); + for (String value : values ) { + buff.append(value + ", "); + } + logger.debug(buff.toString()); + } + + if ( values == null || values.size() == 0 ){ + return new EvaluationResult(BagAttribute.createEmptyBag(attributeType)); + } else { + Collection attrValues = new Vector(); + AttributeFactory attrFactory = AttributeFactory.getInstance(); + for ( String value : values) { + try { + attrValues.add(attrFactory.createValue(attributeType, value)); + } catch (UnknownIdentifierException e) { + logger.error("UnknownIdentifierException - " + e.getMessage() + ": cannot transform " + value + " to an attributeValue of type" + attributeType, e); + } catch (ParsingException e) { + logger.error("ParsingException - " + e.getMessage() + ": cannot transform " + value + " to an attributeValue of type" + attributeType, e); + } + } + return new EvaluationResult(new BagAttribute(attributeType, attrValues)); + } + } else { + logger.debug("DBState does not have any value for this AttributeType"); + // we are not responsible.. DBState does not have any value... + return new EvaluationResult(BagAttribute.createEmptyBag(attributeType)); + } + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/resources/eu.aniketos.pdpState.xml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/resources/eu.aniketos.pdpState.xml new file mode 100644 index 0000000..c0c6514 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/resources/eu.aniketos.pdpState.xml @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + = :validAt AND a.validFrom <= :validAt ]]> + = :validAt AND a.validFrom <= :validAt + AND c.ctxAttribute = :ctxAttrTypeNull + AND c.value = :ctxAttrNull ]]> + = :validAt AND a.validFrom <= :validAt + AND cnull.ctxAttribute = :ctxAttrTypeNull + AND cnull.value = :ctxAttrNull + AND cone.ctxAttribute = :ctxAttrTypeOne + AND cone.value = :ctxAttrOne]]> + = :validFrom OR a.validTo >= :validTo ) AND + ( a.validFrom <= :validFrom OR a.validTo <= :validTo ) ) + AND a.value = :value]]> + = :validFrom OR a.validTo >= :validTo ) AND + ( a.validFrom <= :validFrom OR a.validTo <= :validTo ) ) + AND a.value = :value + AND c.ctxAttribute = :ctxAttrTypeNull + AND c.value = :ctxAttrNull]]> + = :validFrom OR a.validTo >= :validTo ) AND + ( a.validFrom <= :validFrom OR a.validTo <= :validTo ) ) + AND a.value = :value + AND cnull.ctxAttribute = :ctxAttrTypeNull + AND cnull.value = :ctxAttrNull + AND cone.ctxAttribute = :ctxAttrTypeOne + AND cone.value = :ctxAttrOne]]> + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/resources/hibernate.pdpState.cfg.xml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/resources/hibernate.pdpState.cfg.xml new file mode 100644 index 0000000..96b2ed8 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/resources/hibernate.pdpState.cfg.xml @@ -0,0 +1,29 @@ + + + + + + + org.hsqldb.jdbcDriver + jdbc:hsqldb:hsql://localhost/pdpstate + sa + + + 1 + + org.hibernate.dialect.HSQLDialect + + thread + + org.hibernate.cache.NoCacheProvider + + true + + + create + + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/resources/pdpStateDependencies.conf b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/resources/pdpStateDependencies.conf new file mode 100644 index 0000000..645b53b --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/main/resources/pdpStateDependencies.conf @@ -0,0 +1,180 @@ +# +# this config files defines the used attributes and +# dependencies between attributes. +# empty lines and lines starting with # are ignored +# +# to define an attribute, write +#attribute: +# +# +# +# +# +# category, attributeId, dataType, and issuer have to be an URI (java.net.URI), +# issuer may be defined as "null". For example, the XACML standard resource id +# can be defined with +#attribute:urn:oasis:names:tc:xacml:1.0:resource:resource-id +#urn:oasis:names:tc:xacml:3.0:attribute-category:resource +#http://www.w3.org/2001/XMLSchema#string +#urn:oasis:names:tc:xacml:1.0:resource:resource-id +#null +# +# to define a dependency, write +#dependency: +# -> null|[, ] +# -> +# +# is the resource (standard resource-id as defined in policy, +# e.g., a role assignment modelled as resource urn:runEx:role:assignment) +# is the AttrType for which this depenedency is defined (e.g., +# urn:custom:subject:role, using the key defined in the attribute: definition) +# are those attributes (identified along the key of the +# attribute: definition) which are required at runtime to resolve the +# attribute, e.g., subject-id to resolve a role +# -> defines the value of which xacml-attr of a request +# should be used for the dependent-key key_n +# +# For example +#dependency:urn:runEx:role:assignment +#urn:custom:subject:role -> urn:oasis:names:tc:xacml:1.0:subject:subject-id +#urn:custom:subject:role -> urn:custom:resource:role +#urn:oasis:names:tc:xacml:1.0:subject:subject-id -> urn:custom:resource:subject-id +# +# defines that the role assignment in the xacml policy is modelled as resource +# urn:runEx:role:assignment and changes to this resource should trigger a +# policyState change. +# the AttrType urn:custom:subject:role requires the subject-id to be resolved +# at runtime. The value for the role (i.e., which role is assigned) can be +# retrieved from the request by getting the attribute urn:custom:resource:role +# from the request, the value for the subject (i.e., to which the role is +# assigned) can be retrieved by getting urn:custom:resource:subject-id from the +# request +# +# +# Note: an attribute has to be defined before it can be used within a +# dependency definition + + + +#standard subject-id +attribute:urn:oasis:names:tc:xacml:1.0:subject:subject-id +urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +http://www.w3.org/2001/XMLSchema#string +urn:oasis:names:tc:xacml:1.0:subject:subject-id +null + +#standard resource-id +attribute:urn:oasis:names:tc:xacml:1.0:resource:resource-id +urn:oasis:names:tc:xacml:3.0:attribute-category:resource +http://www.w3.org/2001/XMLSchema#string +urn:oasis:names:tc:xacml:1.0:resource:resource-id +null + +#currentlyClaimedTasks +attribute:urn:custom:resource:cc-tasks +urn:oasis:names:tc:xacml:3.0:attribute-category:resource +http://www.w3.org/2001/XMLSchema#string +urn:custom:resource:cc-tasks +null + +#delegationCounter +attribute:urn:custom:resource:delegationCounter +urn:oasis:names:tc:xacml:3.0:attribute-category:resource +http://www.w3.org/2001/XMLSchema#string +urn:custom:resource:delegationCounter +null + +#role (assigned to subject) +attribute:urn:custom:subject:role +urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +http://www.w3.org/2001/XMLSchema#string +urn:custom:subject:role +null + +#if subject-id is treated as resource, e.g., if a role is assigned to a subject +attribute:urn:custom:resource:subject-id +urn:oasis:names:tc:xacml:3.0:attribute-category:resource +http://www.w3.org/2001/XMLSchema#string +urn:custom:resource:subject-id +null + +#if role is treated as resource, e.g., if a role is assigned to a subject +attribute:urn:custom:resource:role +urn:oasis:names:tc:xacml:3.0:attribute-category:resource +http://www.w3.org/2001/XMLSchema#string +urn:custom:resource:role +null + +# +attribute:urn:runEx:subject:qualifications +urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +http://www.w3.org/2001/XMLSchema#string +urn:runEx:subject:qualifications +null + +attribute:urn:runEx:subject:departments +urn:oasis:names:tc:xacml:1.0:subject-category:access-subject +http://www.w3.org/2001/XMLSchema#string +urn:runEx:subject:departments +null + +attribute:urn:custom:resource:creator +urn:oasis:names:tc:xacml:3.0:attribute-category:resource +http://www.w3.org/2001/XMLSchema#string +urn:custom:resource:creator +null + +attribute:urn:runEx:patient:treating-departments +urn:oasis:names:tc:xacml:3.0:attribute-category:resource +http://www.w3.org/2001/XMLSchema#string +urn:runEx:patient:treating-departments +null + +attribute:urn:runEx:patient:treating-subjects +urn:oasis:names:tc:xacml:3.0:attribute-category:resource +http://www.w3.org/2001/XMLSchema#string +urn:runEx:patient:treating-subjects +null + +attribute:urn:custom:svnPolicyVersion +urn:oasis:names:tc:xacml:3.0:attribute-category:environment +http://www.w3.org/2001/XMLSchema#integer +urn:custom:svnPolicyVersion +null + +attribute:urn:activePolicies +urn:oasis:names:tc:xacml:3.0:attribute-category:environment +http://www.w3.org/2001/XMLSchema#string +urn:activePolicies +null + +attribute:urn:resource:activePolicies +urn:oasis:names:tc:xacml:3.0:attribute-category:resource +http://www.w3.org/2001/XMLSchema#string +urn:resource:activePolicies +null + +# +# DEPENDENCIES +# + +# role assignment: to retrieve roles at runtime, resolve subject-id +dependency:urn:runEx:role:assignment +urn:custom:subject:role -> urn:oasis:names:tc:xacml:1.0:subject:subject-id +urn:custom:subject:role -> urn:custom:resource:role +urn:oasis:names:tc:xacml:1.0:subject:subject-id -> urn:custom:resource:subject-id + +# activation of policies: no dependent attributes +dependency:urn:runEx:activePolicies +urn:activePolicies -> null +urn:activePolicies -> urn:resource:activePolicies + +#breakGlassState:urn:breakGlass:patient-subjDep +#urn:breakGlass:patient-subjDep -> urn:runEx:subject:departments, todo:patientid + +#dependency:urn:custom:subject:role -> urn:oasis:names:tc:xacml:1.0:subject:subject-id +#dependency:urn:runEx:subject:qualifications -> urn:oasis:names:tc:xacml:1.0:subject:subject-id +#dependency:urn:runEx:subject:departments -> urn:oasis:names:tc:xacml:1.0:subject:subject-id +#dependency:urn:custom:resource:creator -> urn:oasis:names:tc:xacml:1.0:resource:resource-id +#dependency:urn:runEx:patient:treating-departments -> +#dependency: diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/test/java/eu/aniketos/securebpmn/xacml/pdpstate/PDPStateManagementFoo.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/test/java/eu/aniketos/securebpmn/xacml/pdpstate/PDPStateManagementFoo.java new file mode 100644 index 0000000..4d2324c --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/test/java/eu/aniketos/securebpmn/xacml/pdpstate/PDPStateManagementFoo.java @@ -0,0 +1,79 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdpstate; + +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.List; +import java.util.Properties; + +import junit.framework.Test; +import junit.framework.TestSuite; + +import org.apache.log4j.PropertyConfigurator; + +public class PDPStateManagementFoo { + + + private static PDPStateManagementFoo pdpStateMgt; + + /** + * @param args + * @throws IOException + * @throws FileNotFoundException + * @throws InterruptedException + */ + public static void main(String[] args) throws FileNotFoundException, IOException, InterruptedException { + +// Properties log4jProps = new Properties(); +// log4jProps.load(new BufferedInputStream(new FileInputStream(new File("src/test/log4j.properties")))); +// PropertyConfigurator.configure(log4jProps); +// +// pdpStateMgt = PDPStateManagement.getInstance(); +// +// pdpStateMgt.addRole("Alice", "Nurse"); +// pdpStateMgt.addRole("Bob", "Doctor"); +// pdpStateMgt.addRole("Bob", "Nurse"); +// pdpStateMgt.addRole("Bob", "Admin"); +// printRoles("Bob"); +// +// pdpStateMgt.removeRole("Bob", "Admin"); +// +// printRoles("Bob"); +// printRoles("Alice"); +// pdpStateMgt.addRole("Bob", "Admin"); +// +// printRoles("Bob"); + + + + } + + private static void printRoles(String subjectId) { +// List roles = pdpStateMgt.getRoles(subjectId); +// System.out.print("Roles of " + subjectId + ": "); +// for (String role : roles) { +// System.out.print(role + ", "); +// } +// System.out.println(""); + } + + + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/test/java/eu/aniketos/securebpmn/xacml/pdpstate/PDPStateStartup.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/test/java/eu/aniketos/securebpmn/xacml/pdpstate/PDPStateStartup.java new file mode 100644 index 0000000..dcee537 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/test/java/eu/aniketos/securebpmn/xacml/pdpstate/PDPStateStartup.java @@ -0,0 +1,209 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.pdpstate; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URI; +import java.util.Date; +import java.util.List; +import java.util.Properties; +import java.util.Vector; + +import org.apache.log4j.Logger; +import org.apache.log4j.PropertyConfigurator; + +import com.sun.xacml.Constants; +import com.sun.xacml.attr.TypeIdentifierConstants; + +import eu.aniketos.securebpmn.xacml.api.autho.AttributeIdentifier; +import eu.aniketos.securebpmn.xacml.api.autho.AuthoAttribute; +import eu.aniketos.securebpmn.xacml.pdpstate.db.AttributeAssignment; +import eu.aniketos.securebpmn.xacml.pdpstate.db.AttributeType; +import eu.aniketos.securebpmn.xacml.pdpstate.db.HibernateUtil; + + +public class PDPStateStartup { + + private static final Logger logger = Logger.getLogger(PDPStateStartup.class); + + public static PDPState pdpState; + + /** + * @param args + * @throws IOException + * @throws FileNotFoundException + */ + public static void main(String[] args) throws FileNotFoundException, IOException { + + + Properties log4jProps = new Properties(); + log4jProps.load(new BufferedInputStream(new FileInputStream(new File("src/test/log4j.properties")))); + PropertyConfigurator.configure(log4jProps); + + + copyConfForTest(); + + pdpState = PDPState.getInstance(); + + //HibernateUtil hUtil = pdpState.getHibernateUtil(); + List values; + + //checkRoleAttrType(hUtil); + //checkRoleAttrType(hUtil); + + addRoleAssignment("alice", "Nurse"); + addRoleAssignment("dave", "Doctor"); + addRoleAssignment("dave", "Nurse"); + addSubjectDepartment("alice", "Interne"); + addSubjectDepartment("dave", "Chirurgie"); + + //pdpState.test(); + + values = getRoles("alice"); + System.out.print("roles for alice: "); + for ( String value : values) { + System.out.print(value + ", "); + } + System.out.println(""); + + + values = getRoles("dave"); + System.out.print("roles for dave: "); + for ( String value : values) { + System.out.print(value + ", "); + } + System.out.println(""); + + + addDummyAssignment("val1", "key1_1", "key2_1"); + addDummyAssignment("val2", "key1_1", "key2_1"); + + addDummyAssignment("val3", "key1_2", "key2_1"); + addDummyAssignment("val4", "key1_1", "key2_2"); + + + values = getDummyAssignment("key1_2", "key2_1"); + System.out.print("dummy assignment for key1_1/key2_1: "); + for ( String value : values) { + System.out.print(value + ", "); + } + + List contextAttrs = new Vector(); + contextAttrs.add(new AuthoAttribute(subjetIdentifier, "alice")); + //return pdpState.getAttribute(roleIdentifier, contextAttrs) + + List assigns = pdpState.getAssignmentIds(roleIdentifier, "Nurse", contextAttrs, new Date(), new Date()); + for ( Long id : assigns ) { + System.out.println("assigned id " + id); + } + + + } + + /** + * checks if the role assignment is already defined => subject-roles requiring subject-id + * @param hUtil + */ + public static void checkRoleAttrType(HibernateUtil hUtil) { + logger.debug("Create role AttrId"); + + AttributeIdentifier roleId = new AttributeIdentifier(Constants.SUBJECT_CAT, URI.create("subject-roles"), TypeIdentifierConstants.STRING_URI, null); + + AttributeType attrType = hUtil.getAttributeType(roleId); + if ( attrType != null ) { + logger.debug("attrType role already exisits and has " + attrType.getCtxTypes().size() + " contextTypes"); + } else { + List contextAttrs = new Vector(); + contextAttrs.add(new AttributeIdentifier(Constants.SUBJECT_CAT, Constants.SUBJECT_ID, TypeIdentifierConstants.STRING_URI, null)); + attrType = hUtil.addAttributeType(roleId, contextAttrs); + logger.debug("added role"); + } + + logger.debug("attrType role has id " + attrType.getId()); + } + + public static AttributeIdentifier roleIdentifier = new AttributeIdentifier(Constants.SUBJECT_CAT, URI.create("subject-roles"), TypeIdentifierConstants.STRING_URI, null); + public static AttributeIdentifier subjetIdentifier = new AttributeIdentifier(Constants.SUBJECT_CAT, Constants.SUBJECT_ID, TypeIdentifierConstants.STRING_URI, null); + public static AttributeIdentifier subjDep = new AttributeIdentifier(Constants.SUBJECT_CAT, URI.create("department"), TypeIdentifierConstants.STRING_URI, null); + public static AttributeIdentifier fooIdentifier = new AttributeIdentifier(Constants.SUBJECT_CAT, URI.create("foo"), TypeIdentifierConstants.STRING_URI, null); + + + public static AttributeAssignment addRoleAssignment(String userId, String role) { + + List contextAttrs = new Vector(); + contextAttrs.add(new AuthoAttribute(subjetIdentifier, userId)); + return pdpState.addAssignment(new AuthoAttribute(roleIdentifier, role), null, null, contextAttrs); + } + + public static List getRoles(String userId) { + List contextAttrs = new Vector(); + contextAttrs.add(new AuthoAttribute(subjetIdentifier, userId)); + return pdpState.getAttribute(roleIdentifier, contextAttrs); + } + + public static AttributeAssignment addSubjectDepartment(String userId, String role) { + + List contextAttrs = new Vector(); + contextAttrs.add(new AuthoAttribute(subjetIdentifier, userId)); + return pdpState.addAssignment(new AuthoAttribute(subjDep, role), null, null, contextAttrs); + } + + public static AttributeAssignment addDummyAssignment(String foo, String bar, String baz) { + List contextAttrs = new Vector(); + contextAttrs.add(new AuthoAttribute(roleIdentifier, bar)); + contextAttrs.add(new AuthoAttribute(subjDep, baz)); + return pdpState.addAssignment(new AuthoAttribute(subjetIdentifier, foo), null, null, contextAttrs); + } + + public static List getDummyAssignment(String bar, String baz) { + List contextAttrs = new Vector(); + contextAttrs.add(new AuthoAttribute(roleIdentifier, bar)); + contextAttrs.add(new AuthoAttribute(subjDep, baz)); + return pdpState.getAttribute(subjetIdentifier, contextAttrs); + } + + + public static void copyConfForTest() throws IOException { + + BufferedInputStream bIS = new BufferedInputStream(new FileInputStream(new File("src/main/resources/hibernate.cfg.xml"))); + BufferedOutputStream bOS = new BufferedOutputStream(new FileOutputStream(new File("target/classes/hibernate.cfg.xml"))); + + byte[] buffer = new byte[4096]; + int read = -1; + + while ( (read = bIS.read(buffer)) != -1 ) { + bOS.write(buffer, 0, read); + } + bOS.flush(); + bOS.close(); + + + bIS = new BufferedInputStream(new FileInputStream(new File("src/main/resources/eu.aniketos.pdpState.xml"))); + bOS = new BufferedOutputStream(new FileOutputStream(new File("target/classes/eu.aniketos.pdpState.xml"))); + + while ( (read = bIS.read(buffer)) != -1 ) { + bOS.write(buffer, 0, read); + } + bOS.flush(); + bOS.close(); + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/test/log4j.properties b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/test/log4j.properties new file mode 100644 index 0000000..883f66f --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.pdpstate/src/test/log4j.properties @@ -0,0 +1,19 @@ +log4j.rootLogger=INFO, console + +log4j.appender.logfile=org.apache.log4j.FileAppender +log4j.appender.logfile.layout=org.apache.log4j.PatternLayout +log4j.appender.logfile.layout.ConversionPattern=%d [%t] %-5p %c - %m%n +log4j.appender.logfile.File=${catalina.base}/logs/pdp.log + +log4j.appender.console=org.apache.log4j.ConsoleAppender +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern=%-5p %c - %m%n + +# %d [%t] + +log4j.logger.eu.aniketos=DEBUG +log4j.logger.com.sun.xacml=DEBUG + +log4j.logger.org.apache.commons.httpclient.HttpMethodDirector=WARN + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/pom.xml b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/pom.xml new file mode 100644 index 0000000..c072909 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + eu.aniketos.securebpmn.xacml + eu.aniketos.securebpmn.xacml.parent + 1.0 + ../eu.aniketos.securebpmn.xacml.parent/pom.xml + + eu.aniketos.securebpmn.xacml.support + jar + SecureBPMN XACML - Support + http://maven.apache.org + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.0.2 + + 1.6 + 1.6 + + + + + + + junit + junit + 3.8.1 + test + + + eu.aniketos.securebpmn.xacml + com.sun.xacml + 0.1 + + + eu.aniketos.securebpmn.xacml + com.sun.xacml.support + 0.1 + + + eu.aniketos.securebpmn.xacml + eu.aniketos.securebpmn.xacml.api + 0.1 + + + diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/AttributeResolver.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/AttributeResolver.java new file mode 100644 index 0000000..aa25e1d --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/AttributeResolver.java @@ -0,0 +1,80 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support; + +import java.net.URI; +import java.util.HashSet; +import java.util.Set; + +import org.apache.log4j.Logger; + +import eu.aniketos.securebpmn.xacml.support.finder.IPDPStateEvaluationContext; + +import com.sun.xacml.Constants; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BagAttribute; +import com.sun.xacml.attr.IntegerAttribute; +import com.sun.xacml.attr.StringAttribute; +import com.sun.xacml.attr.TypeIdentifierConstants; +import com.sun.xacml.cond.EvaluationResult; + +public class AttributeResolver { + + private static final Logger logger = Logger.getLogger(AttributeResolver.class); + + public static long getPDPStatePolicyVersion(EvaluationCtx ctx) { + EvaluationResult evalResult = ctx.getAttribute(IPDPStateEvaluationContext.PDPSTATE_CATEGORY, + IPDPStateEvaluationContext.PDPSTATE_ATTRIBUTETYPE, + IPDPStateEvaluationContext.PDPSTATE_URI, + IPDPStateEvaluationContext.PDPSTATE_ISSUER); + + if ( ((BagAttribute) evalResult.getAttributeValue()).size() > 1 ) { + logger.error("Did not retreive a bag with one (" +((BagAttribute) evalResult.getAttributeValue()).size() + + ") entry after attribute search for current svn policy version number; " + + "PDP Dtate requires exactly one attribute to be defined"); + return -1; + } else if ( ((BagAttribute) evalResult.getAttributeValue()).size() == 1 ) { + IntegerAttribute attrVal = (IntegerAttribute) ((BagAttribute) evalResult.getAttributeValue()).iterator().next(); + if ( logger.isDebugEnabled() && ctx instanceof EvaluationIdContext) + logger.debug("Request " + ((EvaluationIdContext) ctx).getCurrentEvaluationId() + " is executed under policy " + attrVal.getValue()); + return attrVal.getValue(); + } else { + logger.debug("Could not resolve current policy version"); + return -1; + } + } + + public static final URI ACTIVEPOLICY_CATEGORY = Constants.ENVIRONMENT_CAT; + public static final URI ACTIVEPOLICY_ATTRIBUTETYPE = TypeIdentifierConstants.STRING_URI; + public static final String ACTIVEPOLICY = "urn:activePolicies"; + public static final URI ACTIVEPOLICY_URI = URI.create(ACTIVEPOLICY); + public static final URI ACTIVEPOLICY_ISSUER = null; + + public static Set getActivePolicies(EvaluationCtx ctx) { + EvaluationResult evalResult = ctx.getAttribute(ACTIVEPOLICY_CATEGORY, + ACTIVEPOLICY_ATTRIBUTETYPE, + ACTIVEPOLICY_URI, + ACTIVEPOLICY_ISSUER); + + Set policies = new HashSet(); + + for (AttributeValue value : ((BagAttribute) evalResult.getAttributeValue()).iterable()) { + policies.add( ((StringAttribute)value).getValue()); + } + return policies; + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/Category.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/Category.java new file mode 100644 index 0000000..7d69d4a --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/Category.java @@ -0,0 +1,104 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support; + +import java.net.URI; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import eu.aniketos.securebpmn.xacml.support.helper.*; + +import com.sun.xacml.Constants; +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; +import com.sun.xacml.attr.AnyURIAttribute; +import com.sun.xacml.attr.StringAttribute; +import com.sun.xacml.ctx.Attribute; +import com.sun.xacml.ctx.RequestElement; + +/** + * + * Describes the categories known by xacml as enum + * + */ +public enum Category implements IElementCreator { + SUBJECT (Constants.SUBJECT_CAT, Constants.SUBJECT_ID, StringAttribute.identifier, new DefaultElementCreator()), + RESOURCE (Constants.RESOURCE_CAT, Constants.RESOURCE_ID, AnyURIAttribute.identifier, new ResourceCreator()), + ACTION (Constants.ACTION_CAT, Constants.ACTION_ID, StringAttribute.identifier, new DefaultElementCreator()), + ENVIRONMENT (Constants.ENVIRONMENT_CAT, null, StringAttribute.identifier, new DefaultElementCreator()); + + private URI uri, defaultId, defaultType; + private ElementCreator creator; + + private static Map known_categories; + + static { + known_categories = new HashMap(); + + for ( Category cat : Category.values()) { + known_categories.put(cat.getURI(), cat); + } + } + + Category(URI uri, URI defaultId, String defaultType, ElementCreator creator) { + this.uri = uri; + this.defaultId = defaultId; + this.defaultType = URI.create(defaultType); + this.creator = creator; + creator.setCategory(this); + } + + public URI getURI() { + return uri; + } + + public URI getDefaultId() { + return defaultId; + } + + public URI getDefaultType() { + return defaultType; + } + + public static Category getCategory(URI category) { + return known_categories.get(category); + } + + public ElementCreator getElementCreator() { + return creator; + } + + + public Attribute getAttributeDefaultType(String value) + throws ParsingException { + return creator.getAttributeDefaultType(value); + } + + public RequestElement getRequestElement(String value) + throws ParsingException { + return creator.getRequestElement(value); + } + + public Attribute getAttribute(URI attributeId, URI dataType, String value) + throws ParsingException, UnknownIdentifierException { + return creator.getAttribute(attributeId, dataType, value); + } + + public RequestElement getRequestElement(Set attrs) { + return creator.getRequestElement(attrs); + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/CtxInfoExtension.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/CtxInfoExtension.java new file mode 100644 index 0000000..3c4d0dc --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/CtxInfoExtension.java @@ -0,0 +1,24 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support; + +import java.util.List; + +import eu.aniketos.securebpmn.xacml.api.autho.AuthoAttribute; + +public interface CtxInfoExtension { + List getCtxInformation(); +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/EvaluationIdContext.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/EvaluationIdContext.java new file mode 100644 index 0000000..481467d --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/EvaluationIdContext.java @@ -0,0 +1,42 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support; + +import eu.aniketos.securebpmn.xacml.support.finder.IEvaluationIdContext; + +import com.sun.xacml.BasicEvaluationCtx; +import com.sun.xacml.ParsingException; +import com.sun.xacml.ctx.RequestCtx; +import com.sun.xacml.finder.AttributeFinder; +import com.sun.xacml.finder.RevocationFinder; + +public class EvaluationIdContext extends BasicEvaluationCtx implements IEvaluationIdContext { + + //private static Logger logger = Logger.getLogger(EvaluationIdContext.class); + + private Long evaluationId; + + public EvaluationIdContext(RequestCtx request, AttributeFinder aFinder, + RevocationFinder rFinder, boolean cacheEnvValues, Long evaluationId) throws ParsingException { + super(request, aFinder, rFinder, cacheEnvValues); + this.evaluationId = evaluationId; + } + + + public Long getCurrentEvaluationId() { + return evaluationId; + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/RecordAttributeFinder.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/RecordAttributeFinder.java new file mode 100644 index 0000000..4c6a8ac --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/RecordAttributeFinder.java @@ -0,0 +1,45 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ +package eu.aniketos.securebpmn.xacml.support; + +import java.net.URI; + +import org.apache.log4j.Logger; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.cond.EvaluationResult; +import com.sun.xacml.finder.AttributeFinder; + +public class RecordAttributeFinder extends AttributeFinder { + + private static final Logger logger = Logger.getLogger(RecordEvaluationContext.class); + + public RecordAttributeFinder(AttributeFinder attrFinder) { + super(attrFinder); + } + + public EvaluationResult findAttribute(URI category, URI attributeType, + URI attributeId, URI issuer, + EvaluationCtx context) { + EvaluationResult evalResult = super.findAttribute(category, attributeType, attributeId, issuer, context); + + if ( context instanceof RecordEvaluationContext ) { + ((RecordEvaluationContext) context).retreiveDesignatorAttributeSearch(category, attributeType, attributeId, issuer, evalResult); + } else { + logger.warn("RecordAttributeFinder used without RecordEvaluationContext"); + } + return evalResult; + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/RecordEvaluationContext.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/RecordEvaluationContext.java new file mode 100644 index 0000000..bdb9724 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/RecordEvaluationContext.java @@ -0,0 +1,141 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support; + +import java.net.URI; +import java.util.Date; +import java.util.List; +import java.util.Vector; + +import org.apache.log4j.Logger; + +import com.sun.xacml.ParsingException; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.BagAttribute; +import com.sun.xacml.cond.EvaluationResult; +import com.sun.xacml.ctx.RequestCtx; +import com.sun.xacml.finder.AttributeFinder; +import com.sun.xacml.finder.RevocationFinder; + +import eu.aniketos.securebpmn.xacml.api.autho.DesignatorAttribute; +import eu.aniketos.securebpmn.xacml.support.finder.IRecordEvaluationContext; + +/** + * + * RecordEvaluationContext is able to retreive events of collected attributes at runtime and store them + * + * + */ +public class RecordEvaluationContext extends EvaluationIdContext implements IRecordEvaluationContext { + + private static Logger logger = Logger.getLogger(RecordEvaluationContext.class); + + /** + * contains all attributes which have been resolved at runtime + */ + private List attrs; + + /** + * defines the time when the policies have been resolved + */ + private Date execTime; + + /** + * defines (if applicable) which policy version has been used + */ + private long version; + + + public RecordEvaluationContext(RequestCtx request, AttributeFinder aFinder, + RevocationFinder rFinder, Long evaluationId) throws ParsingException { + super(request, aFinder, rFinder, true, evaluationId); + this.execTime = new Date(); + version = AttributeResolver.getPDPStatePolicyVersion(this); + } + + +// protected long getPDPStatePolicyVersion() { +// EvaluationResult evalResult = this.getAttribute(IPDPStateEvaluationContext.PDPSTATE_CATEGORY, +// IPDPStateEvaluationContext.PDPSTATE_ATTRIBUTETYPE, +// IPDPStateEvaluationContext.PDPSTATE_URI, +// IPDPStateEvaluationContext.PDPSTATE_ISSUER); +// +// if ( ((BagAttribute) evalResult.getAttributeValue()).size() > 1 ) { +// logger.error("Did not retreive a bag with one (" +((BagAttribute) evalResult.getAttributeValue()).size() + +// ") entry after attribute search for current svn policy version number; " + +// "PDP Dtate requires exactly one attribute to be defined"); +// return -1; +// } else if ( ((BagAttribute) evalResult.getAttributeValue()).size() == 1 ) { +// IntegerAttribute attrVal = (IntegerAttribute) ((BagAttribute) evalResult.getAttributeValue()).iterator().next(); +// logger.debug("Request " + super.getCurrentEvaluationId() + " will be executed under policy " + attrVal.getValue()); +// return attrVal.getValue(); +// } else { +// logger.debug("Could not resolve current policy version"); +// return -1; +// } +// } + + public void retreiveDesignatorAttributeSearch(URI category, URI attributeType, + URI attributeId, URI issuer, EvaluationResult evalResult) { + + //TODO why not only store the stuff at runtime and do the transformation aftwards? + + if ( ! (evalResult.getAttributeValue() instanceof BagAttribute) ) { + logger.warn("RecordEvaluationContext received a non-bag attribute"); + } else { + BagAttribute bAttr = (BagAttribute) evalResult.getAttributeValue(); + + if ( attrs == null ) { + attrs = new Vector(); + } + if (bAttr.isEmpty()) { + attrs.add(new DesignatorAttribute(attributeId, attributeType, category)); + if ( logger.isDebugEnabled() ) { + logger.debug("Result for attributeId " + attributeId + " of type " + attributeType + + ", category " + category + " is empty"); + } + } else { + DesignatorAttribute attr = new DesignatorAttribute(attributeId, attributeType, category); + + for ( AttributeValue value : bAttr.iterable()) { + attr.addBagValue(value.encode()); + } + attrs.add(attr); + if ( logger.isDebugEnabled() ) { + logger.debug("Added designatorAttr (" + attributeId + " of type " + attributeType + + ", category " + category +") with " + attr.getBagValues().size() + " values added to EvaluationContext"); + } + } + } + } + + /** + * + * @return the list of collected designators or null, if non have been collected + */ + public List getDesignatorAttributes() { + return attrs; + } + + public Date getExecTime() { + return execTime; + } + + public long getVersion() { + return version; + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/XACML2APIMapper.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/XACML2APIMapper.java new file mode 100644 index 0000000..ba30b24 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/XACML2APIMapper.java @@ -0,0 +1,86 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support; + +import java.util.Collection; +import java.util.List; +import java.util.Set; +import java.util.Vector; + +import org.apache.log4j.Logger; + +import eu.aniketos.securebpmn.xacml.api.ErrorType; +import eu.aniketos.securebpmn.xacml.api.ReasonType; +import eu.aniketos.securebpmn.xacml.api.SecurityError; +import eu.aniketos.securebpmn.xacml.api.autho.AuthoAttribute; +import eu.aniketos.securebpmn.xacml.api.autho.AuthoObligation; +import eu.aniketos.securebpmn.xacml.api.autho.AuthoResult; +import eu.aniketos.securebpmn.xacml.api.autho.Decision; + +import com.sun.xacml.Obligation; +import com.sun.xacml.ctx.Attribute; +import com.sun.xacml.ctx.ResponseCtx; +import com.sun.xacml.ctx.Result; + +public class XACML2APIMapper { + + private static final Logger logger = Logger.getLogger(XACML2APIMapper.class); + + public static AuthoResult getAuthoResult(ResponseCtx resCtx) throws SecurityError { + + AuthoResult authoResult = new AuthoResult(); + + if (resCtx.getResults().size() != 1 ) { + logger.error("Received unexpected number of results: " + resCtx.getResults().size()); + throw new SecurityError(ErrorType.CONFIGURATION_ERROR, ReasonType.PDE_ENGINE_ERROR, "Received unexpected number of results"); + } + + Result xacmlResult = resCtx.getResults().iterator().next(); + + authoResult.setDecision(Decision.getFromInt(xacmlResult.getDecision())); + authoResult.setObligations(transformObligations(xacmlResult.getObligations())); + authoResult.setStatusCode(xacmlResult.getStatus().getCode()); + authoResult.setStatusMessage(xacmlResult.getStatus().getMessage()); + + // TODO get missing attributes + + + return authoResult; + } + + public static List transformObligations(Set xacmlOblgs) { + if ( xacmlOblgs != null && xacmlOblgs.size() > 0 ) { + List oblgs = new Vector(); + + for ( Obligation xacmlOblg : xacmlOblgs ) { + AuthoObligation oblg = new AuthoObligation(xacmlOblg.getId()); + if ( xacmlOblg.getAssignments() != null && xacmlOblg.getAssignments().size() > 0 ) { + Collection attrs = new Vector(xacmlOblg.getAssignments().size()); + for ( Attribute xacmlAttr : xacmlOblg.getAssignments()) { + attrs.add(new AuthoAttribute(AuthoAttribute.OBLIGATION_CATEGORY, + xacmlAttr.getId(), xacmlAttr.getValue().getType(), xacmlAttr.getValue().encode())); + } + oblg.setParameters(attrs); + } + oblgs.add(oblg); + } + return oblgs; + } else { + return null; + } + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/XACMLDecoder.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/XACMLDecoder.java new file mode 100644 index 0000000..d7444dd --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/XACMLDecoder.java @@ -0,0 +1,168 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support; + +import java.io.ByteArrayInputStream; +import java.net.URI; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.log4j.Logger; + + +import eu.aniketos.securebpmn.xacml.api.SecurityError; +import eu.aniketos.securebpmn.xacml.api.ErrorType; +import eu.aniketos.securebpmn.xacml.api.ReasonType; +import eu.aniketos.securebpmn.xacml.api.autho.AttributeIdentifier; +import eu.aniketos.securebpmn.xacml.api.autho.AuthoAttribute; +import eu.aniketos.securebpmn.xacml.api.idm.IdInfo; +import eu.aniketos.securebpmn.xacml.support.helper.ResourceCreator; + +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; +import com.sun.xacml.ctx.Attribute; +import com.sun.xacml.ctx.RequestCtx; +import com.sun.xacml.ctx.RequestElement; +import com.sun.xacml.ctx.ResponseCtx; + + + + +/** + * Helper class, decoding XML strings to XACML Objects + * + */ +public class XACMLDecoder { + + private static Logger logger = Logger.getLogger(XACMLDecoder.class); + + public static RequestCtx decodeRequestCtx(String request) throws SecurityError { + RequestCtx requ; + try { + requ = RequestCtx.getInstance(new ByteArrayInputStream(request.getBytes())); + } catch (ParsingException e) { + logger.error("ParsingException during parsing xacmlRequest", e); + throw new SecurityError(ErrorType.AUTHORIZATION_FAILED, ReasonType.INVALID_XACML, "ParsingError: " + e.getMessage()); + } + return requ; + } + + public static ResponseCtx decodeResponseCtx(String reponse) throws SecurityError { + ResponseCtx resp; + try { + resp = ResponseCtx.getInstance(new ByteArrayInputStream(reponse.getBytes())); + } catch (ParsingException e) { + logger.error("ParsingException during parsing xacmlRequest", e); + throw new SecurityError(ErrorType.AUTHORIZATION_FAILED, ReasonType.INVALID_XACML, "ParsingError: " + e.getMessage()); + } + return resp; + } + + public static RequestCtx decodeRequestCtx(IdInfo authinfo, URI resource, + String action) throws SecurityError { + + Set requElems = new HashSet(); + + try { + requElems.add(Category.SUBJECT.getRequestElement(authinfo.getUserId())); + } catch (ParsingException e) { + logger.error("Could not create subject element from subject " + authinfo.getUserId() + ": ParsingException: " + e.getMessage(), e); + } + + requElems.add(( (ResourceCreator) Category.RESOURCE.getElementCreator()).getRequestElement(resource)); + + if ( action != null ) { + try { + requElems.add(Category.ACTION.getRequestElement(action)); + } catch (ParsingException e) { + logger.error("Could not create action element from action " + action + ": ParsingException: " + e.getMessage(), e); + } + } + + return new RequestCtx(requElems, null, null); + } + + + public static RequestCtx decodeRequestCtx(IdInfo idInfo, URI resource, + String action, List attributes) throws SecurityError { + + //"cheap" creation if no attributes are present + if ( attributes == null || attributes.size() == 0 ) { + return decodeRequestCtx(idInfo, resource, action); + } else { + + Map> attrsPerCat = new HashMap>(); + + Set subjects = new HashSet(); + try { + Attribute subjectId = Category.SUBJECT.getAttributeDefaultType(idInfo.getUserId()); + subjects.add(subjectId); + } catch (ParsingException e) { + logger.error("Could not create subject element from subject " + idInfo.getUserId() + ": ParsingException: " + e.getMessage(), e); + } + attrsPerCat.put(Category.SUBJECT, subjects); + + //RESOURCE as URI + Set resources = new HashSet(); + resources.add( ( (ResourceCreator) Category.RESOURCE.getElementCreator()).getAttributeDefaultType(resource)); + attrsPerCat.put(Category.RESOURCE, resources); + + //ACTION if != NULL + if (action != null ) { + Set actions = new HashSet(); + try { + actions.add(Category.ACTION.getAttributeDefaultType(action)); + } catch (ParsingException e) { + // TODO log + e.printStackTrace(); + } + attrsPerCat.put(Category.ACTION, actions); + } + + for (AuthoAttribute attr : attributes) { + AttributeIdentifier attrId = attr.getAttributeIdentifier(); + Category cat = Category.getCategory(attrId.getCategory()); + Set attrs; + if ( attrsPerCat.containsKey(cat) ) { + attrs = attrsPerCat.get(cat); + } else { + attrs = new HashSet(); + attrsPerCat.put(cat, attrs); + } + try { + attrs.add(cat.getAttribute(attrId.getAttributeId(), attrId.getAttributeType(), attr.getValue())); + } catch (ParsingException e) { + // TODO log + e.printStackTrace(); + } catch (UnknownIdentifierException e) { + // TODO log + e.printStackTrace(); + } + } + + Set requElems = new HashSet(); + + for (Category cat : attrsPerCat.keySet()) { + requElems.add(cat.getRequestElement(attrsPerCat.get(cat))); + } + + return new RequestCtx(requElems, null, null); + } + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/XACMLEncoder.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/XACMLEncoder.java new file mode 100644 index 0000000..a79e5f3 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/XACMLEncoder.java @@ -0,0 +1,86 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support; + +import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +import org.apache.log4j.Logger; + +import com.sun.xacml.ctx.RequestCtx; +import com.sun.xacml.ctx.ResponseCtx; + +/** + * Helper class, encoding XACML Objects to its XML representation + * + * + */ +public class XACMLEncoder { + + + public static final String ERROR_EVALUATING_REQUEST = "todo"; + + private static Logger logger = Logger.getLogger(XACMLEncoder.class); + + + /** + * Helper function, encodes a com.sun.xacml.ctx.ResponseCtx to a String, containing a XML representation + * @param response + * @return XML representation of response + */ + public static String encodeResponseCtx(ResponseCtx response) { + ByteArrayOutputStream bAOut = new ByteArrayOutputStream(); + BufferedOutputStream bOut = new BufferedOutputStream(bAOut); + + try { + response.encode(bAOut, null); + bOut.flush(); + } catch (UnsupportedEncodingException e) { + logger.error("Unexpected UnsupportedEncodingException during encoding ResponseCtx to String:" + e.getMessage(), e ); + return ERROR_EVALUATING_REQUEST; + } catch (IOException e) { + logger.error("Unexpected IOException during encoding ResponseCtx to String:" + e.getMessage(), e ); + return ERROR_EVALUATING_REQUEST; + } + + return bAOut.toString(); + } + + /** + * Helper function, encodes a com.sun.xacml.ctx.RequestCtx to a String, containing a XML representation + * @param request + * @return XML representation of request + */ + public static String encodeRequestCtx(RequestCtx request) { + ByteArrayOutputStream bAOut = new ByteArrayOutputStream(); + BufferedOutputStream bOut = new BufferedOutputStream(bAOut); + + try { + request.encode(bAOut, null); + bOut.flush(); + } catch (UnsupportedEncodingException e) { + logger.error("Unexpected UnsupportedEncodingException during encoding ResponseCtx to String:" + e.getMessage(), e ); + return ERROR_EVALUATING_REQUEST; + } catch (IOException e) { + logger.error("Unexpected IOException during encoding ResponseCtx to String:" + e.getMessage(), e ); + return ERROR_EVALUATING_REQUEST; + } + + return bAOut.toString(); + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/attr/EvaluationIdAttribute.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/attr/EvaluationIdAttribute.java new file mode 100644 index 0000000..b2469ad --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/attr/EvaluationIdAttribute.java @@ -0,0 +1,113 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support.attr; + +import java.net.URI; + +import org.apache.log4j.Logger; +import org.w3c.dom.Node; + +import eu.aniketos.securebpmn.xacml.support.finder.IEvaluationIdContext; + +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.ParsingException; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.cond.EvaluationResult; + +/** + * + * This attribute represents an urn:type:evaluationId which has to be evaluated at runtime by the xacml engine. + * Within the evaluation, the evaluation ID is read from the evaluation context and stored within the attribute. + * + */ +public class EvaluationIdAttribute extends AttributeValue { + + + public static final String identifier = "urn:type:evaluationId"; + public static final URI identifierURI = URI.create(identifier); + + public static final Long INVALID = new Long(-1); + + private static Logger logger = Logger.getLogger(EvaluationIdAttribute.class); + + public static final String RUNTIME = "RUNTIME"; + + private Long value; + + + + public EvaluationIdAttribute(Long value) { + super(identifierURI); + this.value = value; + } + + protected EvaluationIdAttribute(URI type) { + super(type); + } + + @Override + public EvaluationResult evaluate(EvaluationCtx context) { + + if ( value == null || value.longValue() == -1 ) { + if ( context instanceof IEvaluationIdContext ) { + //retreive evaluationID from current context + value = ((IEvaluationIdContext) context).getCurrentEvaluationId(); + } else { + logger.warn("Received non-IEvaluationIdContext: Could not determine evaluation ID"); + value = new Long(-1); + } + } + return new EvaluationResult(this); + } + + public static EvaluationIdAttribute getInstance(String value) { + if ( value == null || RUNTIME.equals(value) ) { + return new EvaluationIdAttribute(new Long(-1)); + } else { + try { + long newValue = Long.parseLong(value); + return new EvaluationIdAttribute(newValue); + } catch (NumberFormatException e) { + logger.warn("Could not transfer evaluationID \"" + value + "\" to long value: " + e.getMessage()); + return new EvaluationIdAttribute(new Long(-1)); + } + } + } + + public static EvaluationIdAttribute getInstance(Node root) throws ParsingException { + if (root.getFirstChild() != null) { + return getInstance(root.getFirstChild().getNodeValue()); + } else { + return new EvaluationIdAttribute(new Long(-1)); + } + } + + + @Override + public String encode() { + return value.toString(); + } + + @Override + public boolean isDynamic() { + return true; + } + + public Long getEvaluationId() { + return value; + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/attr/proxy/EvaluationIdAttributeProxy.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/attr/proxy/EvaluationIdAttributeProxy.java new file mode 100644 index 0000000..04f788c --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/attr/proxy/EvaluationIdAttributeProxy.java @@ -0,0 +1,44 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support.attr.proxy; + +import org.w3c.dom.Node; + +import eu.aniketos.securebpmn.xacml.support.attr.EvaluationIdAttribute; + +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.attr.AttributeProxy; +import com.sun.xacml.attr.AttributeValue; + +public class EvaluationIdAttributeProxy implements AttributeProxy { + //private static Logger logger = Logger.getLogger(EvaluationIdAttributeProxy.class); + + public AttributeValue getInstance(Node root) throws Exception { + return EvaluationIdAttribute.getInstance(root); + } + + public AttributeValue getInstance(String value) throws Exception { + return EvaluationIdAttribute.getInstance(value); + } + + public EvaluationIdAttributeProxy() { + + } + + public void setConfigurationStore(ConfigurationStore confStore) { + + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/comb/LatticeCombiningAlgorithm.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/comb/LatticeCombiningAlgorithm.java new file mode 100644 index 0000000..229e495 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/comb/LatticeCombiningAlgorithm.java @@ -0,0 +1,297 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support.comb; + +import java.net.URI; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.log4j.Logger; + +import eu.aniketos.securebpmn.xacml.support.AttributeResolver; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.MatchResult; +import com.sun.xacml.Obligation; +import com.sun.xacml.PolicyTreeElement; +import com.sun.xacml.attr.StringAttribute; +import com.sun.xacml.combine.CombinerElement; +import com.sun.xacml.combine.CombinerParameter; +import com.sun.xacml.combine.PolicyCombiningAlgorithm; +import com.sun.xacml.ctx.Result; + +public class LatticeCombiningAlgorithm extends PolicyCombiningAlgorithm { + + + public static final String algId = + "urn:policy-combining-algorithm:policy-lattice"; + + private static URI identifierURI = URI.create(algId); + + private static final String LATTICE_IDENTIFIER = "urn:policyLattice:latticeIdentifier"; + + private static Logger logger = Logger.getLogger(LatticeCombiningAlgorithm.class); + + private Map> latticeCache = new HashMap>(); + + public LatticeCombiningAlgorithm() { + super(identifierURI); + } + + @Override + public Result combine(EvaluationCtx evalCtx, List combParam, + List combElem) { + + // store the first deny we get, we will return it in case we do not find a permit + Result firstDeny = null; + // store the first indeterminate + Result firstIndeterminate = null; + + // create a cache where all permits are stored; + // we may need the result itself to get the obligations + Map permitCache = new HashMap(); + // create a cache where the results of all deny policies are stored + // deny policies could be executed several time, i.e., + // remember both the result and if we executed it + Map denyCache = new HashMap(); + + // get the active policies from the context once + Set activePolicies = getActivePolicies(evalCtx); + + // create (or get from cache) the policy lattice we want to evaluate + PolicyLattice lattice = getLattice(evalCtx, combParam, combElem); + + // iterate over the lattice (i.e., level per level) + for ( LatticeElem elem : lattice ) { + // check if current element is an active policy + if ( isActive(elem, lattice, activePolicies) ) { + boolean permitted = false, denied = false; + + // store a permit if we find it in this policy + Result permit = null; + // first, check for an inherited permit, then for a permit + LatticeElem inhPermit = getInheritedPermit(elem, permitCache); + if ( inhPermit != null ) { + permitted = true; + } else if (elem.getPermitPolicy() != null ) { + // no inherited permit, we have to evaluate the current permit policy + Result res = evaluate(elem.getPermitPolicy(), evalCtx); + if ( res.getDecision() == Result.DECISION_INDETERMINATE ) { + if ( firstIndeterminate == null ) { + firstIndeterminate = res; + } + continue; // this policy will not provide a result, go to next + } else if ( res.getDecision() == Result.DECISION_PERMIT ) { + // we found a permit, store it to cache (in the current policy it may be overwritten by a deny) + permitCache.put(elem.getIdentifier(), res); + permit = res; + permitted = true; + } else if ( res.getDecision() == Result.DECISION_DENY && firstDeny == null) { + firstDeny = res; + continue; // we do not need to evaluate the deny policies if we do not have a permit + } + } + + if ( permitted ) { + // check if there is an inherited deny: iterate over all extending policies, i.e, downwards + for ( LatticeElem extending : elem.downwards() ) { + // check if extending policy has a deny policy defined + if ( extending.getDenyPolicy() != null ) { + Result res; + // check if we already evaluated this policy + if ( denyCache.containsKey(extending.getIdentifier()) ) { + res = denyCache.get(extending.getIdentifier()); + } else { + // else, evaluate it and store it into the cache + res = evaluate(extending.getDenyPolicy(), evalCtx); + denyCache.put(extending.getIdentifier(), res); + } + // check if the current deny policy denies this request + if ( res.getDecision() == Result.DECISION_INDETERMINATE ) { + if ( firstIndeterminate == null ) { + firstIndeterminate = res; + } + } else if ( res.getDecision() == Result.DECISION_DENY ) { + denied = true; + if ( firstDeny == null ) { + firstDeny = res; + } + break; // we have found a deny, do not need to look further + } + } + } + // we end up here only if we found a permit, check if we also found a deny + if ( ! denied) { + // if we did not find a permit for this policy + if ( permit == null ) { + // we got an inherited permit: we have to remove the lattice obligations + // from this permit and attach the lattice obligations of the current policy + permit = permitCache.get(inhPermit.getIdentifier()); + AbstractPolicy curPolicy = (AbstractPolicy) elem.getPermitPolicy(); + AbstractPolicy inhPolicy = (AbstractPolicy) inhPermit.getPermitPolicy(); + + Set obligations = permit.getObligations(); + + // remove obligations defined by inhPolicy + for ( Obligation oblgRm : inhPolicy.getObligations() ) { + for ( Obligation oblg : obligations ) { + if ( oblg.getId().equals(oblgRm) ) { + obligations.remove(oblg); + break; + } + } + } + // add obligations from current policy + for ( Obligation oblg : curPolicy.getObligations() ) { + obligations.add(oblg.evaluate(evalCtx)); + } + permit = new Result(permit.getDecision(), evalCtx, obligations); + } + return permit; + } + } + } + } + if ( firstIndeterminate != null ) { + return firstIndeterminate; + } else if ( firstDeny != null ) { + return firstDeny; + } else { + return new Result(Result.DECISION_DENY, evalCtx); + } + } + + private Result evaluate(PolicyTreeElement policy, EvaluationCtx evalCtx) { + + evalCtx.newEvent(policy); + + MatchResult match = policy.match(evalCtx); + Result res = null; + + if (match.getResult() == MatchResult.INDETERMINATE) { + res = new Result(Result.DECISION_INDETERMINATE, evalCtx); + } else if (match.getResult() == MatchResult.NO_MATCH) { + res = new Result(Result.DECISION_NOT_APPLICABLE, evalCtx); + } else if (match.getResult() == MatchResult.MATCH) { + res = policy.evaluate(evalCtx); + } + evalCtx.closeCurrentEvent(res); + return res; + } + + private boolean isActive(LatticeElem elem, PolicyLattice lattice, Set activePolicies) { + if ( activePolicies.contains(elem.getIdentifier())) { + return true; + } else { + for ( LatticeElem extending : elem.downwards() ) { + if ( activePolicies.contains(extending.getIdentifier())) { + return true; + } + } + } + return false; + } + + private LatticeElem getInheritedPermit(LatticeElem elem, Map permitCache) { + for ( LatticeElem extended : elem.upwards() ) { + if ( permitCache.containsKey(extended)) { + return extended; + } + } + return null; + } + + + + private PolicyLattice getLattice(EvaluationCtx evalCtx, List combParam, + List combElem) { + + + String latticeId = getLatticeIdentifier(combParam); + + PolicyLattice lattice = null; + if ( latticeId != null) { + Map latticeVerCache = null; + if ( latticeCache.containsKey(latticeId) ) { + latticeVerCache = latticeCache.get(latticeId); + } else { + latticeVerCache = new HashMap(); + latticeCache.put(latticeId, latticeVerCache); + } + + Long policyVers = getPolicyVersion(evalCtx); + if ( latticeVerCache.containsKey(policyVers)) { + return latticeVerCache.get(policyVers); + } else { + lattice = new PolicyLattice(latticeId, combElem); + latticeVerCache.put(policyVers, lattice); + return lattice; + } + } else { + return new PolicyLattice(null, combElem); + } + +// if ( latticeCache.containsKey(policyVers) && +// latticeCache.get(policyVers).containsKey(latticeId) ) { +// lattice = latticeCache.get(policyVers).get(latticeId); +// } else { +// Map latticeVerCache = null; +// if ( latticeCache.containsKey(policyVers) ) { +// latticeVerCache = latticeCache.get(policyVers); +// } else { +// latticeVerCache = new HashMap(); +// latticeCache.put(policyVers, latticeVerCache); +// } +// lattice = new PolicyLattice(latticeId, combElem); +// latticeVerCache.put(latticeId, lattice); +// } +// return lattice; + } + + + private String getLatticeIdentifier(List combParam) { + + if ( combParam != null && combParam.size() > 0 ) { + for ( CombinerParameter param : combParam ) { + if ( LATTICE_IDENTIFIER.equals(param.getName()) ) { + if ( param.getValue() instanceof StringAttribute ) { + return ((StringAttribute)param.getValue()).getValue(); + } else { + logger.warn("Found " + LATTICE_IDENTIFIER + " which is not of type string (" + param.getValue().encode() + ")"); + } + } + } + } + + logger.warn("Did not find a " + LATTICE_IDENTIFIER + " for evaluating the LatticeCombiningAlgorithm " + + (getRuntimeInfo() == null ? "" : getRuntimeInfo().getLocationMsgRuntime())); + return null; + } + + private Long getPolicyVersion(EvaluationCtx evalCtx) { + return new Long(AttributeResolver.getPDPStatePolicyVersion(evalCtx)); + } + + + private Set getActivePolicies(EvaluationCtx evalCtx) { + return AttributeResolver.getActivePolicies(evalCtx); + } + + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/comb/LatticeElem.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/comb/LatticeElem.java new file mode 100644 index 0000000..581eb74 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/comb/LatticeElem.java @@ -0,0 +1,223 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support.comb; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; + +import eu.aniketos.securebpmn.xacml.support.comb.PolicyLatticeIterator.MODE; + +import com.sun.xacml.PolicyTreeElement; +import com.sun.xacml.attr.AttributeValue; +import com.sun.xacml.attr.StringAttribute; +import com.sun.xacml.combine.CombinerElement; +import com.sun.xacml.combine.CombinerParameter; + +public class LatticeElem { + + private int level = 0; + private String identifier; + /** + * policy IDs this policy extends, defined as combiner parameter + */ + private List extendedPolicyIds; + /** + * policies which are extended by this policy (i.e., upwards) + */ + private List extendedPolicies; + /** + * policies extending this policy (i.e, downwards) + */ + private List extendingPolicies; + private PolicyTreeElement permitPolicy, denyPolicy; + + private static final String + POLICY_IDENDIFIER = "urn:policyLattice:identifier", + POLICY_TYPE = "urn:policyLattice:type", + EXTENDS_POLICY = "urn:policyLattice:extends"; + + private static final Logger logger = Logger.getLogger(LatticeElem.class); + + public static LatticeElem addLatticeElem(CombinerElement combElem, + Map elems) { + +// if ( ! (combElem.getElement() instanceof AbstractPolicy) ) { +// logger.warn("LatticeElement has to be an instance of AbstractPolicy (got " + combElem.getElement().getClass().toString() + ")"); +// return null; +// } +// +// AbstractPolicy policy = (AbstractPolicy) combElem.getElement(); + + // read parameters for policy + List params = combElem.getParameters(); + //List params = policy.getCombiningParameters(); + String identifier = null, type = null; + List extendedPolicies = null; + if ( params != null && params.size() > 0 ) { + for ( CombinerParameter param : params ) { + String name = param.getName(); + if ( POLICY_IDENDIFIER.equals(name) ) { + identifier = getString(name, param.getValue()); + } else if ( POLICY_TYPE.equals(name) ) { + type = getString(name, param.getValue()); + } else if ( EXTENDS_POLICY.equals(name)) { + if ( extendedPolicies == null ) { + extendedPolicies = new ArrayList(); + } + extendedPolicies.add(getString(name, param.getValue())); + } else { + logger.warn("Unknown parameter " + name); + } + } + } else { + logger.warn("No CombinerParamters defined for " + combElem.getElement().getId()); + } + + if ( identifier == null ) { + logger.warn("Cannot read policy " + combElem.getElement().getId() + " without defining " + POLICY_IDENDIFIER + " as combiner parameter"); + return null; + } else { + LatticeElem elem; + if ( elems.containsKey(identifier)) { + elem = elems.get(identifier); + } else { + elem = new LatticeElem(identifier); + elems.put(identifier, elem); + } + + if ( extendedPolicies != null ) { + if ( elem.extendedPolicyIds != null ) { + logger.warn("For policy with ID " + identifier + " there are already extending policies defined"); + } else { + elem.extendedPolicyIds = extendedPolicies; + } + } + + if ( type != null ) { + if ( "permit".equals(type.toLowerCase()) ) { + if ( elem.permitPolicy != null ) { + logger.warn("Overwriting permit policy for ID " + identifier); + } + elem.permitPolicy = combElem.getElement(); + } else if ( "deny".equals(type.toLowerCase()) ) { + if ( elem.denyPolicy != null ) { + logger.warn("Overwriting deny policy for ID " + identifier); + } + } + } else { + // assume default value + if ( elem.permitPolicy != null ) { + logger.warn("Overwriting permit policy for ID " + identifier); + } + elem.permitPolicy = combElem.getElement(); + } + return elem; + } + } + + private LatticeElem(String identifer) { + this.identifier = identifer; + } + + + private static String getString(String name, AttributeValue value ) { + if ( value instanceof StringAttribute ) { + return ((StringAttribute) value).getValue(); + } else { + logger.warn("Attribute " + name + " was not an String Attribute"); + return null; + } + } + + + + public int getLevel() { + return level; + } + + public void setLevel(int level) { + this.level = Math.max(this.level, level); + } + + public void resetLeve(int level) { + this.level = level; + } + + public PolicyTreeElement getPermitPolicy() { + return permitPolicy; + } + + public void setPermitPolicy(PolicyTreeElement permitPolicy) { + this.permitPolicy = permitPolicy; + } + + public PolicyTreeElement getDenyPolicy() { + return denyPolicy; + } + + public void setDenyPolicy(PolicyTreeElement denyPolicy) { + this.denyPolicy = denyPolicy; + } + + public String getIdentifier() { + return identifier; + } + + public List getExtendedPolicyIds() { + return extendedPolicyIds; + } + + public void addExtendingPolicy(LatticeElem elem) { + if ( this.extendingPolicies == null) { + this.extendingPolicies = new ArrayList(); + } + this.extendingPolicies.add(elem); + } + + public List getExtendingPolicies() { + return this.extendingPolicies; + } + + public void resolveExtendedPolicies(Map policies) { + if ( this.extendedPolicyIds != null && + this.extendedPolicies.size() > 0 ) { + this.extendingPolicies = new ArrayList(); + + for ( String elemId : extendedPolicyIds) { + if ( policies.containsKey(elemId)) { + extendedPolicies.add(policies.get(elemId)); + } else { + logger.warn("Could not find a policy with ID " + elemId + " to resolve extended policies of policy " + identifier); + } + } + } + } + + public List getExtendedPolicies() { + return this.extendedPolicies; + } + + public Iterable downwards() { + return new PolicyLatticeIterator(this, MODE.DOWNWARDS); + } + + public Iterable upwards() { + return new PolicyLatticeIterator(this, MODE.UPWARDS); + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/comb/PolicyLattice.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/comb/PolicyLattice.java new file mode 100644 index 0000000..e6327b3 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/comb/PolicyLattice.java @@ -0,0 +1,105 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support.comb; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; + +import eu.aniketos.securebpmn.xacml.support.comb.PolicyLatticeIterator.MODE; + +import com.sun.xacml.combine.CombinerElement; + +public class PolicyLattice implements Iterable { + + private List level1; + + private Map policies; + + private static Logger logger = Logger.getLogger(PolicyLattice.class); + + public PolicyLattice(String latticeIdentifier, List combElem) { + if ( logger.isDebugEnabled() ) { + logger.debug("Creating PolicyLattice " + + (latticeIdentifier == null ? "without identifier" : latticeIdentifier) + " with " + + combElem.size() + " elements"); + } + policies = new HashMap(); + level1 = new ArrayList(); + + + // read all policies + for (int i = 0; i < combElem.size(); ++i ) { + LatticeElem elem = LatticeElem.addLatticeElem(combElem.get(i), policies); + if (logger.isDebugEnabled() && elem != null ) { + logger.debug("Read policy element with ID \"" + elem.getIdentifier() + + "\" with " + (elem.getExtendedPolicyIds() == null ? 0 : elem.getExtendedPolicyIds().size()) + " extended policy definitions"); + } + } + + // + for ( LatticeElem elem : policies.values() ) { + elem.resolveExtendedPolicies(policies); + if ( elem.getExtendedPolicyIds() == null || + elem.getExtendedPolicyIds().size() == 0 ) { + level1.add(elem); + logger.debug("Added " + elem.getIdentifier() + " as " + level1.size() + "th element as level 1 element"); + } else { + for ( String extPol : elem.getExtendedPolicyIds()) { + if ( policies.containsKey(extPol) ) { + policies.get(extPol).addExtendingPolicy(elem); + } else { + logger.warn("Policy " + elem.getIdentifier() + " defined extension to " + extPol + ", but did not find policy"); + } + } + } +// if ( policies.containsKey(elem.getExtendedPolicy() )) { +// policies.get(elem.getExtendedPolicy()).addChild(elem); +// logger.debug("Added policy " + elem.getIdentifier() +// + " as child to policy" + elem.getExtendedPolicy() ); +// } else { +// logger.warn("Policy with id " + elem.getIdentifier() + +// " defines extending an unkown policy with id " + elem.getExtendedPolicy()); +// } + } + for ( LatticeElem elem : level1 ) { + setPolicyLevel(elem, 1); + } + } + + + private void setPolicyLevel(LatticeElem elem, int level) { + elem.setLevel(level); + if ( elem.getExtendingPolicies() != null ) { + for ( LatticeElem refElem : elem.getExtendingPolicies() ) { + setPolicyLevel(refElem, level + 1); + } + } + } + + + public Iterator iterator() { + return new PolicyLatticeIterator(level1, MODE.DOWNWARDS); + } + + + + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/comb/PolicyLatticeIterator.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/comb/PolicyLatticeIterator.java new file mode 100644 index 0000000..f4e609f --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/comb/PolicyLatticeIterator.java @@ -0,0 +1,95 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support.comb; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; + +public class PolicyLatticeIterator implements Iterator, Iterable { + + enum MODE { + UPWARDS, // iterates over all refining policies, i.e., policies with lower levels + DOWNWARDS // iterates over all extending policies, i.e., policies with higher levels + } + + Queue todos; + + MODE mode; + + /** + * + * @param elements should be all on the same level + */ + PolicyLatticeIterator(List elements, MODE mode) { + this.mode = mode; + todos = new LinkedList(); + for ( LatticeElem elem : elements) { + todos.add(elem); + } + } + + PolicyLatticeIterator(LatticeElem element, MODE mode) { + this.mode = mode; + todos = new LinkedList(); + todos.add(element); + } + + public boolean hasNext() { + if ( todos.size() > 0 ) { + return true; + } else { + return false; + } + } + + public LatticeElem next() { + LatticeElem next = todos.remove(); + if ( mode == MODE.DOWNWARDS ) { + if ( next.getExtendingPolicies() != null ) { + for ( LatticeElem elem : next.getExtendingPolicies() ) { + // check if element to put on queue + if ( elem.getLevel() + 1 == next.getLevel() && // put on queue only if on next level + ( elem.getExtendedPolicyIds().size() == 1 || // if referenced elem has only one refining (extends) relation + ! todos.contains(elem) ) ) { // or, if it has several, check that it is not already on the queue + todos.add(elem); + } + } + } + } else if ( mode == MODE.UPWARDS ) { + if ( next.getExtendedPolicyIds() != null ) { + for ( LatticeElem elem : next.getExtendedPolicies() ) { + if ( elem.getLevel() -1 == next.getLevel() && // put on queue only if on next (upper) level + ( elem.getExtendingPolicies().size() == 1 || // if referenced elem has only one extending (refines) relation + ! todos.contains(elem))) { // or, if it has severl, that that it is not alrey on the queue + todos.add(elem); + } + } + } + } + return next; + } + + public void remove() { + throw new RuntimeException("remove is not permitted by PolicyLatticeIterator"); + } + + public Iterator iterator() { + return this; + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/finder/FilePolicyModule.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/finder/FilePolicyModule.java new file mode 100644 index 0000000..8ca2b9b --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/finder/FilePolicyModule.java @@ -0,0 +1,283 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support.finder; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.net.URI; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Vector; + +import org.apache.log4j.Logger; + +import com.sun.xacml.AbstractPolicy; +import com.sun.xacml.ConfigurationStore; +import com.sun.xacml.EvaluationCtx; +import com.sun.xacml.MatchResult; +import com.sun.xacml.ParsingException; +import com.sun.xacml.PolicyMetaData; +import com.sun.xacml.VersionConstraints; +import com.sun.xacml.ctx.Result; +import com.sun.xacml.ctx.Status; +import com.sun.xacml.finder.PolicyFinder; +import com.sun.xacml.finder.PolicyFinderModule; +import com.sun.xacml.finder.PolicyFinderResult; +import com.sun.xacml.support.finder.PolicyReader; + +/** + * + * PolicyFinderModule which allows to load policies by filename and folder + *
      + * When searching for policies, only main (entry) policies are searched, + * i.e., only policies with an "main" at the end are loaded + * + */ +public class FilePolicyModule extends PolicyFinderModule { + + private File schemaFile; + + // the filenames for the files we'll load + private Set fileNames; + private Set folders; + + private Map policies; + + private Map mainPolicies; + + private static final Logger logger = Logger.getLogger(FilePolicyModule.class); + + // configuration: keep track of lines when loadig policies (slow! use only for debugging!) + protected boolean useLines = false, enf_useLines = false; + + protected Map confParams = new HashMap(); + + + protected static final String CONF_PREFIX = "conf:", + FOLDER_PREFIX = "folder:", + FILE_PREFIX = "file:", + CONF_USELINES = "useLines"; + + + public FilePolicyModule() { + fileNames = new HashSet(); + folders = new HashSet(); + policies = new HashMap(); + mainPolicies = new HashMap(); + + String schemaName = + System.getProperty(PolicyReader.POLICY_SCHEMA_PROPERTY); + + if (schemaName != null) { + this.schemaFile = new File(schemaName); + } + } + + public FilePolicyModule(List fileNames) { + this(); + + if (fileNames != null) { + for ( String fileName : fileNames ) { + if ( fileName.startsWith(CONF_PREFIX) ) { + String tmp = fileName.substring(5); + try { + String confId = tmp.substring(0, tmp.indexOf(":")); + String value = tmp.substring(tmp.indexOf(":") + 1); + confParams.put(confId, value); + } catch(Exception e) { + logger.warn("Could not add configuration: " + tmp); + } + } else if ( fileName.startsWith(FOLDER_PREFIX)) { + this.folders.add(fileName.substring(7)); + } else if ( fileName.startsWith(FILE_PREFIX) ) { + this.fileNames.add(fileName.substring(5)); + } else { + this.fileNames.add(fileName); + } + } + } + if ( enf_useLines ) { + useLines = true; + } else if ( confParams.containsKey(CONF_USELINES)) { + useLines = getBool(confParams.get(CONF_USELINES)); + } + } + + @Override + public boolean isRequestSupported() { + return true; + } + + @Override + public void init(PolicyFinder finder) { + Object o = finder.getPDPConfiguration().getCustomAttr(ConfigurationStore.BASEDIR); + String baseDir = ""; + if ( o != null) { + baseDir = (String) o; + } + + PolicyReader reader = new PolicyReader(finder, + java.util.logging.Logger.getLogger(FilePolicyModule.class.getName()), + this.schemaFile, this.useLines); + + for (String fname : this.fileNames ) { + try { + AbstractPolicy policy = + reader.readPolicy(new FileInputStream(baseDir + fname), fname); + addPolicy(policy); + } catch (FileNotFoundException fnfe) { + logger.warn("File couldn't be read: "+ fname, fnfe); + } catch (ParsingException e) { + logger.warn("Error reading policy from file " + fname + ": " + e.getMessage(), e); + } + } + + for ( String sFolder : this.folders ) { + File folder = new File(baseDir + sFolder); + File[] files = folder.listFiles(); + for ( File f : files ) { + String name_lower = f.getName().toLowerCase(); + if ( name_lower.endsWith(".xacml")) { + try { + AbstractPolicy policy = reader.readPolicy(new FileInputStream(f), f.getName()); + addPolicy(policy); + } catch (FileNotFoundException e) { + logger.warn("File couldn't be read: "+ f.getName(), e); + } catch (ParsingException e) { + logger.warn("Error reading policy from file " + f.getName(), e); + } + } + } + } + logger.info("Loaded " + policies.size() + " policies, " + mainPolicies.size() + " main policies"); + } + + @Override + public PolicyFinderResult findPolicy(EvaluationCtx context) { + logger.debug("FilePolicyModule.findPolicy"); + + context.newEvent(this); + AbstractPolicy match = null; + for ( AbstractPolicy policy : this.mainPolicies.values() ) { + context.newEvent(policy); + logger.debug("Check match for Policy "+ policy.getId()); + + MatchResult mResult = policy.match(context); + int iResult = mResult.getResult(); + if ( iResult == MatchResult.NO_MATCH ) { + context.closeCurrentEvent(new Result(Result.DECISION_NOT_APPLICABLE)); + } else if ( iResult == MatchResult.MATCH ) { + context.closeCurrentEvent(); + if ( match == null ) { + match = policy; + } else { + logger.error("Multiple main policies are matching: first: " + match.getId() + " - " + policy.getId()); + List statusCodes = new Vector(); + statusCodes.add(Status.STATUS_PROCESSING_ERROR); + Status errorStatus = new Status(statusCodes, "Error in PDP Configuration: Multiple matching main policies"); + context.closeCurrentEvent(Result.INDETERMINATE); + return new PolicyFinderResult(errorStatus); + //throw new TopLevelPolicyException(mResult.getStatus(), "Multiple main policies are matching"); + } + } else if ( iResult == MatchResult.INDETERMINATE ) { + context.closeCurrentEvent(); + context.closeCurrentEvent(new Result(Result.DECISION_INDETERMINATE, context)); + return new PolicyFinderResult(mResult.getStatus()); + } + } + + if (match == null) { + context.closeCurrentEvent(); + logger.debug("Found no matching main policy"); + return new PolicyFinderResult(); + } + context.closeCurrentEvent(match.getId().toString()); + logger.debug("Found one matching main policy: " + match.getId()); + return new PolicyFinderResult(match); +// } catch (TopLevelPolicyException e) { +// logger.error("Could not find Policy (TopLevelPolicyException): " + e.getMessage()); +// e.printStackTrace(); +// context.closeCurrentEvent(); +// return new PolicyFinderResult(e.getStatus()); +// } + } + + public boolean addPolicy(String filename) { + return this.fileNames.add(filename); + } + + + protected void addPolicy(AbstractPolicy policy) { + URI policyId = policy.getId(); + this.policies.put(policyId,policy); + if ( policyId.toString().endsWith("main") ) { + this.mainPolicies.put(policyId, policy); + } + } + + + + protected static boolean getBool(String value) { + try { + Boolean val = new Boolean(value); + return val.booleanValue(); + } catch (Exception e) { + logger.warn( "Could not read boolean value " + value + "; Using false as default"); + return false; + } + } + + @Override + public boolean isIdReferenceSupported() { + return true; + } + + @Override + public PolicyFinderResult findPolicy(EvaluationCtx context, + URI idReference, int type, + VersionConstraints constraints, + PolicyMetaData parentMetaData) { + + if ( policies.containsKey(idReference)) { + AbstractPolicy policy = policies.get(idReference); + + if ( constraints.meetsConstraint(policy.getVersion())) { + return new PolicyFinderResult(policy); + } else { + logger.warn("Found policy with right ID " + idReference + ", but version contraints do not match"); + } + } + return new PolicyFinderResult(); + } + + /** + * this method can be used to enforce the usage of lines parsing + * programatically + * @param useLines + */ + public void enforceUseLines() { + this.enf_useLines = true; + this.useLines = true; + } + + public void setConfigurationStore(ConfigurationStore confStore) { + // save confStore if needed + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/finder/FolderPolicyModule.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/finder/FolderPolicyModule.java new file mode 100644 index 0000000..a9bed09 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/finder/FolderPolicyModule.java @@ -0,0 +1,29 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support.finder; + +import com.sun.xacml.finder.PolicyFinder; +import com.sun.xacml.finder.PolicyFinderModule; + +public class FolderPolicyModule extends PolicyFinderModule { + + @Override + public void init(PolicyFinder arg0) { + // TODO Auto-generated method stub + + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/finder/IEvaluationIdContext.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/finder/IEvaluationIdContext.java new file mode 100644 index 0000000..b8ea76d --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/finder/IEvaluationIdContext.java @@ -0,0 +1,20 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support.finder; + +public interface IEvaluationIdContext { + Long getCurrentEvaluationId(); +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/finder/IPDPStateEvaluationContext.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/finder/IPDPStateEvaluationContext.java new file mode 100644 index 0000000..19a1859 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/finder/IPDPStateEvaluationContext.java @@ -0,0 +1,34 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support.finder; + +import java.net.URI; +import java.util.Date; + +import com.sun.xacml.Constants; +import com.sun.xacml.attr.TypeIdentifierConstants; + +public interface IPDPStateEvaluationContext { + + public static final URI PDPSTATE_CATEGORY = Constants.ENVIRONMENT_CAT; + public static final URI PDPSTATE_ATTRIBUTETYPE = TypeIdentifierConstants.INTEGER_URI; + public static final String PDPSTATE = "urn:custom:svnPolicyVersion"; + public static final URI PDPSTATE_URI = URI.create(PDPSTATE); + public static final URI PDPSTATE_ISSUER = null; + + public Date getExecTime(); + public long getVersion(); +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/finder/IRecordEvaluationContext.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/finder/IRecordEvaluationContext.java new file mode 100644 index 0000000..66682da --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/finder/IRecordEvaluationContext.java @@ -0,0 +1,26 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support.finder; + +import java.net.URI; + +import com.sun.xacml.cond.EvaluationResult; + +public interface IRecordEvaluationContext extends IEvaluationIdContext, IPDPStateEvaluationContext { + void retreiveDesignatorAttributeSearch(URI category, URI attributeType, + URI attributeId, URI issuer, EvaluationResult evalResult); + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/helper/DefaultElementCreator.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/helper/DefaultElementCreator.java new file mode 100644 index 0000000..7c64eb6 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/helper/DefaultElementCreator.java @@ -0,0 +1,62 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support.helper; + +import java.net.URI; + +import eu.aniketos.securebpmn.xacml.support.Category; + +public class DefaultElementCreator extends ElementCreator { + + private Category category; + private URI categoryURI, defaultId, defaultType; + + public DefaultElementCreator(Category category) { + setCategory(category); + } + + public DefaultElementCreator() { + ; + } + + public void setCategory(Category category) { + this.category = category; + this.categoryURI = category.getURI(); + this.defaultId = category.getDefaultId(); + this.defaultType = category.getDefaultType(); + } + + @Override + protected URI getCategory() { + return categoryURI; + } + + @Override + protected URI getDefaultType() { + return defaultType; + } + + @Override + protected URI getDefaultId() { + return defaultId; + } + + protected Category getCategoryObject() { + return this.category; + } + + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/helper/ElementCreator.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/helper/ElementCreator.java new file mode 100644 index 0000000..93fd344 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/helper/ElementCreator.java @@ -0,0 +1,77 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support.helper; + +import java.net.URI; +import java.util.HashSet; +import java.util.Set; + +import org.apache.log4j.Logger; + +import eu.aniketos.securebpmn.xacml.support.Category; + +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; +import com.sun.xacml.attr.AttributeFactory; +import com.sun.xacml.ctx.Attribute; +import com.sun.xacml.ctx.RequestElement; + +public abstract class ElementCreator implements IElementCreator { + + private static Logger logger = Logger.getLogger(ElementCreator.class); + + protected static AttributeFactory attrFactory = AttributeFactory.getInstance(); + + + protected abstract URI getCategory(); + protected abstract URI getDefaultId(); + protected abstract URI getDefaultType(); + public abstract void setCategory(Category category); + + public RequestElement getRequestElement(String value) throws ParsingException { + Attribute attrs; + try { + attrs = new Attribute(getDefaultId(), null, attrFactory.createValue(getDefaultType(), value)); + } catch (UnknownIdentifierException e) { + logger.error("Could not create attribute for category " + getCategory() + ", default type " + getDefaultType() + " and value " + value); + return null; //should not happen... + } + Set resourceSet = new HashSet(); + resourceSet.add(attrs); + return new RequestElement(getCategory(), resourceSet); + } + + + + public RequestElement getRequestElement(Set attrs) { + return new RequestElement(getCategory(), attrs); + } + + + public Attribute getAttribute(URI attributeId, URI dataType, String value) throws ParsingException, UnknownIdentifierException { + return new Attribute(attributeId != null ? attributeId : getDefaultId(), + null, attrFactory.createValue(dataType != null ? dataType : getDefaultType(), value)); + } + + public Attribute getAttributeDefaultType(String value) throws ParsingException { + try { + return new Attribute(getDefaultId(), null, attrFactory.createValue(getDefaultType(), value)); + } catch (UnknownIdentifierException e) { + logger.error("Could not create attribute for category " + getCategory() + ", default type " + getDefaultType() + " and value " + value); + return null; //should not happen... + } + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/helper/IElementCreator.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/helper/IElementCreator.java new file mode 100644 index 0000000..d09c468 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/helper/IElementCreator.java @@ -0,0 +1,33 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support.helper; + + +import java.net.URI; +import java.util.Set; + +import com.sun.xacml.ParsingException; +import com.sun.xacml.UnknownIdentifierException; +import com.sun.xacml.ctx.Attribute; +import com.sun.xacml.ctx.RequestElement; + +public interface IElementCreator { + RequestElement getRequestElement(String value) throws ParsingException; + RequestElement getRequestElement(Set attrs); + + Attribute getAttribute(URI attributeId, URI dataType, String value) throws ParsingException, UnknownIdentifierException; + Attribute getAttributeDefaultType(String value) throws ParsingException; +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/helper/LogPreparer.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/helper/LogPreparer.java new file mode 100644 index 0000000..87becdb --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/helper/LogPreparer.java @@ -0,0 +1,56 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support.helper; + +import org.apache.log4j.Logger; + +import com.sun.xacml.ctx.RequestCtx; +import com.sun.xacml.ctx.ResponseCtx; + +import eu.aniketos.securebpmn.xacml.api.log.AccessControlRequest; +import eu.aniketos.securebpmn.xacml.support.XACMLEncoder; + +public class LogPreparer { + + private static Logger logger = Logger.getLogger(LogPreparer.class); + + public static void prepare(AccessControlRequest requ) { + RequestCtx requCtx = (RequestCtx) requ.getRequest(); + ResponseCtx respCtx = (ResponseCtx) requ.getResponse(); + + if ( requ.getXacmlRequest() == null || requ.getXacmlResponse() == null) { + requ.setXacmlRequest(XACMLEncoder.encodeRequestCtx(requCtx)); + requ.setXacmlResponse(XACMLEncoder.encodeResponseCtx(respCtx)); + + if ( ! (requ.getXacmlRequest() == null && requ.getXacmlResponse() == null) + || requ.getResource() == null || requ.getResult() == null ) { + logInconsistant(requ); + } + } + + if ( requ.getResource() == null || requ.getResult() == null ) { + //TODO read from requCtx + } + } + + private static void logInconsistant(AccessControlRequest requ) { + logger.warn("Inconsistant AccessControlRequest: XacmlRequest" + requ.getXacmlRequest() + + ", XacmlResponse: " + requ.getXacmlResponse() + + ", Resource: " + requ.getResource() + + ", Result: " + requ.getResult()); + } + +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/helper/ResourceCreator.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/helper/ResourceCreator.java new file mode 100644 index 0000000..68c1bd9 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/main/java/eu/aniketos/securebpmn/xacml/support/helper/ResourceCreator.java @@ -0,0 +1,75 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support.helper; + +import java.net.URI; +import java.util.HashSet; +import java.util.Set; + +import eu.aniketos.securebpmn.xacml.support.Category; + +import com.sun.xacml.Constants; +import com.sun.xacml.attr.AnyURIAttribute; +import com.sun.xacml.ctx.Attribute; +import com.sun.xacml.ctx.RequestElement; + +/** + * + * Creates a RequestElement, containing a resource for evaluation by the XACML PDP + * + * + */ +public class ResourceCreator extends ElementCreator { + + private static final URI resourceID_URI = Constants.RESOURCE_CAT; //Category.RESOURCE.getURI(); + private static final URI defaultId = Constants.RESOURCE_ID; //Category.RESOURCE.getDefaultId(); + private static final URI default_Type = URI.create(AnyURIAttribute.identifier); //Category.RESOURCE.getDefaultType(); + + + @Override + protected URI getCategory() { + return resourceID_URI; + } + + @Override + protected URI getDefaultType() { + return default_Type; + } + + @Override + protected URI getDefaultId() { + return defaultId; + } + + @Override + public void setCategory(Category category) { + if ( ! category.getURI().equals(resourceID_URI) ) { + throw new RuntimeException("It is not possbile to set the category of " + ResourceCreator.class + " afterwards"); + } + } + + + public RequestElement getRequestElement(URI resource) { + Attribute resourceAttribute = new Attribute(defaultId, null, new AnyURIAttribute(resource)); + Set resourceSet = new HashSet(); + resourceSet.add(resourceAttribute); + return new RequestElement(resourceID_URI, resourceSet); + } + + public Attribute getAttributeDefaultType(URI value) { + return new Attribute(getDefaultId(), null, new AnyURIAttribute(value)); + } +} diff --git a/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/test/java/eu/aniketos/securebpmn/xacml/support/AppTest.java b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/test/java/eu/aniketos/securebpmn/xacml/support/AppTest.java new file mode 100644 index 0000000..6254351 --- /dev/null +++ b/GenericBreakGlass-XACML/src/eu.aniketos.securebpmn.xacml.support/src/test/java/eu/aniketos/securebpmn/xacml/support/AppTest.java @@ -0,0 +1,53 @@ +/* Copyright 2012-2015 SAP SE + * + * 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. + */ + +package eu.aniketos.securebpmn.xacml.support; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +}