Ejemplo n.º 1
0
def main():
    if len(sys.argv) < 2:
        print "Provide an OVAL file that contains inventory definitions."
        print "This script extracts these definitions and writes them to STDOUT."
        sys.exit(1)

    ovalfile = sys.argv[1]
    cpedictfile = sys.argv[2]
    idname = sys.argv[3]

    # parse oval file
    ovaltree = parse_xml_file(ovalfile)

    # extract inventory definitions
    # making (dubious) assumption that all inventory defs are CPE
    defs = ovaltree.find("./{%s}definitions" % oval_ns)
    inventory_defs = defs.findall(".//{%s}definition[@class='inventory']" % oval_ns)
    defs.clear()
    [defs.append(inventory_def) for inventory_def in inventory_defs]

    tests = ovaltree.find("./{%s}tests" % oval_ns)
    cpe_tests = extract_referred_nodes(defs, tests, "test_ref")
    tests.clear()
    [tests.append(cpe_test) for cpe_test in cpe_tests]

    states = ovaltree.find("./{%s}states" % oval_ns)
    cpe_states = extract_referred_nodes(tests, states, "state_ref")
    states.clear()
    [states.append(cpe_state) for cpe_state in cpe_states]

    objects = ovaltree.find("./{%s}objects" % oval_ns)
    cpe_objects = extract_referred_nodes(tests, objects, "object_ref")
    objects.clear()
    [objects.append(cpe_object) for cpe_object in cpe_objects]

    variables = ovaltree.find("./{%s}variables" % oval_ns)
    cpe_variables = extract_referred_nodes(ovaltree, variables, "var_ref")
    if cpe_variables:
        variables.clear()
        [variables.append(cpe_variable) for cpe_variable in cpe_variables]
    else:
        ovaltree.remove(variables)

        # turn IDs into meaningless numbers
    translator = idtranslate.idtranslator("./output/" + idname + ".ini", idname)
    ovaltree = translator.translate(ovaltree)

    newovalfile = ovalfile.replace("oval", "cpe-oval")
    newovalfile = newovalfile.replace("unlinked", idname)
    ET.ElementTree(ovaltree).write(newovalfile)

    # replace and sync IDs, href filenames in input cpe dictionary file
    cpedicttree = parse_xml_file(cpedictfile)
    newcpedictfile = idname + "-" + os.path.basename(cpedictfile)
    for check in cpedicttree.findall(".//{%s}check" % cpe_ns):
        check.set("href", os.path.basename(newovalfile))
        check.text = translator.assign_id("{" + oval_ns + "}definition", check.text)
    ET.ElementTree(cpedicttree).write("./output/" + newcpedictfile)

    sys.exit(0)
Ejemplo n.º 2
0
def main():
    global definitions
    global tests
    global objects
    global states
    global variables

    if len(sys.argv) < 2:
        print "Provide the name of an XML file, which contains the definition to test."
        sys.exit(1)

    for testfile in sys.argv[1:]:
        body = read_ovaldefgroup_file(testfile)
        defname = add_oval_elements(body)
        ovaltree = ET.fromstring(header + footer)
        # append each major element type, if it has subelements
        for element in [definitions, tests, objects, states, variables]:
            if element.getchildren():
                ovaltree.append(element)
        # re-map all the element ids from meaningful names to meaningless numbers
        testtranslator = idtranslate.idtranslator(
            "testids.ini", "oval:scap-security-guide.testing")
        ovaltree = testtranslator.translate(ovaltree)
        (ovalfile, fname) = tempfile.mkstemp(prefix=defname, suffix=".xml")
        os.write(ovalfile, ET.tostring(ovaltree))
        os.close(ovalfile)
        print "Evaluating with OVAL tempfile : " + fname
        # temporary workaround for fedora/redhat oscap version differences
        # (distname, distversion, distcodename) = platform.linux_distribution(full_distribution_name=0)
        # if distname == 'redhat':
        #    subprocess.call("oscap oval eval --result-file "+ fname + "-results " + fname, shell=True)
        # else:

        # content requires OVAL 5.8 support, which is only supported by openscap 0.8 or later
        # for RHEL 6, this implies installing openscap from source until RPM is released
        subprocess.call("oscap oval eval --results " + fname + "-results " +
                        fname,
                        shell=True)
        # perhaps delete tempfile?
        definitions = ET.Element("definitions")
        tests = ET.Element("tests")
        objects = ET.Element("objects")
        states = ET.Element("states")
        variables = ET.Element("variables")

    sys.exit(0)
Ejemplo n.º 3
0
def main():
    global definitions
    global tests
    global objects
    global states
    global variables

    if len(sys.argv) < 2:
        print "Provide the name of an XML file, which contains the definition to test."
        sys.exit(1)

    for testfile in sys.argv[1:]:
        body = read_ovaldefgroup_file(testfile)
        defname = add_oval_elements(body)
        ovaltree = ET.fromstring(header + footer)
        # append each major element type, if it has subelements
        for element in [definitions, tests, objects, states, variables]:
            if element.getchildren():
                ovaltree.append(element)
        # re-map all the element ids from meaningful names to meaningless numbers
        testtranslator = idtranslate.idtranslator("testids.ini", "oval:scap-security-guide.testing")
        ovaltree = testtranslator.translate(ovaltree)
        (ovalfile, fname) = tempfile.mkstemp(prefix=defname,suffix=".xml")
        os.write(ovalfile, ET.tostring(ovaltree))
        os.close(ovalfile)
        print "Evaluating with OVAL tempfile : " + fname
	# temporary workaround for fedora/redhat oscap version differences
        # (distname, distversion, distcodename) = platform.linux_distribution(full_distribution_name=0)
        # if distname == 'redhat':
        #    subprocess.call("oscap oval eval --result-file "+ fname + "-results " + fname, shell=True)
        # else:

        # content requires OVAL 5.8 support, which is only supported by openscap 0.8 or later
        # for RHEL 6, this implies installing openscap from source until RPM is released
        subprocess.call("oscap oval eval --results "+ fname + "-results " + fname, shell=True)
        # perhaps delete tempfile?
        definitions = ET.Element("definitions")
        tests = ET.Element("tests")
        objects = ET.Element("objects")
        states = ET.Element("states")
        variables = ET.Element("variables")

    sys.exit(0)
Ejemplo n.º 4
0
def main():
    global definitions
    global tests
    global objects
    global states
    global variables

    if len(sys.argv) < 2:
        print "Provide the name of an XML file, which contains the definition to test."
        sys.exit(1)

    for testfile in sys.argv[1:]:
        body = read_ovaldefgroup_file(testfile)
        defname = add_oval_elements(body)
        ovaltree = ET.fromstring(header + footer)
        # append each major element type, if it has subelements
        for element in [definitions, tests, objects, states, variables]:
            if element.getchildren():
                ovaltree.append(element)
        # re-map all the element ids from meaningful names to meaningless numbers
        testtranslator = idtranslate.idtranslator(
            "testids.ini", "scap-security-guide.testing")
        ovaltree = testtranslator.translate(ovaltree)
        (ovalfile, fname) = tempfile.mkstemp(prefix=defname, suffix=".xml")
        os.write(ovalfile, ET.tostring(ovaltree))
        os.close(ovalfile)
        print "Evaluating with OVAL tempfile : " + fname
        print "Writing results to : " + fname + "-results"
        subprocess.call("oscap oval eval --results " + fname + "-results " +
                        fname,
                        shell=True)
        # perhaps delete tempfile?
        definitions = ET.Element("definitions")
        tests = ET.Element("tests")
        objects = ET.Element("objects")
        states = ET.Element("states")
        variables = ET.Element("variables")

    sys.exit(0)
Ejemplo n.º 5
0
def main():
    global definitions
    global tests
    global objects
    global states
    global variables

    if len(sys.argv) < 2:
        print "Provide the name of an XML file, which contains the definition to test."
        sys.exit(1)

    for testfile in sys.argv[1:]:
        body = read_ovaldefgroup_file(testfile)
        defname = add_oval_elements(body)
        ovaltree = ET.fromstring(header + footer)
        # append each major element type, if it has subelements
        for element in [definitions, tests, objects, states, variables]:
            if element.getchildren():
                ovaltree.append(element)
        # re-map all the element ids from meaningful names to meaningless numbers
        testtranslator = idtranslate.idtranslator("testids.ini", "scap-security-guide.testing")
        ovaltree = testtranslator.translate(ovaltree)
        (ovalfile, fname) = tempfile.mkstemp(prefix=defname, suffix=".xml")
        os.write(ovalfile, ET.tostring(ovaltree))
        os.close(ovalfile)
        print "Evaluating with OVAL tempfile : " + fname
        print "Writing results to : " + fname + "-results"
        subprocess.call("oscap oval eval --results " + fname + "-results " + fname, shell=True)
        # perhaps delete tempfile?
        definitions = ET.Element("definitions")
        tests = ET.Element("tests")
        objects = ET.Element("objects")
        states = ET.Element("states")
        variables = ET.Element("variables")

    sys.exit(0)
Ejemplo n.º 6
0
def main():
    if len(sys.argv) < 3:
        print "Provide an XCCDF file and an ID name scheme."
        print ("This script finds check-content files (currently, OVAL " +
               "and OCIL) referenced from XCCDF and synchronizes all IDs.")
        sys.exit(1)

    xccdffile = sys.argv[1]
    idname = sys.argv[2]

    os.chdir("./output")
    # step over xccdf file, and find referenced check files
    xccdftree = parse_xml_file(xccdffile)

    # Check that OVAL IDs and XCCDF Rule IDs match
    if 'unlinked-ocilref' not in xccdffile:
        allrules = xccdftree.findall(".//{%s}Rule" % xccdf_ns)
        for rule in allrules:
            xccdf_rule = rule.get("id")
            if xccdf_rule is not None:
                checks = rule.find("./{%s}check" % xccdf_ns)
                if checks is not None:
                    for check in checks:
                        oval_id = check.get("name")
                        if not xccdf_rule == oval_id and oval_id is not None \
                            and not xccdf_rule == 'sample_rule':
                            print("The OVAL ID does not match the XCCDF Rule ID!\n"
                                  "\n  OVAL ID:       \'%s\'"
                                  "\n  XCCDF Rule ID: \'%s\'"
                                  "\n\nBoth OVAL and XCCDF Rule IDs must match!") % (oval_id, xccdf_rule)
                            sys.exit(1)

    checks = xccdftree.findall(".//{%s}check" % xccdf_ns)
    ovalfiles = get_checkfiles(checks, oval_cs)
    ocilfiles = get_checkfiles(checks, ocil_cs)

    if len(ovalfiles) > 1 or len(ocilfiles) > 1:
        sys.exit("referencing more than one file per check system " +
                 "is not yet supported by this script.")
    ovalfile = ovalfiles.pop() if ovalfiles else None
    ocilfile = ocilfiles.pop() if ocilfiles else None

    translator = idtranslate.idtranslator(idname+".ini", idname)

    # rename all IDs in the oval file
    if ovalfile:
        ovaltree = parse_xml_file(ovalfile)
        ovaltree = translator.translate(ovaltree, store_defname=True)
        newovalfile = ovalfile.replace("unlinked", idname)
        ET.ElementTree(ovaltree).write(newovalfile)

    # rename all IDs in the ocil file
    if ocilfile:
        ociltree = parse_xml_file(ocilfile)
        ociltree = translator.translate(ociltree)
        newocilfile = ocilfile.replace("unlinked", idname)
        ET.ElementTree(ociltree).write(newocilfile)

    # rename all IDs and file refs in the xccdf file
    for check in checks:
        checkcontentref = check.find("./{%s}check-content-ref" % xccdf_ns)

        # Don't attempt to relabel ID on empty <check-content-ref> element
        if checkcontentref is None:
            continue
        # Obtain the value of the 'href' attribute of particular
        # <check-content-ref> element
        checkcontentref_hrefattr = checkcontentref.get("href")

        # Don't attempt to relabel ID on <check-content-ref> element having
        # its "href" attribute set either to "http://" or to "https://" values
        if checkcontentref_hrefattr.startswith("http://") or \
           checkcontentref_hrefattr.startswith("https://"):
            continue

        if check.get("system") == oval_cs:
            checkid = translator.assign_id("{" + oval_ns + "}definition",
                                           checkcontentref.get("name"))
            checkcontentref.set("name", checkid)
            checkcontentref.set("href", newovalfile)
            checkexport = check.find("./{%s}check-export" % xccdf_ns)
            if checkexport is not None:
                newexportname = translator.assign_id("{" + oval_ns + "}variable",
                                                     checkexport.get("export-name"))
                checkexport.set("export-name", newexportname)

        if check.get("system") == ocil_cs:
            checkid = translator.assign_id("{" + ocil_ns + "}questionnaire",
                                           checkcontentref.get("name"))
            checkcontentref.set("name", checkid)
            checkcontentref.set("href", newocilfile)
            checkexport = check.find("./{%s}check-export" % xccdf_ns)
            if checkexport is not None:
                newexportname = translator.assign_id("{" + oval_ns + "}variable",
                                                     checkexport.get("export-name"))
                checkexport.set("export-name", newexportname)

    newxccdffile = xccdffile.replace("unlinked", idname)
    # ET.dump(xccdftree)
    ET.ElementTree(xccdftree).write(newxccdffile)
    sys.exit(0)
Ejemplo n.º 7
0
def main():
	if len(sys.argv) < 3:
		print "Provide an XCCDF file and an ID name scheme."
		print "This script finds check-content files (currently, OVAL and OCIL) referenced from XCCDF and synchronizes all IDs."
		sys.exit(1)

	xccdffile = sys.argv[1]
	idname = sys.argv[2]

	os.chdir("./output")
	# step over xccdf file, and find referenced check files
	xccdftree = parse_xml_file(xccdffile)

	checks = xccdftree.findall(".//{%s}check" % xccdf_ns)
	ovalfiles = get_checkfiles(checks, oval_cs)
	ocilfiles = get_checkfiles(checks, ocil_cs)

	if len(ovalfiles) > 1 or len(ocilfiles) > 1:
		sys.exit("referencing more than one file per check system is not yet supported by this script.")
	ovalfile = ovalfiles.pop() if ovalfiles else None
	ocilfile = ocilfiles.pop() if ocilfiles else None

	translator = idtranslate.idtranslator(idname+".ini", idname)

	# rename all IDs in the oval file
	if ovalfile:
		ovaltree = parse_xml_file(ovalfile) 
		ovaltree = translator.translate(ovaltree, store_defname=True)
		newovalfile = ovalfile.replace("unlinked", idname)
		ET.ElementTree(ovaltree).write(newovalfile)

	# rename all IDs in the ocil file
	if ocilfile:
		ociltree = parse_xml_file(ocilfile) 
		ociltree = translator.translate(ociltree)
		newocilfile = ocilfile.replace("unlinked", idname)
		ET.ElementTree(ociltree).write(newocilfile)

	# rename all IDs and file refs in the xccdf file
	for check in checks:
		checkcontentref = check.find("./{%s}check-content-ref" % xccdf_ns)
		if checkcontentref is None:
			continue

		if check.get("system") == oval_cs:
			checkid = translator.assign_id("{" + oval_ns + "}definition", checkcontentref.get("name"))
			checkcontentref.set("name", checkid)
			checkcontentref.set("href", newovalfile)
			checkexport = check.find("./{%s}check-export" % xccdf_ns)
			if checkexport is not None:
				newexportname = translator.assign_id("{"+ oval_ns + "}variable", checkexport.get("export-name"))
				checkexport.set("export-name", newexportname) 

		if check.get("system") == ocil_cs:
			checkid = translator.assign_id("{" + ocil_ns + "}questionnaire", checkcontentref.get("name"))
			checkcontentref.set("name", checkid)
			checkcontentref.set("href", newocilfile)
			checkexport = check.find("./{%s}check-export" % xccdf_ns)
			if checkexport is not None:
				newexportname = translator.assign_id("{"+ oval_ns + "}variable", checkexport.get("export-name"))
				checkexport.set("export-name", newexportname) 

	newxccdffile = xccdffile.replace("unlinked", idname)
	#ET.dump(xccdftree)
	ET.ElementTree(xccdftree).write(newxccdffile)
	sys.exit(0)
Ejemplo n.º 8
0
def main():
    if len(sys.argv) < 2:
        print "Provide an OVAL file that contains inventory definitions."
        print("This script extracts these definitions and writes them" +
              " to STDOUT.")
        sys.exit(1)

    ovalfile = sys.argv[1]
    cpedictfile = sys.argv[2]
    idname = sys.argv[3]

    # parse oval file
    ovaltree = parse_xml_file(ovalfile)

    # extract inventory definitions
    # making (dubious) assumption that all inventory defs are CPE
    defs = ovaltree.find("./{%s}definitions" % oval_ns)
    inventory_defs = defs.findall(".//{%s}definition[@class='inventory']" %
                                  oval_ns)
    defs.clear()
    [defs.append(inventory_def) for inventory_def in inventory_defs]

    tests = ovaltree.find("./{%s}tests" % oval_ns)
    cpe_tests = extract_referred_nodes(defs, tests, "test_ref")
    tests.clear()
    [tests.append(cpe_test) for cpe_test in cpe_tests]

    states = ovaltree.find("./{%s}states" % oval_ns)
    cpe_states = extract_referred_nodes(tests, states, "state_ref")
    states.clear()
    [states.append(cpe_state) for cpe_state in cpe_states]

    objects = ovaltree.find("./{%s}objects" % oval_ns)
    cpe_objects = extract_referred_nodes(tests, objects, "object_ref")
    objects.clear()
    [objects.append(cpe_object) for cpe_object in cpe_objects]

    variables = ovaltree.find("./{%s}variables" % oval_ns)
    if variables:
        cpe_variables = extract_referred_nodes(tests, variables, "var_ref")
        if cpe_variables:
            variables.clear()
            [variables.append(cpe_variable) for cpe_variable in cpe_variables]
        else:
            ovaltree.remove(variables)

    # turn IDs into meaningless numbers
    translator = idtranslate.idtranslator("./output/" + idname + ".ini",
                                          idname)
    ovaltree = translator.translate(ovaltree)

    newovalfile = ovalfile.replace("oval", "cpe-oval")
    newovalfile = newovalfile.replace("unlinked", idname)
    ET.ElementTree(ovaltree).write(newovalfile)

    # replace and sync IDs, href filenames in input cpe dictionary file
    cpedicttree = parse_xml_file(cpedictfile)
    newcpedictfile = idname + "-" + os.path.basename(cpedictfile)
    for check in cpedicttree.findall(".//{%s}check" % cpe_ns):
        check.set("href", os.path.basename(newovalfile))
        check.text = translator.assign_id("{" + oval_ns + "}definition",
                                          check.text)
    ET.ElementTree(cpedicttree).write("./output/" + newcpedictfile)

    sys.exit(0)
Ejemplo n.º 9
0
def main():
    if len(sys.argv) < 3:
        print "Provide an XCCDF file and an ID name scheme."
        print (
            "This script finds check-content files (currently, OVAL "
            + "and OCIL) referenced from XCCDF and synchronizes all IDs."
        )
        sys.exit(1)

    xccdffile = sys.argv[1]
    idname = sys.argv[2]

    os.chdir("./output")
    # Step over xccdf file, and find referenced check files
    xccdftree = parse_xml_file(xccdffile)

    # Create XCCDF rule ID to assigned CCE ID mapping
    xccdf_to_cce_id_mapping = create_xccdf_id_to_cce_id_mapping(xccdftree)

    # Check that OVAL IDs and XCCDF Rule IDs match
    if "unlinked-ocilref" not in xccdffile:
        allrules = xccdftree.findall(".//{%s}Rule" % xccdf_ns)
        for rule in allrules:
            xccdf_rule = rule.get("id")
            if xccdf_rule is not None:
                checks = rule.find("./{%s}check" % xccdf_ns)
                if checks is not None:
                    for check in checks:
                        check_name = check.get("name")
                        # Verify match of XCCDF vs OVAL / OCIL IDs for
                        # * the case of OVAL <check>
                        # * the case of OCIL <check>
                        if (
                            not xccdf_rule == check_name
                            and check_name is not None
                            and not xccdf_rule + "_ocil" == check_name
                            and not xccdf_rule == "sample_rule"
                        ):
                            print ("The OVAL / OCIL ID does not match the XCCDF Rule ID!\n")
                            if "_ocil" in check_name:
                                print ("\n  OCIL ID:       '%s'" % check_name)
                            else:
                                print ("\n  OVAL ID:       '%s'" % check_name)
                            print (
                                "\n  XCCDF Rule ID: '%s'" "\n\nBoth OVAL and XCCDF Rule IDs must match!" % xccdf_rule
                            )
                            sys.exit(1)

    checks = xccdftree.findall(".//{%s}check" % xccdf_ns)
    ovalfiles = get_checkfiles(checks, oval_cs)
    ocilfiles = get_checkfiles(checks, ocil_cs)

    if len(ovalfiles) > 1 or len(ocilfiles) > 1:
        sys.exit("referencing more than one file per check system " + "is not yet supported by this script.")
    ovalfile = ovalfiles.pop() if ovalfiles else None
    ocilfile = ocilfiles.pop() if ocilfiles else None

    translator = idtranslate.idtranslator(idname)

    # Rename all IDs in the oval file
    if ovalfile:
        ovaltree = parse_xml_file(ovalfile)

        # Add new <reference source="CCE" ref_id="CCE-ID" /> element to those OVAL
        # checks having CCE ID already assigned in XCCDF for particular rule.
        # But add the <reference> only in the case CCE is in valid form!
        # Exit with failure if the assignment wasn't successful
        # Fixes: https://github.com/OpenSCAP/scap-security-guide/issues/1092
        # Fixes: https://github.com/OpenSCAP/scap-security-guide/issues/1230
        # Fixes: https://github.com/OpenSCAP/scap-security-guide/issues/1229
        # Fixes: https://github.com/OpenSCAP/scap-security-guide/issues/1228
        add_cce_id_refs_to_oval_checks(ovaltree, xccdf_to_cce_id_mapping)

        # Verify all by XCCDF referenced (local) OVAL checks are defined in OVAL file
        # If not drop the <check-content> OVAL checksystem reference from XCCDF
        # Fixes: https://github.com/OpenSCAP/scap-security-guide/issues/1092
        # Fixes: https://github.com/OpenSCAP/scap-security-guide/issues/1095
        # Fixes: https://github.com/OpenSCAP/scap-security-guide/issues/1098
        ensure_by_xccdf_referenced_oval_def_is_defined_in_oval_file(xccdftree, ovaltree)

        # Verify the XCCDF to OVAL datatype export matching constraints
        # Fixes: https://github.com/OpenSCAP/scap-security-guide/issues/1089
        check_and_correct_xccdf_to_oval_data_export_matching_constraints(xccdftree, ovaltree)

        # Verify if CCE identifiers present in the XCCDF follow the required form
        # (either CCE-XXXX-X, or CCE-XXXXX-X). Drop from XCCDF those who don't follow it
        verify_correct_form_of_referenced_cce_identifiers(xccdftree)

        ovaltree = translator.translate(ovaltree, store_defname=True)
        newovalfile = ovalfile.replace("unlinked", idname)
        ET.ElementTree(ovaltree).write(newovalfile)

    # Rename all IDs in the ocil file
    if ocilfile:
        ociltree = parse_xml_file(ocilfile)
        ociltree = translator.translate(ociltree)
        newocilfile = ocilfile.replace("unlinked", idname)
        ET.ElementTree(ociltree).write(newocilfile)

    # Rename all IDs and file refs in the xccdf file
    for check in checks:
        checkcontentref = check.find("./{%s}check-content-ref" % xccdf_ns)

        # Don't attempt to relabel ID on empty <check-content-ref> element
        if checkcontentref is None:
            continue
        # Obtain the value of the 'href' attribute of particular
        # <check-content-ref> element
        checkcontentref_hrefattr = checkcontentref.get("href")

        # Don't attempt to relabel ID on <check-content-ref> element having
        # its "href" attribute set either to "http://" or to "https://" values
        if checkcontentref_hrefattr.startswith("http://") or checkcontentref_hrefattr.startswith("https://"):
            continue

        if check.get("system") == oval_cs:
            checkid = translator.generate_id("{" + oval_ns + "}definition", checkcontentref.get("name"))
            checkcontentref.set("name", checkid)
            checkcontentref.set("href", newovalfile)
            checkexport = check.find("./{%s}check-export" % xccdf_ns)
            if checkexport is not None:
                newexportname = translator.generate_id("{" + oval_ns + "}variable", checkexport.get("export-name"))
                checkexport.set("export-name", newexportname)

        if check.get("system") == ocil_cs:
            checkid = translator.generate_id("{" + ocil_ns + "}questionnaire", checkcontentref.get("name"))
            checkcontentref.set("name", checkid)
            checkcontentref.set("href", newocilfile)
            checkexport = check.find("./{%s}check-export" % xccdf_ns)
            if checkexport is not None:
                newexportname = translator.generate_id("{" + oval_ns + "}variable", checkexport.get("export-name"))
                checkexport.set("export-name", newexportname)

    newxccdffile = xccdffile.replace("unlinked", idname)
    # ET.dump(xccdftree)
    ET.ElementTree(xccdftree).write(newxccdffile)
    sys.exit(0)
Ejemplo n.º 10
0
def main():
    if len(sys.argv) < 2:
        print "Provide an OVAL file that contains inventory definitions."
        print ("This script extracts these definitions and writes them" +
               " to STDOUT.")
        sys.exit(1)

    ovalfile = sys.argv[1]
    cpedictfile = sys.argv[2]
    idname = sys.argv[3]

    # parse oval file
    ovaltree = parse_xml_file(ovalfile)

# extract inventory definitions
# making (dubious) assumption that all inventory defs are CPE
    defs = ovaltree.find("./{%s}definitions" % oval_ns)
    inventory_defs = defs.findall(".//{%s}definition[@class='inventory']"
                                  % oval_ns)
    # Keep the list of 'id' attributes from untranslated inventory def elements
    inventory_defs_id_attrs = []

    defs.clear()
    [defs.append(inventory_def) for inventory_def in inventory_defs]
    # Fill in that list
    [inventory_defs_id_attrs.append(inventory_def.get("id")) for \
    inventory_def in inventory_defs]

    tests = ovaltree.find("./{%s}tests" % oval_ns)
    cpe_tests = extract_referred_nodes(defs, tests, "test_ref")
    tests.clear()
    [tests.append(cpe_test) for cpe_test in cpe_tests]

    states = ovaltree.find("./{%s}states" % oval_ns)
    cpe_states = extract_referred_nodes(tests, states, "state_ref")
    states.clear()
    [states.append(cpe_state) for cpe_state in cpe_states]

    objects = ovaltree.find("./{%s}objects" % oval_ns)
    cpe_objects = extract_referred_nodes(tests, objects, "object_ref")
    env_objects = extract_referred_nodes(objects, objects, "id")
    objects.clear()
    [objects.append(cpe_object) for cpe_object in cpe_objects]

    # if any subelements in an object contain var_ref, return it here
    local_var_ref = extract_subelement(objects, 'var_ref')

    variables = ovaltree.find("./{%s}variables" % oval_ns)
    if variables is not None:
        cpe_variables = extract_referred_nodes(tests, variables, "var_ref")
        local_variables = extract_referred_nodes(variables, variables, "id")
        if cpe_variables:
            variables.clear()
            [variables.append(cpe_variable) for cpe_variable in cpe_variables]
        elif local_var_ref:
            for local_var in local_variables:
                if local_var.get('id') == local_var_ref:
                    variables.clear()
                    variables.append(local_var)
                    env_obj = extract_env_obj(env_objects, local_var)
                    objects.append(env_obj)
        else:
            ovaltree.remove(variables)

    # turn IDs into meaningless numbers
    translator = idtranslate.idtranslator(idname)
    ovaltree = translator.translate(ovaltree)

    newovalfile = ovalfile.replace("oval", "cpe-oval")
    newovalfile = newovalfile.replace("unlinked", idname)
    ET.ElementTree(ovaltree).write(newovalfile)

    # replace and sync IDs, href filenames in input cpe dictionary file
    cpedicttree = parse_xml_file(cpedictfile)
    newcpedictfile = idname + "-" + os.path.basename(cpedictfile)
    for check in cpedicttree.findall(".//{%s}check" % cpe_ns):
        checkhref = check.get("href")
        # If CPE OVAL references another OVAL file
        if checkhref == 'filename':
            # Sanity check -- Verify the referenced OVAL is truly defined
            # somewhere in the (sub)directory tree below CWD. In correct
            # scenario is should be located:
            # * either in input/oval/*.xml
            # * or copied by former run of "combineovals.py" script from
            #   shared/ directory into build/ subdirectory
            refovalfilename = check.text
            refovalfilefound = False
            for dirpath, dirnames, filenames in os.walk(os.curdir, topdown=True):
                # Case when referenced OVAL file exists
                for location in fnmatch.filter(filenames, refovalfilename + '.xml'):
                    refovalfilefound = True
                    break                     # break from the inner for loop

                if refovalfilefound:
                    break                     # break from the outer for loop

            shared_dir = os.getenv("SHARED")
            if shared_dir is not None:
                for dirpath, dirnames, filenames in os.walk(shared_dir, topdown=True):
                    # Case when referenced OVAL file exists
                    for location in fnmatch.filter(filenames, refovalfilename + '.xml'):
                        refovalfilefound = True
                        break                     # break from the inner for loop

                    if refovalfilefound:
                        break                     # break from the outer for loop

            # Referenced OVAL doesn't exist in the subdirtree below CWD:
            # * there's either typo in the refenced OVAL filename, or
            # * is has been forgotten to be placed into input/oval, or
            # * the <platform> tag of particular shared/ OVAL wasn't modified
            #   to include the necessary referenced file.
            # Therefore display an error and exit with failure in such cases
            if not refovalfilefound:
                error_msg = "\n\tError: Can't locate \"%s\" OVAL file in the \
                \n\tlist of OVAL checks for this product! Exiting..\n" % refovalfilename
                sys.stderr.write(error_msg)
                # sys.exit(1)
        check.set("href", os.path.basename(newovalfile))

        # Sanity check to verify if inventory check OVAL id is present in the
        # list of known "id" attributes of inventory definitions. If not it
        # means provided ovalfile (sys.argv[1]) doesn't contain this OVAL
        # definition (it wasn't included due to <platform> tag restrictions)
        # Therefore display an error and exit with failure, since otherwise
        # we might end up creating invalid $(ID)-$(PROD)-cpe-oval.xml file
        if check.text not in inventory_defs_id_attrs:
            error_msg = "\n\tError: Can't locate \"%s\" definition in \"%s\". \
            \n\tEnsure <platform> element is configured properly for \"%s\".  \
            \n\tExiting..\n" % (check.text, ovalfile, check.text)
            sys.stderr.write(error_msg)
            # sys.exit(1)

        # Referenced OVAL checks passed both of the above sanity tests
        check.text = translator.generate_id("{" + oval_ns + "}definition", check.text)

    ET.ElementTree(cpedicttree).write("./output/"+newcpedictfile)

    sys.exit(0)
Ejemplo n.º 11
0
def main():
    if len(sys.argv) < 2:
        print "Provide an OVAL file that contains inventory definitions."
        print ("This script extracts these definitions and writes them" +
               " to STDOUT.")
        sys.exit(1)

    ovalfile = sys.argv[1]
    cpedictfile = sys.argv[2]
    idname = sys.argv[3]

    # parse oval file
    ovaltree = parse_xml_file(ovalfile)

# extract inventory definitions
# making (dubious) assumption that all inventory defs are CPE
    defs = ovaltree.find("./{%s}definitions" % oval_ns)
    inventory_defs = defs.findall(".//{%s}definition[@class='inventory']"
                                  % oval_ns)
    # Keep the list of 'id' attributes from untranslated inventory def elements
    inventory_defs_id_attrs = []

    defs.clear()
    [defs.append(inventory_def) for inventory_def in inventory_defs]
    # Fill in that list
    [inventory_defs_id_attrs.append(inventory_def.get("id")) for \
    inventory_def in inventory_defs]

    tests = ovaltree.find("./{%s}tests" % oval_ns)
    cpe_tests = extract_referred_nodes(defs, tests, "test_ref")
    tests.clear()
    [tests.append(cpe_test) for cpe_test in cpe_tests]

    states = ovaltree.find("./{%s}states" % oval_ns)
    cpe_states = extract_referred_nodes(tests, states, "state_ref")
    states.clear()
    [states.append(cpe_state) for cpe_state in cpe_states]

    objects = ovaltree.find("./{%s}objects" % oval_ns)
    cpe_objects = extract_referred_nodes(tests, objects, "object_ref")
    env_objects = extract_referred_nodes(objects, objects, "id")
    objects.clear()
    [objects.append(cpe_object) for cpe_object in cpe_objects]

    # if any subelements in an object contain var_ref, return it here
    local_var_ref = extract_subelement(objects, 'var_ref')

    variables = ovaltree.find("./{%s}variables" % oval_ns)
    if variables is not None:
        cpe_variables = extract_referred_nodes(tests, variables, "var_ref")
        local_variables = extract_referred_nodes(variables, variables, "id")
        if cpe_variables:
            variables.clear()
            [variables.append(cpe_variable) for cpe_variable in cpe_variables]
        elif local_var_ref:
            for local_var in local_variables:
                if local_var.get('id') == local_var_ref:
                    variables.clear()
                    variables.append(local_var)
                    env_obj = extract_env_obj(env_objects, local_var)
                    objects.append(env_obj)
        else:
            ovaltree.remove(variables)

    # turn IDs into meaningless numbers
    translator = idtranslate.idtranslator(idname)
    ovaltree = translator.translate(ovaltree)

    newovalfile = ovalfile.replace("oval", "cpe-oval")
    newovalfile = newovalfile.replace("unlinked", idname)
    ET.ElementTree(ovaltree).write(newovalfile)

    # replace and sync IDs, href filenames in input cpe dictionary file
    cpedicttree = parse_xml_file(cpedictfile)
    newcpedictfile = idname + "-" + os.path.basename(cpedictfile)
    for check in cpedicttree.findall(".//{%s}check" % cpe_ns):
        checkhref = check.get("href")
        # If CPE OVAL references another OVAL file
        if checkhref == 'filename':
            # Sanity check -- Verify the referenced OVAL is truly defined
            # somewhere in the (sub)directory tree below CWD. In correct
            # scenario is should be located:
            # * either in input/oval/*.xml
            # * or copied by former run of "combineovals.py" script from
            #   shared/ directory into build/ subdirectory
            refovalfilename = check.text
            refovalfilefound = False
            for dirpath, dirnames, filenames in os.walk(os.curdir, topdown=True):
                # Case when referenced OVAL file exists
                for location in fnmatch.filter(filenames, refovalfilename + '.xml'):
                    refovalfilefound = True
                    break                     # break from the inner for loop

                if refovalfilefound:
                    break                     # break from the outer for loop

            # Referenced OVAL doesn't exist in the subdirtree below CWD:
            # * there's either typo in the refenced OVAL filename, or
            # * is has been forgotten to be placed into input/oval, or
            # * the <platform> tag of particular shared/ OVAL wasn't modified
            #   to include the necessary referenced file.
            # Therefore display an error and exit with failure in such cases
            if not refovalfilefound:
                error_msg = "\n\tError: Can't locate \"%s\" OVAL file in the \
                \n\tlist of OVAL checks for this product! Exiting..\n" % refovalfilename
                sys.stderr.write(error_msg)
                # sys.exit(1)
        check.set("href", os.path.basename(newovalfile))

        # Sanity check to verify if inventory check OVAL id is present in the
        # list of known "id" attributes of inventory definitions. If not it
        # means provided ovalfile (sys.argv[1]) doesn't contain this OVAL
        # definition (it wasn't included due to <platform> tag restrictions)
        # Therefore display an error and exit with failure, since otherwise
        # we might end up creating invalid $(ID)-$(PROD)-cpe-oval.xml file
        if check.text not in inventory_defs_id_attrs:
            error_msg = "\n\tError: Can't locate \"%s\" definition in \"%s\". \
            \n\tEnsure <platform> element is configured properly for \"%s\".  \
            \n\tExiting..\n" % (check.text, ovalfile, check.text)
            sys.stderr.write(error_msg)
            # sys.exit(1)

        # Referenced OVAL checks passed both of the above sanity tests
        check.text = translator.generate_id("{" + oval_ns + "}definition", check.text)

    ET.ElementTree(cpedicttree).write("./output/"+newcpedictfile)

    sys.exit(0)
Ejemplo n.º 12
0
def main():
    if len(sys.argv) < 3:
        print "Provide an XCCDF file and an ID name scheme."
        print ("This script finds check-content files (currently, OVAL " +
               "and OCIL) referenced from XCCDF and synchronizes all IDs.")
        sys.exit(1)

    xccdffile = sys.argv[1]
    idname = sys.argv[2]

    os.chdir("./output")
    # Step over xccdf file, and find referenced check files
    xccdftree = parse_xml_file(xccdffile)

    # Create XCCDF rule ID to assigned CCE ID mapping
    xccdf_to_cce_id_mapping = create_xccdf_id_to_cce_id_mapping(xccdftree)

    # Check that OVAL IDs and XCCDF Rule IDs match
    if 'unlinked-ocilref' not in xccdffile:
        allrules = xccdftree.findall(".//{%s}Rule" % xccdf_ns)
        for rule in allrules:
            xccdf_rule = rule.get("id")
            if xccdf_rule is not None:
                checks = rule.find("./{%s}check" % xccdf_ns)
                if checks is not None:
                    for check in checks:
                        check_name = check.get("name")
                        # Verify match of XCCDF vs OVAL / OCIL IDs for
                        # * the case of OVAL <check>
                        # * the case of OCIL <check>
                        if (not xccdf_rule == check_name and check_name is not None \
                            and not xccdf_rule + '_ocil' == check_name \
                            and not xccdf_rule == 'sample_rule'):
                            print("The OVAL / OCIL ID does not match the XCCDF Rule ID!\n")
                            if '_ocil' in check_name:
                                print("\n  OCIL ID:       \'%s\'" % check_name)
                            else:
                                print("\n  OVAL ID:       \'%s\'" % check_name)
                            print("\n  XCCDF Rule ID: \'%s\'"
                                  "\n\nBoth OVAL and XCCDF Rule IDs must match!" % xccdf_rule)
                            sys.exit(1)

    checks = xccdftree.findall(".//{%s}check" % xccdf_ns)
    ovalfiles = get_checkfiles(checks, oval_cs)
    ocilfiles = get_checkfiles(checks, ocil_cs)

    if len(ovalfiles) > 1 or len(ocilfiles) > 1:
        sys.exit("referencing more than one file per check system " +
                 "is not yet supported by this script.")
    ovalfile = ovalfiles.pop() if ovalfiles else None
    ocilfile = ocilfiles.pop() if ocilfiles else None

    translator = idtranslate.idtranslator(idname)

    # Rename all IDs in the oval file
    if ovalfile:
        ovaltree = parse_xml_file(ovalfile)

        # Add new <reference source="CCE" ref_id="CCE-ID" /> element to those OVAL
        # checks having CCE ID already assigned in XCCDF for particular rule.
        # But add the <reference> only in the case CCE is in valid form!
        # Exit with failure if the assignment wasn't successful
        # Fixes: https://github.com/OpenSCAP/scap-security-guide/issues/1092
        # Fixes: https://github.com/OpenSCAP/scap-security-guide/issues/1230
        # Fixes: https://github.com/OpenSCAP/scap-security-guide/issues/1229
        # Fixes: https://github.com/OpenSCAP/scap-security-guide/issues/1228
        add_cce_id_refs_to_oval_checks(ovaltree, xccdf_to_cce_id_mapping)

        # Verify all by XCCDF referenced (local) OVAL checks are defined in OVAL file
        # If not drop the <check-content> OVAL checksystem reference from XCCDF
        # Fixes: https://github.com/OpenSCAP/scap-security-guide/issues/1092
        # Fixes: https://github.com/OpenSCAP/scap-security-guide/issues/1095
        # Fixes: https://github.com/OpenSCAP/scap-security-guide/issues/1098
        ensure_by_xccdf_referenced_oval_def_is_defined_in_oval_file(xccdftree, ovaltree)

        # Verify the XCCDF to OVAL datatype export matching constraints
        # Fixes: https://github.com/OpenSCAP/scap-security-guide/issues/1089
        check_and_correct_xccdf_to_oval_data_export_matching_constraints(xccdftree, ovaltree)

        # Verify if CCE identifiers present in the XCCDF follow the required form
        # (either CCE-XXXX-X, or CCE-XXXXX-X). Drop from XCCDF those who don't follow it
        verify_correct_form_of_referenced_cce_identifiers(xccdftree)

        ovaltree = translator.translate(ovaltree, store_defname=True)
        newovalfile = ovalfile.replace("unlinked", idname)
        ET.ElementTree(ovaltree).write(newovalfile)

    # Rename all IDs in the ocil file
    if ocilfile:
        ociltree = parse_xml_file(ocilfile)
        ociltree = translator.translate(ociltree)
        newocilfile = ocilfile.replace("unlinked", idname)
        ET.ElementTree(ociltree).write(newocilfile)

    # Rename all IDs and file refs in the xccdf file
    for check in checks:
        checkcontentref = check.find("./{%s}check-content-ref" % xccdf_ns)

        # Don't attempt to relabel ID on empty <check-content-ref> element
        if checkcontentref is None:
            continue
        # Obtain the value of the 'href' attribute of particular
        # <check-content-ref> element
        checkcontentref_hrefattr = checkcontentref.get("href")

        # Don't attempt to relabel ID on <check-content-ref> element having
        # its "href" attribute set either to "http://" or to "https://" values
        if checkcontentref_hrefattr.startswith("http://") or \
           checkcontentref_hrefattr.startswith("https://"):
            continue

        if check.get("system") == oval_cs:
            checkid = translator.generate_id("{" + oval_ns + "}definition",
                                             checkcontentref.get("name"))
            checkcontentref.set("name", checkid)
            checkcontentref.set("href", newovalfile)
            checkexport = check.find("./{%s}check-export" % xccdf_ns)
            if checkexport is not None:
                newexportname = translator.generate_id("{" + oval_ns + "}variable",
                                                       checkexport.get("export-name"))
                checkexport.set("export-name", newexportname)

        if check.get("system") == ocil_cs:
            checkid = translator.generate_id("{" + ocil_ns + "}questionnaire",
                                             checkcontentref.get("name"))
            checkcontentref.set("name", checkid)
            checkcontentref.set("href", newocilfile)
            checkexport = check.find("./{%s}check-export" % xccdf_ns)
            if checkexport is not None:
                newexportname = translator.generate_id("{" + oval_ns + "}variable",
                                                       checkexport.get("export-name"))
                checkexport.set("export-name", newexportname)

    newxccdffile = xccdffile.replace("unlinked", idname)
    # ET.dump(xccdftree)
    ET.ElementTree(xccdftree).write(newxccdffile)
    sys.exit(0)
def main():
    if len(sys.argv) < 3:
        print "Provide an XCCDF file and an ID name scheme."
        print("This script finds check-content files (currently, OVAL " +
              "and OCIL) referenced from XCCDF and synchronizes all IDs.")
        sys.exit(1)

    xccdffile = sys.argv[1]
    idname = sys.argv[2]

    os.chdir("./output")
    # step over xccdf file, and find referenced check files
    xccdftree = parse_xml_file(xccdffile)

    checks = xccdftree.findall(".//{%s}check" % xccdf_ns)
    ovalfiles = get_checkfiles(checks, oval_cs)
    ocilfiles = get_checkfiles(checks, ocil_cs)

    if len(ovalfiles) > 1 or len(ocilfiles) > 1:
        sys.exit("referencing more than one file per check system " +
                 "is not yet supported by this script.")
    ovalfile = ovalfiles.pop() if ovalfiles else None
    ocilfile = ocilfiles.pop() if ocilfiles else None

    translator = idtranslate.idtranslator(idname + ".ini", idname)

    # rename all IDs in the oval file
    if ovalfile:
        ovaltree = parse_xml_file(ovalfile)
        ovaltree = translator.translate(ovaltree, store_defname=True)
        newovalfile = ovalfile.replace("unlinked", idname)
        ET.ElementTree(ovaltree).write(newovalfile)

    # rename all IDs in the ocil file
    if ocilfile:
        ociltree = parse_xml_file(ocilfile)
        ociltree = translator.translate(ociltree)
        newocilfile = ocilfile.replace("unlinked", idname)
        ET.ElementTree(ociltree).write(newocilfile)

    # rename all IDs and file refs in the xccdf file
    for check in checks:
        checkcontentref = check.find("./{%s}check-content-ref" % xccdf_ns)
        if checkcontentref is None:
            continue

        if check.get("system") == oval_cs:
            checkid = translator.assign_id("{" + oval_ns + "}definition",
                                           checkcontentref.get("name"))
            checkcontentref.set("name", checkid)
            checkcontentref.set("href", newovalfile)
            checkexport = check.find("./{%s}check-export" % xccdf_ns)
            if checkexport is not None:
                newexportname = translator.assign_id(
                    "{" + oval_ns + "}variable",
                    checkexport.get("export-name"))
                checkexport.set("export-name", newexportname)

        if check.get("system") == ocil_cs:
            checkid = translator.assign_id("{" + ocil_ns + "}questionnaire",
                                           checkcontentref.get("name"))
            checkcontentref.set("name", checkid)
            checkcontentref.set("href", newocilfile)
            checkexport = check.find("./{%s}check-export" % xccdf_ns)
            if checkexport is not None:
                newexportname = translator.assign_id(
                    "{" + oval_ns + "}variable",
                    checkexport.get("export-name"))
                checkexport.set("export-name", newexportname)

    newxccdffile = xccdffile.replace("unlinked", idname)
    # ET.dump(xccdftree)
    ET.ElementTree(xccdftree).write(newxccdffile)
    sys.exit(0)