Beispiel #1
0
			public static void TestResponseElement( ResponseElement res )
			{
				MemoryStream ms = new MemoryStream();
				XmlTextWriter tw = new XmlTextWriter( ms, System.Text.Encoding.ASCII );
				res.WriteDocument( tw );
				tw.Flush();
				ms.Position = 0;
				ContextDocument cd = new ContextDocument( new XmlTextReader( ms ), XacmlVersion.Version11 );
			}
        /// <summary>
        /// Creates a new ContextDocumentReadWrite using the XmlReader instance provided.
        /// </summary>
        /// <param name="reader">The XmlReader instance positioned at the begining of the document.</param>
        /// <param name="schemaVersion">The schema used to validate this context document.</param>
        public ContextDocumentReadWrite(XmlReader reader, XacmlVersion schemaVersion)
        {
            if (reader == null)
            {
                throw new ArgumentNullException(nameof(reader));
            }
            // Search for the first element.
            while (reader.Read() && reader.NodeType != XmlNodeType.Element)
            {
            }

            // Keep the contents of the context document.
            // HACK: Due to XPath validation the document must be readed twice, the first time to load the instance
            // and the second one to keep a document to execute XPath sentences.
            _xmlString = reader.ReadOuterXml();

            // Read the contents in a new reader.
#if NET20
            StringReader sreader = new StringReader(_xmlString);
#endif

            // Prepare the validation.

#if NET20
            ValidationEventHandler validationHandler = vreader_ValidationEventHandler;
            XmlReaderSettings      settings          = new XmlReaderSettings {
                ValidationType = ValidationType.Schema
            };
            settings.ValidationEventHandler += validationHandler;
            XmlReader vreader = null;
#endif
            switch (schemaVersion)
            {
            case XacmlVersion.Version10:
            case XacmlVersion.Version11:
            {
                Stream policySchemaStream  = Assembly.GetExecutingAssembly().GetManifestResourceStream(pol.PolicyDocument.Xacml10PolicySchemaResourceName);
                Stream contextSchemaStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(Xacml10ContextSchemaResourceName);
#if NET10
                vreader.Schemas.Add(PolicySchema1.Namespaces.Policy, new XmlTextReader(policySchemaStream));
                vreader.Schemas.Add(PolicySchema1.Namespaces.Context, new XmlTextReader(contexSchemaStream));
#endif
#if NET20
                if (_compiledSchemas11 == null)
                {
                    _compiledSchemas11 = new XmlSchemaSet();
                    _compiledSchemas11.Add(XmlSchema.Read(policySchemaStream, validationHandler));
                    _compiledSchemas11.Add(XmlSchema.Read(contextSchemaStream, validationHandler));
                    _compiledSchemas11.Compile();
                }
                settings.Schemas.Add(_compiledSchemas11);
#endif
                break;
            }

            case XacmlVersion.Version20:
            {
                Stream policySchemaStream  = Assembly.GetExecutingAssembly().GetManifestResourceStream(pol.PolicyDocumentReadWrite.Xacml20PolicySchemaResourceName);
                Stream contextSchemaStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(Xacml20ContextSchemaResourceName);

                if (_compiledSchemas20 == null)
                {
                    _compiledSchemas20 = new XmlSchemaSet();
                    if (policySchemaStream != null)
                    {
                        _compiledSchemas20.Add(XmlSchema.Read(policySchemaStream, validationHandler));
                    }
                    if (contextSchemaStream != null)
                    {
                        _compiledSchemas20.Add(XmlSchema.Read(contextSchemaStream, validationHandler));
                    }
                    _compiledSchemas20.Compile();
                }
                settings.Schemas.Add(_compiledSchemas20);

                break;
            }

            default:
                throw new ArgumentException(Resource.ResourceManager[Resource.MessageKey.exc_invalid_version_parameter_value], nameof(reader));
            }

#if NET20
            vreader = XmlReader.Create(sreader, settings);
#endif
            while (vreader.Read())
            {
                //Read all the namespaces and keep them in the _namespaces hashtable.
                if (vreader.HasAttributes)
                {
                    while (vreader.MoveToNextAttribute())
                    {
                        if (vreader.LocalName == PolicySchema1.Namespaces.XMLNS)
                        {
                            _namespaces.Add(vreader.Prefix, vreader.Value);
                        }
                        else if (vreader.Prefix == PolicySchema1.Namespaces.XMLNS)
                        {
                            _namespaces.Add(vreader.LocalName, vreader.Value);
                        }
                    }
                    vreader.MoveToElement();
                }
                switch (vreader.LocalName)
                {
                case ContextSchema.RequestElement.Request:
                    _request = new RequestElementReadWrite(vreader, schemaVersion);
                    break;

                case ContextSchema.ResponseElement.Response:
                    _response = new ResponseElement(vreader, schemaVersion);
                    break;
                }
            }
        }
Beispiel #3
0
		/// <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 ContextDocumentReadWrite using the XmlReader instance provided.
        /// </summary>
        /// <param name="reader">The XmlReader instance positioned at the begining of the document.</param>
        /// <param name="schemaVersion">The schema used to validate this context document.</param>
        public ContextDocumentReadWrite(XmlReader reader, XacmlVersion schemaVersion)
        {
            if (reader == null) throw new ArgumentNullException(nameof(reader));
            // Search for the first element.
            while (reader.Read() && reader.NodeType != XmlNodeType.Element)
            { }

            // Keep the contents of the context document.
            // HACK: Due to XPath validation the document must be readed twice, the first time to load the instance
            // and the second one to keep a document to execute XPath sentences.
            _xmlString = reader.ReadOuterXml();

            // Read the contents in a new reader.
#if NET20
            StringReader sreader = new StringReader(_xmlString);
#endif

            // Prepare the validation.

#if NET20
            ValidationEventHandler validationHandler = vreader_ValidationEventHandler;
            XmlReaderSettings settings = new XmlReaderSettings {ValidationType = ValidationType.Schema};
            settings.ValidationEventHandler += validationHandler;
            XmlReader vreader = null;
#endif
            switch (schemaVersion)
            {
                case XacmlVersion.Version10:
                case XacmlVersion.Version11:
                    {
                        Stream policySchemaStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(pol.PolicyDocument.Xacml10PolicySchemaResourceName);
                        Stream contextSchemaStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(Xacml10ContextSchemaResourceName);
#if NET10
					    vreader.Schemas.Add( PolicySchema1.Namespaces.Policy, new XmlTextReader( policySchemaStream ) );
					    vreader.Schemas.Add( PolicySchema1.Namespaces.Context, new XmlTextReader( contexSchemaStream ) );
#endif
#if NET20
                        if (_compiledSchemas11 == null)
                        {
                            _compiledSchemas11 = new XmlSchemaSet();
                            _compiledSchemas11.Add(XmlSchema.Read(policySchemaStream, validationHandler));
                            _compiledSchemas11.Add(XmlSchema.Read(contextSchemaStream, validationHandler));
                            _compiledSchemas11.Compile();
                        }
                        settings.Schemas.Add(_compiledSchemas11);
#endif
                        break;
                    }
                case XacmlVersion.Version20:
                    {
                        Stream policySchemaStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(pol.PolicyDocumentReadWrite.Xacml20PolicySchemaResourceName);
                        Stream contextSchemaStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(Xacml20ContextSchemaResourceName);

                        if (_compiledSchemas20 == null)
                        {
                            _compiledSchemas20 = new XmlSchemaSet();
                            if (policySchemaStream != null)
                                _compiledSchemas20.Add(XmlSchema.Read(policySchemaStream, validationHandler));
                            if (contextSchemaStream != null)
                                _compiledSchemas20.Add(XmlSchema.Read(contextSchemaStream, validationHandler));
                            _compiledSchemas20.Compile();
                        }
                        settings.Schemas.Add(_compiledSchemas20);

                        break;
                    }
                default:
                    throw new ArgumentException(Resource.ResourceManager[Resource.MessageKey.exc_invalid_version_parameter_value], nameof(reader));
            }

#if NET20
            vreader = XmlReader.Create(sreader, settings);
#endif
            while (vreader.Read())
            {
                //Read all the namespaces and keep them in the _namespaces hashtable.
                if (vreader.HasAttributes)
                {
                    while (vreader.MoveToNextAttribute())
                    {
                        if (vreader.LocalName == PolicySchema1.Namespaces.XMLNS)
                        {
                            _namespaces.Add(vreader.Prefix, vreader.Value);
                        }
                        else if (vreader.Prefix == PolicySchema1.Namespaces.XMLNS)
                        {
                            _namespaces.Add(vreader.LocalName, vreader.Value);
                        }
                    }
                    vreader.MoveToElement();
                }
                switch (vreader.LocalName)
                {
                    case ContextSchema.RequestElement.Request:
                        _request = new RequestElementReadWrite(vreader, schemaVersion);
                        break;
                    case ContextSchema.ResponseElement.Response:
                        _response = new ResponseElement(vreader, schemaVersion);
                        break;
                }
            }
        }