GovReady / govready

Toolkit for getting open source apps ready for secure, approved government use
GNU General Public License v3.0
97 stars 31 forks source link

Need to dynamically adjust xccdf/cdf namespace in xsl files from xccdf/1.1 to xccdf/1.2 depending content used. #78

Open gregelin opened 9 years ago

gregelin commented 9 years ago

Name spaces need to adjust automatically in xslt .xsl files, like .govready/xml/scaninfo.xsl depending on names space of schema used to scan.

.govready/xml/scaninfo.xsl and .govready/xml/scaninfo-arf.xsl are essentially same file, except for xccdf name space.

gregelin commented 9 years ago

@openprivacy govready compare, govready rule, etc are all failing because the arf format is using xmlns:cdf="http://checklists.nist.gov/xccdf/1.2 instead of xmlns:cdf="http://checklists.nist.gov/xccdf/1.1.

Changing the name space in the .govready/xml/*.xsl files corrects the problem.

My fix for the quickie report in #79 is not very scalable. We should improve.

A better solution might be to store the xslt as internal templates in GovReady functions with the ability to adjust the name space when the function is called.

The methods, _govready_init_scaninfo_file and _govready_init_scaninfo_arf_file currently write an XSLT file into .govready/xml to be used with xsltproc. Instead of writing the templates to directory, we could call the templates when commands like xsltproc scaninfo_arf.xsl result-file-name.xml are run (see line 928.

local gov_command="xsltproc .govready/xml/scaninfo_arf.xsl ${RESULTS_DIR}/results-arf.xml"
gregelin commented 9 years ago

@fen - easiest solution might be to simply grep for the correct name space.

[vagrant@odesurvey ~]$ grep  -nir  'xmlns="http://checklists.nist.gov/xccdf/1.1"' myfisma/scans/test/results.xml | head -1 | wc -l
1
[vagrant@odesurvey ~]$ grep  -nir  'xmlns="http://checklists.nist.gov/xccdf/1.2"' myfisma/scans/test/results.xml | head -1 | wc -l
0

Other possible solutions:

gregelin commented 9 years ago

Using xmllint

If we xpath for namespace that includes 1.2, and tag uses name space, lots of nodes are returned

xmllint --xpath "//*[local-name()='TestResult' and namespace-uri()='http://checklists.nist.gov/xccdf/1.2']" scans/xccdf_org.ssgproject.content_profile_stig-rhel7-server-upstream-192.168.56.112/results-arf.xml 

If we xpath for namespace that includes 1.1, but tag uses namespace that is 1.2, XPath set is empty is returned:

$> xmllint --xpath "//*[local-name()='TestResult' and namespace-uri()='http://checklists.nist.gov/xccdf/1.1']" scans/xccdf_org.ssgproject.content_profile_stig-rhel7-server-upstream-192.168.56.112/results-arf.xml 
XPath set is empty
gregelin commented 9 years ago

Getting better. Let's see if we can just return numbers...

[vagrant@localhost myfisma]$ echo $FILE
scans/xccdf_org.ssgproject.content_profile_stig-rhel7-server-upstream-192.168.56.112/results-arf.xml
[vagrant@localhost myfisma]$ xmllint --xpath "count(//*[local-name()='TestResult' and namespace-uri()='http://checklists.nist.gov/xccdf/1.1'])" $FILE
0
[vagrant@localhost myfisma]$xmllint --xpath "count(//*[local-name()='TestResult' and namespace-uri()='http://checklists.nist.gov/xccdf/1.2'])" $FILE
1

This approach is a bit risk for an arbitrary ARF file that may have more than one Results section.

gregelin commented 9 years ago

cat and sed to dynamically adjust the xccdf namespace:

cat .govready/xml/filterresults.xsl | sed -e 's~\(xmlns:cdf="http://checklists.nist.gov/xccdf/\).*~\11.2"~'
gregelin commented 9 years ago

@fen suggests a better way of sending in the namespace as a parameter.

First step, move the namespace into the body of the XSLT like so:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:exsl="http://exslt.org/common"
    xmlns:db="http://docbook.org/ns/docbook"
    xmlns:xlink="http://www.w3.org/1999/xlink"
    xmlns="http://docbook.org/ns/docbook"
    xmlns:s="http://open-scap.org/"
    exclude-result-prefixes="xsl cdf db s exsl"
    xmlns:ovalres="http://oval.mitre.org/XMLSchema/oval-results-5"
    xmlns:sceres="http://open-scap.org/page/SCE_result_file"
    >

<!--
****************************************************************************************

Copyright: Greg Elin, 2014

This style sheet lists all failed rules

usage: $> xsltproc - -stringparam paramname paramvalue filterresults.xsl result-file-name.xml
examples
    Which rules pass in most recent scan?
       xsltproc - -stringparam result pass filterresults.xsl scans/results.xml

    Which rules fail in most recent scan?
       xsltproc - -stringparam result fail filterresults.xsl scans/results.xml

    Compare all results that are other than "notselected" 
       xsltproc filterresults.xsl scans/results.xml

-->

<xsl:param name="result">notdefined</xsl:param>
<xsl:strip-space elements="*"/>
<xsl:output method="text" encoding="UTF-8" />

<xsl:template match="/">
    <xsl:apply-templates/>
</xsl:template>

<xsl:template match="/">
<xsl:choose>
  <xsl:when test="$result = 'notdefined'">
    <xsl:for-each select='cdf:Benchmark/cdf:TestResult/cdf:rule-result[cdf:result != "notselected"]' xmlns:cdf="http://checklists.nist.gov/xccdf/1.2">
      <xsl:value-of select="@idref"/>
    <xsl:text>
</xsl:text>
   </xsl:for-each>
  </xsl:when>
  <xsl:otherwise>
    <xsl:for-each select='cdf:Benchmark/cdf:TestResult/cdf:rule-result[cdf:result = $result]' xmlns:cdf="http://checklists.nist.gov/xccdf/1.2">
      <xsl:value-of select="@idref"/>
    <xsl:text>
</xsl:text>
    </xsl:for-each>
  </xsl:otherwise>
</xsl:choose>

</xsl:template>
<!-- include to stop leakage from builtin tempaltes -->
<xsl:template match='node()' mode='engine-results'/>
<xsl:template match="text()"/>

</xsl:stylesheet>