<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
    xmlns:oval-def="http://oval.mitre.org/XMLSchema/oval-definitions-5"
    xmlns:win-def="http://oval.mitre.org/XMLSchema/oval-definitions-5#windows"
    xmlns:cdf="http://checklists.nist.gov/xccdf/1.1" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:oval-res="http://oval.mitre.org/XMLSchema/oval-results-5"
    xmlns:oval-sc="http://oval.mitre.org/XMLSchema/oval-system-characteristics-5"
    xmlns:oval-ind="http://oval.mitre.org/XMLSchema/oval-definitions-5#independent"
    xmlns:ind-sc="http://oval.mitre.org/XMLSchema/oval-system-characteristics-5#independent"
    xmlns:win-sc="http://oval.mitre.org/XMLSchema/oval-system-characteristics-5#windows"
    xmlns:xalan="http://xml.apache.org/xalan">

    <!--
        
        This XSLT is used for the definition which want to verify whether some system configuration is not set as 
        expected by the user in the user input. Choice of user input should be available in the external variable with all 
        the posssible value. 
        
        Message id :  Message id is generated by the template getMessageId. 
        
        Message id is generated by the id of the definition.          
        Message id is generated by the concatenation of  "com.mcafee.pa.msg.winconfiguration" 
        and the phrase of the definition id after "oval:com.mcafee." without  "." and ":" . 
        
        This messages are added in the Windows Messages file.
        
        Schema for the definition is : ( It should have only family and registry tests ) 
        
       Criterio ( and )
            criterion : family test 
            criterion              Registry test  with input value
            criterion              Registry test  to test the existance of the registry  ( optional )
            criterion              Registry test  to test the proper type of the registry value ( ( optional ))
         or 
        
        Criterio ( and )
            criterion : family test 
            Criterio ( and )
                criterion              Registry test  with input value
                criterion              Registry test  to test the existance of the registry  ( optional )
                criterion              Registry test  to test the proper type of the registry value ( ( optional ))
      
	  Same as winSystemConfigurationCheck00.xsl  but doesn't pick up the hint value.
    -->

    <xsl:variable name="Definitions"
        select="/oval-res:oval_results/oval-def:oval_definitions/oval-def:definitions"/>
    <xsl:variable name="Tests"
        select="/oval-res:oval_results/oval-def:oval_definitions/oval-def:tests"/>
    <xsl:variable name="TestedItems"
        select="/oval-res:oval_results/oval-res:results/oval-res:system/oval-res:tests"/>
    <xsl:variable name="CollectedObjects"
        select="/oval-res:oval_results/oval-res:results/oval-res:system/oval-sc:oval_system_characteristics/oval-sc:collected_objects"/>
    <xsl:variable name="SystemData"
        select="/oval-res:oval_results/oval-res:results/oval-res:system/oval-sc:oval_system_characteristics/oval-sc:system_data"/>
    <xsl:variable name="States"
        select="/oval-res:oval_results/oval-def:oval_definitions/oval-def:states"/>
    <xsl:variable name="Objects"
        select="/oval-res:oval_results/oval-def:oval_definitions/oval-def:objects"/>
    <xsl:variable name="Variables"
        select="/oval-res:oval_results/oval-def:oval_definitions/oval-def:variables"/>
    <xsl:variable name="OvalResult"
        select="/oval-res:oval_results/oval-res:results/oval-res:system/oval-res:definitions"/>



    <xsl:template name="toggleBoolean">
        <xsl:param name="value"/>
        <xsl:choose>
            <xsl:when test="$value = 'true'">
                <xsl:value-of select="false()"/>
            </xsl:when>
            <xsl:when test="$value = 'false'">
                <xsl:value-of select="true()"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="true()"/>
            </xsl:otherwise>
        </xsl:choose>


    </xsl:template>

    <xsl:template name="removeColon">
        <xsl:param name="string"/>
        <xsl:param name="count"/>
        <xsl:param name="length"/>

        <xsl:if test="$count  &lt;= $length">

            <xsl:variable name="char">
                <xsl:value-of select="substring($string,$count,1)"/>
            </xsl:variable>

            <xsl:choose>
                <xsl:when test="$char != ':' and $char != '.' ">
                    <xsl:value-of select="$char"/>
                    <xsl:call-template name="removeColon">
                        <xsl:with-param name="string" select="$string"/>
                        <xsl:with-param name="count" select="$count + 1"/>
                        <xsl:with-param name="length" select="$length"/>
                    </xsl:call-template>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:call-template name="removeColon">
                        <xsl:with-param name="string" select="$string"/>
                        <xsl:with-param name="count" select="$count + 1"/>
                        <xsl:with-param name="length" select="$length"/>
                    </xsl:call-template>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:if>

    </xsl:template>

    <xsl:template name="getSuffixForMessageId">
        <xsl:param name="id"/>

        <xsl:variable name="suffix">
            <xsl:value-of select="substring-after($id,'oval:com.mcafee.')"/>
        </xsl:variable>

        <xsl:variable name="suffix1">
            <xsl:call-template name="removeColon">
                <xsl:with-param name="string" select="$suffix"/>
                <xsl:with-param name="length" select="string-length($suffix)"/>
                <xsl:with-param name="count" select="1 + 0"/>
            </xsl:call-template>
        </xsl:variable>
        <xsl:value-of select="$suffix1"/>
    </xsl:template>

    <xsl:template name="getMessageId">
        <xsl:param name="id"/>
        <xsl:param name="status"/>

        <xsl:variable name="suffiex">
            <xsl:call-template name="getSuffixForMessageId">
                <xsl:with-param name="id" select="$id"/>
            </xsl:call-template>
        </xsl:variable>

        <xsl:if test="$suffiex != '' ">
            <xsl:choose>
                <xsl:when test="$status = 'does not exist' ">
                    <xsl:value-of select="concat('com.mcafee.pa.msg.winnoconfiguration',$suffiex)"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="concat('com.mcafee.pa.msg.winconfiguration',$suffiex)"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:if>
    </xsl:template>

    <xsl:template name="getFindings">
        <xsl:param name="definitionId"/>

        <xsl:variable name="result"
            select="/oval-res:oval_results/oval-res:results/oval-res:system/oval-res:definitions/oval-res:definition[@definition_id=$definitionId]/@result"/>


        <xsl:call-template name="winConfigurationCheck">
            <xsl:with-param name="definitionId" select="$definitionId"/>
            <xsl:with-param name="def_result" select="$result"/>
        </xsl:call-template>

    </xsl:template>

    <xsl:template name="winConfigurationCheck">
        <xsl:param name="definitionId"/>
        <xsl:param name="def_result"/>

        <xsl:variable name="tests">
            <xsl:for-each
                select="$OvalResult/oval-res:definition[ @definition_id = $definitionId ]/oval-res:criteria/descendant::oval-res:criterion">

                <xsl:variable name="test" select="@test_ref"/>
                <xsl:if test="$Tests/win-def:registry_test[@id=$test]">
                    <xsl:variable name="object"
                        select="$Tests/win-def:registry_test[@id=$test]/win-def:object/@object_ref"/>
                    <xsl:variable name="state"
                        select="$Tests/win-def:registry_test[@id=$test]/win-def:state/@state_ref"/>

                    <xsl:variable name="key"
                        select="$Objects/win-def:registry_object[@id=$object]/win-def:key"/>
                    <xsl:variable name="name"
                        select="$Objects/win-def:registry_object[@id=$object]/win-def:name"/>

                    <xsl:variable name="externalVar"
                        select="$States/win-def:registry_state[@id=$state]/win-def:value/@var_ref"/>
                    <xsl:variable name="operation"
                        select="$States/win-def:registry_state[@id=$state]/win-def:value/@operation"/>

                    <xsl:element name="test">
                        <xsl:attribute name="id">
                            <xsl:value-of select="$test"/>
                        </xsl:attribute>

                        <xsl:attribute name="key">
                            <xsl:value-of select="$key"/>
                        </xsl:attribute>

                        <xsl:attribute name="state">
                            <xsl:value-of select="$state"/>
                        </xsl:attribute>

                        <xsl:attribute name="name">
                            <xsl:value-of select="$name"/>
                        </xsl:attribute>
                        <xsl:attribute name="externalVar">
                            <xsl:value-of select="$externalVar"/>
                        </xsl:attribute>
                        <xsl:attribute name="operation">
                            <xsl:value-of select="$operation"/>
                        </xsl:attribute>

                        <xsl:if
                            test="$States/win-def:registry_state[@id=$state]/win-def:value or not($state)">
                            <xsl:attribute name="type">
                                <xsl:text>primarytest</xsl:text>
                            </xsl:attribute>
                        </xsl:if>

                        <xsl:if
                            test="$States/win-def:registry_state[@id=$state]/win-def:type and not($States/win-def:registry_state[@id=$state]/win-def:value)">
                            <xsl:attribute name="type">
                                <xsl:text>typecheckingtest</xsl:text>
                            </xsl:attribute>
                            <xsl:attribute name="typeName">
                                <xsl:value-of
                                    select="$States/win-def:registry_state[@id=$state]/win-def:type"
                                />
                            </xsl:attribute>
                        </xsl:if>
                    </xsl:element>
                </xsl:if>

                <xsl:if test="$Tests/oval-ind:family_test[@id=$test]">
                    <xsl:element name="test">
                        <xsl:attribute name="id">
                            <xsl:value-of select="$test"/>
                        </xsl:attribute>
                        <xsl:attribute name="type">
                            <xsl:text>family</xsl:text>
                        </xsl:attribute>
                    </xsl:element>
                </xsl:if>
            </xsl:for-each>

        </xsl:variable>



        <xsl:variable name="exDefinitionId">
            <xsl:for-each
                select="/oval-res:oval_results/oval-res:results/oval-res:system/oval-res:definitions/oval-res:definition[ @definition_id = $definitionId ]/oval-res:criteria/descendant::oval-res:extend_definition[@result = 'false'] ">
                <xsl:if test="./parent::node()/@result = 'false' ">
                    <xsl:element name="extend_definition">
                        <xsl:attribute name="id">
                            <xsl:value-of select="@definition_ref"/>
                        </xsl:attribute>
                        <xsl:attribute name="result">
                            <xsl:value-of select="@result"/>
                        </xsl:attribute>
                    </xsl:element>
                </xsl:if>
            </xsl:for-each>
        </xsl:variable>

        <xsl:variable name="rs_exDefinition">
            <xsl:choose>
                <xsl:when test="xalan:nodeset($exDefinitionId)/descendant::extend_definition[@result='true'] != ''">
                    <xsl:text>true</xsl:text>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of
                        select="xalan:nodeset($exDefinitionId)/descendant::extend_definition/@result"/>
                </xsl:otherwise>
            </xsl:choose>                        
        </xsl:variable>

        <xsl:variable name="pre_test_result">
            <xsl:choose>
                <xsl:when test="$rs_exDefinition != '' ">
                    <xsl:value-of select="$rs_exDefinition"/>
                </xsl:when>
                <xsl:when
                    test="xalan:nodeset($tests)/descendant::test[ @type ='family' ]/@id != '' ">
                    <xsl:variable name="test"
                        select="xalan:nodeset($tests)/descendant::test[ @type ='family' ]/@id"/>
                    <xsl:value-of select="$TestedItems/oval-res:test[@test_id=$test ]/@result"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:text>true</xsl:text>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>


        <xsl:if test=" $pre_test_result = 'true' and $def_result = 'false' ">
            <findings id="{$definitionId}" xmlns="http://results.pa.mcafee.com/findings/5.2">
                <xsl:for-each
                    select="xalan:nodeset($tests)/descendant::test[ @type ='typecheckingtest' ]">
                    <xsl:variable name="test" select="@id"/>
                    <xsl:variable name="key" select="@key"/>
                    <xsl:variable name="name" select="@name"/>
                    <xsl:variable name="typeName" select="@typeName"/>

                    <xsl:for-each
                        select="$TestedItems/oval-res:test[@test_id=$test ]/oval-res:tested_item[ @result = 'false' ] ">

                        <xsl:variable name="itemRef" select="@item_id"/>
                        <xsl:variable name="result" select="@result"/>

                        <xsl:variable name="actualParameterType"
                            select="$SystemData/win-sc:registry_item[@id=$itemRef]/win-sc:type"/>

                        <xsl:if test="$actualParameterType != '' ">
                            <finding messageId="com.mcafee.pa.msg.winregistryvaluetypeisinvalid"
                                isViolation="true">
                                <instanceValue key="registry">
                                    <xsl:value-of select="$key"/>
                                    <xsl:text>\</xsl:text>
                                    <xsl:value-of select="$name"/>
                                </instanceValue>
                                <instanceValue key="expectedType">
                                    <xsl:value-of select="$typeName"/>
                                </instanceValue>
                                <actualValue key="actualType">
                                    <xsl:value-of select="$actualParameterType"/>
                                </actualValue>
                            </finding>
                        </xsl:if>
                    </xsl:for-each>
                </xsl:for-each>

                <xsl:for-each
                    select="xalan:nodeset($tests)/descendant::test[ @type ='primarytest' ]">
                    <xsl:variable name="test" select="@id"/>
                    <xsl:variable name="state" select="@state"/>
                    <xsl:variable name="key" select="@key"/>
                    <xsl:variable name="name" select="@name"/>

                    <xsl:variable name="externalVarId" select="@externalVar"/>
                    <xsl:variable name="operation" select="@operation"/>

                    <xsl:if test="$externalVarId != '' ">

                        <xsl:variable name="externalVarValue"
                            select="$TestedItems/oval-res:test[@test_id=$test ]/oval-res:tested_variable[@variable_id = $externalVarId]"/>

                        <xsl:variable name="inputRegistryParameterValue"
                            select="$externalVarValue" />
							
                        <inputValue key="expectedValue">
                            <xsl:value-of select="$inputRegistryParameterValue"/>
                        </inputValue>
                        <xsl:for-each
                            select="$TestedItems/oval-res:test[@test_id=$test ]/oval-res:tested_item[ @result = 'false'  or @result = 'error'  or  @result='not evaluated' ] ">

                            <xsl:variable name="itemRef" select="@item_id"/>
                            <xsl:variable name="result" select="@result"/>

                            <xsl:variable name="actualParameterValue"
                                select="$SystemData/win-sc:registry_item[@id=$itemRef]/win-sc:value"/>
                            <xsl:variable name="actualParameterStatus"
                                select="$SystemData/win-sc:registry_item[@id=$itemRef]/win-sc:name/@status"/>

                            <xsl:variable name="actualParameterPrintableValue"
                               select="$actualParameterValue"/>

                            <xsl:variable name="message_id">
                                <xsl:call-template name="getMessageId">
                                    <xsl:with-param name="id"
                                        select="normalize-space($definitionId)"/>
                                    <xsl:with-param name="status"
                                        select="normalize-space($actualParameterStatus)"/>
                                </xsl:call-template>
                            </xsl:variable>


                            <finding messageId="{$message_id}" isViolation="true">
                                <actualValue key="actualValue">
                                    <xsl:value-of select="$actualParameterPrintableValue"/>
                                </actualValue>
                            </finding>
                        </xsl:for-each>
                    </xsl:if>

                    <xsl:if test=" $state = '' ">
                        <xsl:for-each
                            select="$TestedItems/oval-res:test[@test_id=$test ]/oval-res:tested_item[ @result = 'false'  or @result = 'error'  or  @result='not evaluated' ] ">

                            <xsl:variable name="itemRef" select="@item_id"/>
                            <xsl:variable name="result" select="@result"/>

                            <xsl:variable name="actualParameterValue"
                                select="$SystemData/win-sc:registry_item[@id=$itemRef]/win-sc:value"/>
                            <xsl:variable name="actualParameterStatus"
                                select="$SystemData/win-sc:registry_item[@id=$itemRef]/win-sc:name/@status"/>

                            <xsl:variable name="message_id">
                                <xsl:choose>
                                    <xsl:when test="$actualParameterStatus = 'does not exist' ">
                                        <xsl:text>com.mcafee.pa.msg.winregistryisnotexist</xsl:text>
                                    </xsl:when>
                                    <xsl:when test="$result = 'error' or  $result='not evaluated' ">
                                        <xsl:text>com.mcafee.pa.msg.winregistryreaderror</xsl:text>
                                    </xsl:when>
                                    <xsl:otherwise>
                                        <xsl:text>com.mcafee.pa.msg.winregistryisexist</xsl:text>
                                    </xsl:otherwise>
                                </xsl:choose>
                            </xsl:variable>

                            <finding messageId="{$message_id}" isViolation="true">
                                <instanceValue key="registry">
                                    <xsl:value-of select="$key"/>
                                    <xsl:text>\</xsl:text>
                                    <xsl:value-of select="$name"/>
                                </instanceValue>
                            </finding>
                        </xsl:for-each>
                    </xsl:if>

                </xsl:for-each>
            </findings>
        </xsl:if>

        <xsl:if test=" $def_result = 'true' ">
            <findings id="{$definitionId}" xmlns="http://results.pa.mcafee.com/findings/5.2">
                <xsl:for-each
                    select="xalan:nodeset($tests)/descendant::test[ @type ='primarytest' ]">
                    <xsl:variable name="test" select="@id"/>
                    <xsl:variable name="state" select="@state"/>
                    <xsl:variable name="key" select="@key"/>
                    <xsl:variable name="name" select="@name"/>

                    <xsl:variable name="externalVarId" select="@externalVar"/>
                    <xsl:variable name="operation" select="@operation"/>

                    <xsl:if test="$externalVarId != '' ">

                        <xsl:variable name="externalVarValue"
                            select="$TestedItems/oval-res:test[@test_id=$test ]/oval-res:tested_variable[@variable_id = $externalVarId]"/>

                        <xsl:variable name="inputRegistryParameterValue"
                               select="$externalVarValue"/>
                        
                        <inputValue key="expectedValue">
                            <xsl:value-of select="$inputRegistryParameterValue"/>
                        </inputValue>

                        <xsl:for-each
                            select="$TestedItems/oval-res:test[@test_id=$test ]/oval-res:tested_item[ @result = 'true' ] ">

                            <xsl:variable name="itemRef" select="@item_id"/>
                            <xsl:variable name="result" select="@result"/>

                            <xsl:variable name="actualParameterValue"
                                select="$SystemData/win-sc:registry_item[@id=$itemRef]/win-sc:value"/>

                            <xsl:variable name="actualParameterPrintableValue"
                                 select="$actualParameterValue"/>

                            <xsl:variable name="message_id">
                                <xsl:call-template name="getMessageId">
                                    <xsl:with-param name="id" select="$definitionId"/>
                                </xsl:call-template>
                            </xsl:variable>


                            <finding messageId="{$message_id}" isViolation="false">
                                <actualValue key="actualValue">
                                    <xsl:value-of select="$actualParameterPrintableValue"/>
                                </actualValue>
                            </finding>
                        </xsl:for-each>
                    </xsl:if>


                </xsl:for-each>
            </findings>
        </xsl:if>

        <xsl:if test="$pre_test_result = 'false'  and $def_result = 'false' ">
            <xsl:variable name="getIE7InstallationResult">
                <xsl:value-of
                    select="xalan:nodeset($exDefinitionId)/descendant::extend_definition[@id = 'oval:com.mcafee.oval.ie7:def:627']/@result"
                />
            </xsl:variable>
            <xsl:if test="$getIE7InstallationResult = 'false' ">
                <findings id="{$definitionId}" xmlns="http://results.pa.mcafee.com/findings/5.2">
                    <finding messageId="com.mcafee.pa.msg.ie7isnotinstalled" isViolation="true"/>
                </findings>
            </xsl:if>
            <xsl:variable name="getWindowsXPInstallationResult">
                <xsl:value-of
                    select="xalan:nodeset($exDefinitionId)/descendant::extend_definition[@id = 'oval:com.mcafee.oval.1:def:2']/@result"
                />
            </xsl:variable>
            <xsl:if test="$getWindowsXPInstallationResult = 'false' ">
                <findings id="{$definitionId}" xmlns="http://results.pa.mcafee.com/findings/5.2">
                    <finding messageId="com.mcafee.pa.msg.winxpisnotinstalled" isViolation="true"/>
                </findings>
            </xsl:if>
        </xsl:if>


    </xsl:template>

</xsl:stylesheet>
