def process_xccdf_group(xccdf, xccdf_path, outdir, rule_profiles, group_path, drop_id_prefix): # Process all of the rules here. rules = [] for rule in xccdf.findall("{http://checklists.nist.gov/xccdf/1.2}Rule"): rules.append(process_rule(rule, rule_profiles, xccdf_path, group_path, outdir, drop_id_prefix)) # Process all of the groups here groups = [] for group in xccdf.findall("{http://checklists.nist.gov/xccdf/1.2}Group"): # a nice directory name for the group g = group.get('id') g = re.sub('^xccdf_org\.(.*)\.content_group_(.*)$', r'\1_\2', g) if drop_id_prefix and g.startswith(drop_id_prefix): g = g[len(drop_id_prefix):] child_drop_id_prefix = drop_id_prefix elif "_" in g: child_drop_id_prefix = g.split("_")[0] + "_" else: child_drop_id_prefix = None groups.append(g) process_xccdf_group(group, xccdf_path, outdir, rule_profiles, group_path + [g], child_drop_id_prefix) groupdict = collections.OrderedDict([ ("id", xccdf.get("id")), ("title", xccdf.find("{http://checklists.nist.gov/xccdf/1.2}title").text), ("description", pandoc(xccdf.find("{http://checklists.nist.gov/xccdf/1.2}description"), 'html', 'markdown')), ("rules", rules), ("subgroups", groups), ]) fn = os.path.join(*([outdir] + group_path + ['group.yaml'])) os.makedirs(os.path.dirname(fn), exist_ok=True) with open(fn, "w") as f: rtyaml.dump(groupdict, f)
def process_rule(filename, oval_nodes): # A rule is metadata + zero or more tests. yaml = rtyaml.load(open(filename)) # Create the rule definition. oval_nodes["definition_count"] += 1 defnode = make_node(oval_nodes["definitions"], "definition", None, id="oval:easyscap_generated:def:%d" % oval_nodes["definition_count"], version="1") defnode.set("class", "compliance") defnodemeta = make_node(defnode, "metadata") make_node(defnodemeta, "title", yaml["title"]) affected = make_node(defnodemeta, "affected", family="unix") make_node(affected, "platform", "Unknown") make_node(defnodemeta, "description", pandoc(yaml["description"], "markdown", "html")) # should be inserted raw, not escaped defnodecriteria = None # Create OVAL definitions for the variables. var_map = {} try: for key, var in yaml.get("variables", {}).items(): node = dict_to_node(oval_nodes["variables"], var, oval_nodes=oval_nodes) varid = "oval:%s:var:%d" % (yaml["id"], key + 1) node.set("id", varid) var_map[key] = varid except Exception as e: raise Exception("Error processing rule %s: %s" % (filename, str(e))) # Create OVAL definitions for the tests. try: for i, test in enumerate(yaml.get("tests", [])): node = process_test(test, oval_nodes, yaml["id"], i, var_map) if defnodecriteria is None: defnodecriteria = make_node(defnode, "criteria", None, operator=yaml["operator"]) make_node(defnodecriteria, "criterion", test_ref=node.get('id')) except Exception as e: raise Exception("Error processing rule %s: %s" % (filename, str(e)))
def process_rule(filename, oval_nodes): # A rule is metadata + zero or more tests. yaml = rtyaml.load(open(filename)) # Create the rule definition. oval_nodes["definition_count"] += 1 defnode = make_node( oval_nodes["definitions"], "definition", None, id="oval:easyscap_generated:def:%d" % oval_nodes["definition_count"], version="1", ) defnode.set("class", "compliance") defnodemeta = make_node(defnode, "metadata") make_node(defnodemeta, "title", yaml["title"]) affected = make_node(defnodemeta, "affected", family="unix") make_node(affected, "platform", "Unknown") make_node( defnodemeta, "description", pandoc(yaml["description"], "markdown", "html") ) # should be inserted raw, not escaped defnodecriteria = None # Create OVAL definitions for the variables. var_map = {} try: for key, var in yaml.get("variables", {}).items(): node = dict_to_node(oval_nodes["variables"], var, oval_nodes=oval_nodes) varid = "oval:%s:var:%d" % (yaml["id"], key + 1) node.set("id", varid) var_map[key] = varid except Exception as e: raise Exception("Error processing rule %s: %s" % (filename, str(e))) # Create OVAL definitions for the tests. try: for i, test in enumerate(yaml.get("tests", [])): node = process_test(test, oval_nodes, yaml["id"], i, var_map) if defnodecriteria is None: defnodecriteria = make_node(defnode, "criteria", None, operator=yaml["operator"]) make_node(defnodecriteria, "criterion", test_ref=node.get("id")) except Exception as e: raise Exception("Error processing rule %s: %s" % (filename, str(e)))
def process_xccdf_group(xccdf, xccdf_path, outdir, rule_profiles, group_path, drop_id_prefix): # Process all of the rules here. rules = [] for rule in xccdf.findall("{http://checklists.nist.gov/xccdf/1.2}Rule"): rules.append( process_rule(rule, rule_profiles, xccdf_path, group_path, outdir, drop_id_prefix)) # Process all of the groups here groups = [] for group in xccdf.findall("{http://checklists.nist.gov/xccdf/1.2}Group"): # a nice directory name for the group g = group.get('id') g = re.sub('^xccdf_org\.(.*)\.content_group_(.*)$', r'\1_\2', g) if drop_id_prefix and g.startswith(drop_id_prefix): g = g[len(drop_id_prefix):] child_drop_id_prefix = drop_id_prefix elif "_" in g: child_drop_id_prefix = g.split("_")[0] + "_" else: child_drop_id_prefix = None groups.append(g) process_xccdf_group(group, xccdf_path, outdir, rule_profiles, group_path + [g], child_drop_id_prefix) groupdict = collections.OrderedDict([ ("id", xccdf.get("id")), ("title", xccdf.find("{http://checklists.nist.gov/xccdf/1.2}title").text), ("description", pandoc( xccdf.find("{http://checklists.nist.gov/xccdf/1.2}description"), 'html', 'markdown')), ("rules", rules), ("subgroups", groups), ]) fn = os.path.join(*([outdir] + group_path + ['group.yaml'])) os.makedirs(os.path.dirname(fn), exist_ok=True) with open(fn, "w") as f: rtyaml.dump(groupdict, f)
def process_rule(rule, rule_profiles, xccdf_path, group_path, outdir, drop_id_prefix): # Turn an XCCDF Rule into a Python dict. ruledict = collections.OrderedDict([ ("id", rule.get("id")), ("severity", rule.get("severity")), ("title", rule.find("{http://checklists.nist.gov/xccdf/1.2}title").text), ("description", pandoc(rule.find("{http://checklists.nist.gov/xccdf/1.2}description"), 'html', 'markdown')), ("rationale", pandoc(rule.find("{http://checklists.nist.gov/xccdf/1.2}rationale"), 'html', 'markdown')), ("references", [node_to_dict(n) for n in rule if n.tag == "{http://checklists.nist.gov/xccdf/1.2}reference"]), ("crosswalk", [node_to_dict(n) for n in rule if n.tag == "{http://checklists.nist.gov/xccdf/1.2}ident"]), ]) ## Which profiles is this rule included in? # Let's move this to the group definitions to the extent that profiles # activate entire groups. # TODO: We'll move profiles into separate files. #if rule.get("id") in rule_profiles: # ruledict["profiles"] = sorted(rule_profiles[rule.get("id")]) # Collect variables from OVAL. variable_map = { } # The rule's test. test = rule.find("{http://checklists.nist.gov/xccdf/1.2}check[@system='http://oval.mitre.org/XMLSchema/oval-definitions-5']") if test is not None: ref = test.find("{http://checklists.nist.gov/xccdf/1.2}check-content-ref") if ref is not None: oval = load_oval_file(xccdf_path, ref.get("href")) ovalcontent = oval.find(".//*[@id='" + ref.get("name") + "']") if ovalcontent is not None: criteria = ovalcontent.find('{http://oval.mitre.org/XMLSchema/oval-definitions-5}criteria') if criteria is not None: ruledict["operator"] = criteria.get("operator", None) ruledict["tests"] = [] # TODO: There may be other nodes here besides criteria. for criterion in criteria.findall('{http://oval.mitre.org/XMLSchema/oval-definitions-5}criterion'): ovaltest = oval.find(".//*[@id='" + criterion.get("test_ref") + "']") testdict = node_to_dict(ovaltest, include_type=True, oval=oval, variable_map=variable_map) ruledict["tests"].append(testdict) # Add variable definitions. if len(variable_map) > 0: ruledict["variables"] = collections.OrderedDict() for old_id, new_id in sorted(variable_map.items()): ovalvar = oval.find(".//*[@id='" + old_id + "']") ruledict["variables"][new_id] = node_to_dict(ovalvar, include_type=True, oval=oval) # make a nice directory name for the rule r = rule.get('id') r = re.sub('^xccdf_org\.(.*)\.content_rule_(.*)$', r'\1_\2', r) if drop_id_prefix and r.startswith(drop_id_prefix): r = r[len(drop_id_prefix):] if r == "group": # name clash with group.yaml r += "_rule" fn = os.path.join(*([outdir] + group_path + [r + '.yaml'])) os.makedirs(os.path.dirname(fn), exist_ok=True) with open(fn, "w") as f: rtyaml.dump(ruledict, f) return r
def process_rule(rule, rule_profiles, xccdf_path, group_path, outdir, drop_id_prefix): # Turn an XCCDF Rule into a Python dict. ruledict = collections.OrderedDict([ ("id", rule.get("id")), ("severity", rule.get("severity")), ("title", rule.find("{http://checklists.nist.gov/xccdf/1.2}title").text), ("description", pandoc(rule.find("{http://checklists.nist.gov/xccdf/1.2}description"), 'html', 'markdown')), ("rationale", pandoc(rule.find("{http://checklists.nist.gov/xccdf/1.2}rationale"), 'html', 'markdown')), ("references", [ node_to_dict(n) for n in rule if n.tag == "{http://checklists.nist.gov/xccdf/1.2}reference" ]), ("crosswalk", [ node_to_dict(n) for n in rule if n.tag == "{http://checklists.nist.gov/xccdf/1.2}ident" ]), ]) ## Which profiles is this rule included in? # Let's move this to the group definitions to the extent that profiles # activate entire groups. # TODO: We'll move profiles into separate files. #if rule.get("id") in rule_profiles: # ruledict["profiles"] = sorted(rule_profiles[rule.get("id")]) # Collect variables from OVAL. variable_map = {} # The rule's test. test = rule.find( "{http://checklists.nist.gov/xccdf/1.2}check[@system='http://oval.mitre.org/XMLSchema/oval-definitions-5']" ) if test is not None: ref = test.find( "{http://checklists.nist.gov/xccdf/1.2}check-content-ref") if ref is not None: oval = load_oval_file(xccdf_path, ref.get("href")) ovalcontent = oval.find(".//*[@id='" + ref.get("name") + "']") if ovalcontent is not None: criteria = ovalcontent.find( '{http://oval.mitre.org/XMLSchema/oval-definitions-5}criteria' ) if criteria is not None: ruledict["operator"] = criteria.get("operator", None) ruledict["tests"] = [] # TODO: There may be other nodes here besides criteria. for criterion in criteria.findall( '{http://oval.mitre.org/XMLSchema/oval-definitions-5}criterion' ): ovaltest = oval.find(".//*[@id='" + criterion.get("test_ref") + "']") testdict = node_to_dict(ovaltest, include_type=True, oval=oval, variable_map=variable_map) ruledict["tests"].append(testdict) # Add variable definitions. if len(variable_map) > 0: ruledict["variables"] = collections.OrderedDict() for old_id, new_id in sorted(variable_map.items()): ovalvar = oval.find(".//*[@id='" + old_id + "']") ruledict["variables"][new_id] = node_to_dict(ovalvar, include_type=True, oval=oval) # make a nice directory name for the rule r = rule.get('id') r = re.sub('^xccdf_org\.(.*)\.content_rule_(.*)$', r'\1_\2', r) if drop_id_prefix and r.startswith(drop_id_prefix): r = r[len(drop_id_prefix):] if r == "group": # name clash with group.yaml r += "_rule" fn = os.path.join(*([outdir] + group_path + [r + '.yaml'])) os.makedirs(os.path.dirname(fn), exist_ok=True) with open(fn, "w") as f: rtyaml.dump(ruledict, f) return r