/// <summary> /// Method called by the EvaluationEngine when the evaluation is executed without a policy document, this /// method search in the policy repository and return the first policy that matches its target with the /// context document specified. /// </summary> /// <param name="context">The evaluation context instance.</param> /// <returns>The policy document ready to be used by the evaluation engine.</returns> public pol.PolicyDocument Match(rtm.EvaluationContext context) { if (context == null) { throw new ArgumentNullException("context"); } pol.PolicyDocument polEv = null; //Search if there is a policySet which target matches the context document foreach (pol.PolicyDocument policy in _policySets.Values) { rtm.PolicySet tempPolicy = new rtm.PolicySet(context.Engine, (pol.PolicySetElement)policy.PolicySet); rtm.EvaluationContext tempContext = new rtm.EvaluationContext(context.Engine, policy, context.ContextDocument); // Match the policy set target with the context document if (tempPolicy.Match(tempContext) == rtm.TargetEvaluationValue.Match) { if (polEv == null) { polEv = policy; } else { throw new EvaluationException(Resource.ResourceManager[Resource.MessageKey.exc_duplicated_policy_in_repository]); } } } //Search if there is a policy which target matches the context document foreach (pol.PolicyDocument policy in _policies.Values) { rtm.Policy tempPolicy = new rtm.Policy((pol.PolicyElement)policy.Policy); rtm.EvaluationContext tempContext = new rtm.EvaluationContext(context.Engine, policy, context.ContextDocument); // Match the policy target with the context document if (tempPolicy.Match(tempContext) == rtm.TargetEvaluationValue.Match) { if (polEv == null) { polEv = policy; } else { throw new EvaluationException(Resource.ResourceManager[Resource.MessageKey.exc_duplicated_policy_in_repository]); } } } return(polEv); }
/// <summary> /// Evaluate the context document using a specified policy /// </summary> /// <param name="policyDocument">The policy instance</param> /// <param name="contextDocument">The context document instance</param> /// <returns>The response document</returns> public ctx.ResponseElement Evaluate( pol.PolicyDocument policyDocument, ctx.ContextDocument contextDocument ) { if (policyDocument == null) throw new ArgumentNullException("policyDocument"); if (contextDocument == null) throw new ArgumentNullException("contextDocument"); EvaluationContext context = new EvaluationContext( this, policyDocument, (ctx.ContextDocument)contextDocument ) ; context.Trace( "Start evaluation" ); context.AddIndent(); if ( policyDocument == null || contextDocument == null ) { // If a validation error was found a response is created with the syntax error message ctx.ResponseElement response = new ctx.ResponseElement( new ctx.ResultElement[] { new ctx.ResultElement( null, Decision.Indeterminate, new ctx.StatusElement( new ctx.StatusCodeElement( StatusCodes.ProcessingError, null, policyDocument.Version ), null, null, policyDocument.Version ), null, policyDocument.Version ) }, policyDocument.Version ); return response; } // Check if both documents are valid if( !policyDocument.IsValidDocument || !contextDocument.IsValidDocument ) { // If a validation error was found a response is created with the syntax error message ctx.ResponseElement response = new ctx.ResponseElement( new ctx.ResultElement[] { new ctx.ResultElement( null, Decision.Indeterminate, new ctx.StatusElement( new ctx.StatusCodeElement( StatusCodes.SyntaxError, null, policyDocument.Version ), null, null, policyDocument.Version ), null, policyDocument.Version ) }, policyDocument.Version ); return response; } // Create a new response contextDocument.Response = new ctx.ResponseElement( (ctx.ResultElement[])null, policyDocument.Version ); try { // Create the evaluable policy intance IMatchEvaluable policy = null; if( policyDocument.PolicySet != null ) { policy = new PolicySet( this, (pol.PolicySetElement)policyDocument.PolicySet ); } else if( policyDocument.Policy != null ) { policy = new Policy( (pol.PolicyElement)policyDocument.Policy ); } // Evaluate the policy or policy set if( policy != null ) { // Creates the evaluable policy set if( policy.AllResources.Count == 0 ) { policy.AllResources.Add( "" ); } string requestedResourceString = String.Empty; Uri requestedResource = null; foreach( ctx.ResourceElement resource in contextDocument.Request.Resources ) { // Keep the requested resource if( resource.IsHierarchical ) { foreach( ctx.AttributeElement attribute in resource.Attributes ) { if( attribute.AttributeId == ResourceElement.ResourceId ) { if( context.PolicyDocument.Version == XacmlVersion.Version10 || context.PolicyDocument.Version == XacmlVersion.Version11 ) { requestedResourceString = attribute.AttributeValues[0].Contents; } else { if( attribute.AttributeValues.Count > 1 ) { throw new NotSupportedException( "resources contains a bag of values" ); } requestedResourceString = attribute.AttributeValues[0].Contents; } } } if( !string.IsNullOrEmpty(requestedResourceString) ) { requestedResource = new Uri( requestedResourceString ); } } // Iterate through the policy resources evaluating each resource in the context document request foreach( string resourceName in policy.AllResources ) { bool mustEvaluate; if( resource.IsHierarchical ) { //Validate if the resource is hierarchically desdendant or children //of the requested resource Uri policyResource = new Uri( resourceName ); if( !(mustEvaluate = requestedResource.Equals( policyResource ) ) ) { // Perform the hierarchical evaluation if( resource.ResourceScopeValue == ctx.ResourceScope.Children ) { mustEvaluate = typ.AnyUri.IsChildrenOf( requestedResource, policyResource ); } else if( resource.ResourceScopeValue == ctx.ResourceScope.Descendants ) { mustEvaluate = typ.AnyUri.IsDescendantOf( requestedResource, policyResource ); } } if( mustEvaluate ) { foreach( ctx.AttributeElementReadWrite attribute in context.CurrentResource.Attributes ) { if( attribute.AttributeId == ResourceElement.ResourceId ) { attribute.AttributeValues[0].Contents = resourceName; break; } } } } else { context.CurrentResource = resource; mustEvaluate = true; } if( mustEvaluate ) { // Evaluates the policy set Decision decision = policy.Evaluate( context ); // Create a status code using the policy execution state ctx.StatusCodeElement scode; if( context.IsMissingAttribute ) { scode = new ctx.StatusCodeElement( StatusCodes.MissingAttribute, null, policyDocument.Version ); } else if( context.ProcessingError ) { scode = new ctx.StatusCodeElement( StatusCodes.ProcessingError, null, policyDocument.Version ); } else { scode = new ctx.StatusCodeElement( StatusCodes.OK, null, policyDocument.Version ); } //Stop the iteration if there is not a hierarchical request if( !resource.IsHierarchical ) { // Ussually when a single resource is requested the ResourceId is not specified in the result IObligationsContainer oblig = policy as IObligationsContainer; contextDocument.Response.Results.Add( new ctx.ResultElement( "", decision, new ctx.StatusElement( scode, "", "", policyDocument.Version ), oblig.Obligations, policyDocument.Version ) ); break; } else { // Adding a resource for each requested resource, using the resourceName as the resourceId of the result IObligationsContainer oblig = policy as IObligationsContainer; contextDocument.Response.Results.Add( new ctx.ResultElement( resourceName, decision, new ctx.StatusElement( scode, "", "", policyDocument.Version ), oblig.Obligations, policyDocument.Version ) ); } } // if( mustEvaluate ) } // foreach( string resourceName in policy.AllResources ) } } //if( policy != null ) } catch( EvaluationException e ) { // If a validation error was found a response is created with the syntax error message contextDocument.Response = new ctx.ResponseElement( new ctx.ResultElement[] { new ctx.ResultElement( null, Decision.Indeterminate, new ctx.StatusElement( new ctx.StatusCodeElement( StatusCodes.ProcessingError, null, policyDocument.Version ), e.Message, e.StackTrace, policyDocument.Version ), null, policyDocument.Version ) }, policyDocument.Version ); } return contextDocument.Response; }
/// <summary> /// Creates a new runtime policy set evaluation. /// </summary> /// <param name="engine">The evaluation engine.</param> /// <param name="policySet">The policy set defined in the policy document.</param> public PolicySet( EvaluationEngine engine, pol.PolicySetElement policySet ) { if (engine == null) throw new ArgumentNullException("engine"); if (policySet == null) throw new ArgumentNullException("policySet"); _policySet = policySet; // Create a runtime target of this policy set. if( policySet.Target != null ) { _target = new Target( (pol.TargetElement)policySet.Target ); foreach( pol.ResourceElement resource in policySet.Target.Resources.ItemsList ) { foreach( pol.ResourceMatchElement rmatch in resource.Match ) { if( !_allResources.Contains( rmatch.AttributeValue.Contents ) ) { _allResources.Add( rmatch.AttributeValue.Contents ); } } } } // Add all the policies (or policy set) inside this policy set. foreach( object child in policySet.Policies ) { pol.PolicySetElement childPolicySet = child as pol.PolicySetElement; pol.PolicyElement childPolicyElement = child as pol.PolicyElement; pol.PolicySetIdReferenceElement childPolicySetIdReference = child as pol.PolicySetIdReferenceElement; pol.PolicyIdReferenceElement childPolicyIdReferenceElement = child as pol.PolicyIdReferenceElement; if (childPolicySet != null) { PolicySet policySetEv = new PolicySet(engine, childPolicySet); foreach( string rName in policySetEv.AllResources ) { if( !_allResources.Contains( rName ) ) { _allResources.Add( rName ); } } _policies.Add( policySetEv ); } else if (childPolicyElement!=null) { Policy policyEv = new Policy(childPolicyElement); foreach( string rName in policyEv.AllResources ) { if( !_allResources.Contains( rName ) ) { _allResources.Add( rName ); } } _policies.Add( policyEv ); } else if (childPolicySetIdReference!=null) { pol.PolicySetElement policySetDefinition = EvaluationEngine.Resolve(childPolicySetIdReference); if( policySetDefinition != null ) { PolicySet policySetEv = new PolicySet( engine, policySetDefinition ); foreach( string rName in policySetEv.AllResources ) { if( !_allResources.Contains( rName ) ) { _allResources.Add( rName ); } } _policies.Add( policySetEv ); } else { throw new EvaluationException( Resource.ResourceManager[ Resource.MessageKey.exc_policyset_reference_not_resolved, ((pol.PolicySetIdReferenceElement)child).PolicySetId ] ); } } else if (childPolicyIdReferenceElement!=null) { pol.PolicyElement policyDefinition = EvaluationEngine.Resolve(childPolicyIdReferenceElement); if( policyDefinition != null ) { Policy policyEv = new Policy( policyDefinition ); foreach( string rName in policyEv.AllResources ) { if( !_allResources.Contains( rName ) ) { _allResources.Add( rName ); } } _policies.Add( policyEv ); } else { throw new EvaluationException( Resource.ResourceManager[ Resource.MessageKey.exc_policy_reference_not_resolved, ((pol.PolicyIdReferenceElement)child).PolicyId ] ); } } } }
/// <summary> /// Method called by the EvaluationEngine when the evaluation is executed without a policy document, this /// method search in the policy repository and return the first policy that matches its target with the /// context document specified. /// </summary> /// <param name="context">The evaluation context instance.</param> /// <returns>The policy document ready to be used by the evaluation engine.</returns> public pol.PolicyDocument Match( rtm.EvaluationContext context ) { if (context == null) throw new ArgumentNullException("context"); pol.PolicyDocument polEv = null; //Search if there is a policySet which target matches the context document foreach( pol.PolicyDocument policy in _policySets.Values ) { rtm.PolicySet tempPolicy = new rtm.PolicySet( context.Engine, (pol.PolicySetElement)policy.PolicySet ); rtm.EvaluationContext tempContext = new rtm.EvaluationContext( context.Engine, policy, context.ContextDocument ); // Match the policy set target with the context document if( tempPolicy.Match( tempContext ) == rtm.TargetEvaluationValue.Match ) { if( polEv == null ) { polEv = policy; } else { throw new EvaluationException( Resource.ResourceManager[ Resource.MessageKey.exc_duplicated_policy_in_repository ] ); } } } //Search if there is a policy which target matches the context document foreach( pol.PolicyDocument policy in _policies.Values ) { rtm.Policy tempPolicy = new rtm.Policy( (pol.PolicyElement)policy.Policy ); rtm.EvaluationContext tempContext = new rtm.EvaluationContext( context.Engine, policy, context.ContextDocument ); // Match the policy target with the context document if( tempPolicy.Match( tempContext ) == rtm.TargetEvaluationValue.Match ) { if( polEv == null ) { polEv = policy; } else { throw new EvaluationException( Resource.ResourceManager[ Resource.MessageKey.exc_duplicated_policy_in_repository ] ); } } } return polEv; }