[PATCH 3/4] rewrite of combinefixes.py to handle parameters for OpenSCAP remedation generation

Jeffrey Blank blank at eclipse.ncsc.mil
Sun Jun 2 19:05:21 UTC 2013


Signed-off-by: Jeffrey Blank <blank at eclipse.ncsc.mil>
---
 RHEL6/transforms/combinefixes.py |   97 +++++++++++++++++---------------------
 1 files changed, 44 insertions(+), 53 deletions(-)

diff --git a/RHEL6/transforms/combinefixes.py b/RHEL6/transforms/combinefixes.py
index f9d8b7f..71fbe6f 100755
--- a/RHEL6/transforms/combinefixes.py
+++ b/RHEL6/transforms/combinefixes.py
@@ -1,58 +1,49 @@
 #!/usr/bin/python
 
-import sys, os 
-
-header = '''<fix-content system="urn:xccdf:fix:script:sh" xmlns="http://checklists.nist.gov/xccdf/1.1">\n'''
-footer = '</fix-content>\n'
-fixGroupHeader = '''<fix-group id="bash" system="urn:xccdf:fix:script:sh" xmlns="http://checklists.nist.gov/xccdf/1.1">\n'''
-fixGroupFooter = '</fix-group>\n'
-fixCommonGroupHeader = '''<fix-common-group id="bash-common" xmlns="http://checklists.nist.gov/xccdf/1.1">\n'''
-fixCommonGroupFooter = '</fix-common-group>\n'
-
-def encode(text):
-    text = text.replace('&','&amp;')
-    text = text.replace('>','&gt;')
-    text = text.replace('<','&lt;')
-    return text
+import sys, os, re, lxml.etree as etree
+
+def substitute_vars(fix):
+	# brittle and troubling code to assign environment vars to XCCDF values
+	m = re.match("(\s*source\s+\S+)\n+(\s*populate\s+)(\S+)\n(.*)", fix.text, re.DOTALL)
+	if not m: 
+		# no need to alter fix.text
+		return
+	# otherwise, create node to populate environment variable
+	varname = m.group(3)
+	mainscript = m.group(4)
+	fix.text = varname + "=" + '"'
+	# new <sub> element to reference XCCDF variable
+	xccdf_sub = etree.SubElement(fix, "sub", idref=varname)
+	xccdf_sub.tail = '"' + mainscript
+	fix.append(xccdf_sub)
+	
 
 def main():
-    if len(sys.argv) < 2:
-        print "Provide a directory name, which contains the fixes."
-        sys.exit(1)
-        
-    fixDir = sys.argv[1]
-    output = sys.argv[2]
-    out = open(output,'w')
-    out.write(header)
-    out.write(fixGroupHeader)
-    for filename in os.listdir(fixDir):
-        if filename.endswith(".sh"):
-            body = ""
-            with open( fixDir + "/" + filename, 'r') as f:
-                body = body + encode(f.read())
-            fixName = os.path.splitext(filename)[0]
-            out.write("<fix rule=\""+fixName+"\">\n")
-            out.write(body.rstrip())
-            out.write("</fix>\n")
-
-    out.write(fixGroupFooter)
-
-    out.write(fixCommonGroupHeader)
-    for filename in os.listdir(fixDir):
-        if filename.endswith("common"):
-            body = ""
-            with open( fixDir + "/" + filename, 'r') as f:
-                body = body + encode(f.read())
-            fixName = os.path.splitext(filename)[0]
-            out.write("<fix-common id=\""+fixName+"\">\n")
-            out.write(body.rstrip())
-            out.write("</fix-common>\n")
-
-    out.write(fixCommonGroupFooter)
-    out.write(footer)
-
-    out.close()
-    sys.exit(0)
-        
+	if len(sys.argv) < 2:
+		print "Provide a directory name, which contains the fixes."
+		sys.exit(1)
+		
+	fixdir = sys.argv[1]
+	output = sys.argv[2]
+
+	fixcontent = etree.Element("fix-content", system="urn:xccdf:fix:script:sh", xmlns="http://checklists.nist.gov/xccdf/1.1")
+	fixgroup = etree.SubElement(fixcontent, "fix-group", id="bash", system="urn:xccdf:fix:script:sh", xmlns="http://checklists.nist.gov/xccdf/1.1")
+	
+	for filename in os.listdir(fixdir):
+		if filename.endswith(".sh"):
+			# create and populate new fix element based on shell file
+			fixname = os.path.splitext(filename)[0]
+			fix = etree.SubElement(fixgroup, "fix", rule=fixname)
+			with open( fixdir + "/" + filename, 'r') as f:
+				# assignment automatically escapes shell characters for XML
+				fix.text = f.read()
+				# replace instance of bash function "populate" with XCCDF variable substitution
+				substitute_vars(fix)
+
+	tree = etree.ElementTree(fixcontent)
+	tree.write(output, pretty_print=True)
+
+	sys.exit(0)
+		
 if __name__ == "__main__":
-    main()
+	main()
-- 
1.7.1



More information about the scap-security-guide mailing list