Esempio n. 1
0
def append(element, newchild):
    """Append new child ONLY if it's not a duplicate"""

    global element_child_cache

    newid = newchild.get("id")
    existing = element_child_cache[element].get(newid, None)

    if existing is not None:
        # ID is identical and OVAL entities are identical
        if oval_entities_are_identical(existing, newchild):
            # Moreover the entity is OVAL <external_variable>
            if oval_entity_is_extvar(newchild):
                # If OVAL entity is identical to some already included
                # in the benchmark and represents an OVAL <external_variable>
                # it's safe to ignore this ID (since external variables are
                # in multiple checks just to notify 'testoval.py' helper to
                # substitute the ID with <local_variable> entity when testing
                # the OVAL for the rule)
                pass
            # Some other OVAL entity
            else:
                # If OVAL entity is identical, but not external_variable, the
                # implementation should be rewritten each entity to be present
                # just once
                sys.stderr.write("ERROR: OVAL ID '%s' is used multiple times "
                                 "and should represent the same elements.\n"
                                 % (newid))
                sys.stderr.write("Rewrite the OVAL checks. Place the identical "
                                 "IDs into their own definition and extend "
                                 "this definition by it.\n")
                sys.exit(1)
        # ID is identical, but OVAL entities are semantically difference =>
        # report and error and exit with failure
        # Fixes: https://github.com/OpenSCAP/scap-security-guide/issues/1275
        else:
            if not oval_entity_is_extvar(existing) and \
              not oval_entity_is_extvar(newchild):
                # This is an error scenario - since by skipping second
                # implementation and using the first one for both references,
                # we might evaluate wrong requirement for the second entity
                # => report an error and exit with failure in that case
                # See
                #   https://github.com/OpenSCAP/scap-security-guide/issues/1275
                # for a reproducer and what could happen in this case
                sys.stderr.write("ERROR: it's not possible to use the " +
                                 "same ID: %s " % newid + "for two " +
                                 "semantically different OVAL entities:\n")
                sys.stderr.write("First entity  %s\n" % ElementTree.tostring(existing))
                sys.stderr.write("Second entity %s\n" % ElementTree.tostring(newchild))
                sys.stderr.write("Use different ID for the second entity!!!\n")
                sys.exit(1)
    else:
        element.append(newchild)
        element_child_cache[element][newid] = newchild
Esempio n. 2
0
def main():
    global definitions
    global tests
    global objects
    global states
    global variables
    global silent_mode

    args = parse_options()
    silent_mode = args.silent_mode
    oval_version = args.oval_version

    testfile = args.xmlfile
    header = oval_generated_header("testoval.py", oval_version, "0.0.1")
    testfile = find_testfile(testfile)
    body = read_ovaldefgroup_file(testfile)
    defname = _add_elements(body, header)
    if defname is None:
        print("Error while evaluating oval: defname not set; missing "
              "definitions section?")
        sys.exit(1)

    ovaltree = ET.fromstring(header + footer)

    # append each major element type, if it has subelements
    for element in [definitions, tests, objects, states, variables]:
        if list(element) > 0:
            ovaltree.append(element)
    # re-map all the element ids from meaningful names to meaningless
    # numbers
    testtranslator = IDTranslator("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)
    if not silent_mode:
        print("Evaluating with OVAL tempfile: " + fname)
        print("OVAL Schema Version: %s" % oval_version)
        print("Writing results to: " + fname + "-results")
    cmd = "oscap oval eval --results " + fname + "-results " + fname
    oscap_child = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
    cmd_out = oscap_child.communicate()[0]
    if not silent_mode:
        print(cmd_out)
    if oscap_child.returncode != 0:
        if not silent_mode:
            print("Error launching 'oscap' command: \n\t" + cmd)
        sys.exit(2)
    if 'false' in cmd_out:
        # at least one from the evaluated OVAL definitions evaluated to
        # 'false' result, exit with '1' to indicate OVAL scan FAIL result
        sys.exit(1)
    # perhaps delete tempfile?
    definitions = ET.Element("definitions")
    tests = ET.Element("tests")
    objects = ET.Element("objects")
    states = ET.Element("states")
    variables = ET.Element("variables")

    # 'false' keyword wasn't found in oscap's command output
    # exit with '0' to indicate OVAL scan TRUE result
    sys.exit(0)