The python bindings finally got fixed upstream and we can audit again.
Also fixed an issue when combining definition models where it would only
clone the definition, and not the tests, states, or objects that the
definition referenced.
---
src/secstate/main.py | 79 +++++++++++++++++++++++++-------
src/secstate/util.py | 123 ++++++++++++++++++++++---------------------------
2 files changed, 116 insertions(+), 86 deletions(-)
diff --git a/src/secstate/main.py b/src/secstate/main.py
index 3ef48eb..1a5b6f4 100644
--- a/src/secstate/main.py
+++ b/src/secstate/main.py
@@ -94,6 +94,65 @@ class Secstate:
else:
return {}
+ def combine_def_models(self, target, source):
+ """
+ Function: Add all the definitions from the source model to the target model
+ Input: Two oval_definition_model's
+ Output: Success or failure of combination
+ """
+ definitions = oscap.oval_definition_model_get_definitions(source)
+ for defn in oval_definition_generator(definitions):
+ if oscap.oval_definition_model_get_definition(target,
oscap.oval_definition_get_id(defn)) == None:
+ new_def = oscap.oval_definition_clone(target, defn)
+ if new_def == None:
+ self.log.error("Error adding definition %(name)s to target
model" % {'name':oscap.oval_definition_get_id(defn)})
+ return False
+ else:
+ self.log.debug("Succesfully added %(name)s to target model"
% {'name':oscap.oval_definition_get_id(defn)})
+
+ tests = oscap.oval_definition_model_get_tests(source)
+ for defn in oval_test_generator(tests):
+ print oscap.oval_test_get_id(defn)
+ if oscap.oval_definition_model_get_test(target, oscap.oval_test_get_id(defn))
== None:
+ new_def = oscap.oval_test_clone(target, defn)
+ if new_def == None:
+ self.log.error("Error adding test %(name)s to target model"
% {'name':oscap.oval_test_get_id(defn)})
+ return False
+ else:
+ self.log.debug("Succesfully added %(name)s to target model"
% {'name':oscap.oval_test_get_id(defn)})
+
+ objects = oscap.oval_definition_model_get_objects(source)
+ for defn in oval_object_generator(objects):
+ if oscap.oval_definition_model_get_object(target,
oscap.oval_object_get_id(defn)) == None:
+ new_def = oscap.oval_object_clone(target, defn)
+ if new_def == None:
+ self.log.error("Error adding object %(name)s to target
model" % {'name':oscap.oval_object_get_id(defn)})
+ return False
+ else:
+ self.log.debug("Succesfully added %(name)s to target model"
% {'name':oscap.oval_object_get_id(defn)})
+
+ states = oscap.oval_definition_model_get_states(source)
+ for defn in oval_state_generator(states):
+ if oscap.oval_definition_model_get_state(target,
oscap.oval_state_get_id(defn)) == None:
+ new_def = oscap.oval_state_clone(target, defn)
+ if new_def == None:
+ self.log.error("Error adding state %(name)s to target
model" % {'name':oscap.oval_state_get_id(defn)})
+ return False
+ else:
+ self.log.debug("Succesfully added %(name)s to target model"
% {'name':oscap.oval_state_get_id(defn)})
+
+ variables = oscap.oval_definition_model_get_variables(source)
+ for defn in oval_variable_generator(variables):
+ if oscap.oval_definition_model_get_variable(target,
oscap.oval_variable_get_id(defn)) == None:
+ new_def = oscap.oval_variable_clone(target, defn)
+ if new_def == None:
+ self.log.error("Error adding variable %(name)s to target
model" % {'name':oscap.oval_variable_get_id(defn)})
+ return False
+ else:
+ self.log.debug("Succesfully added %(name)s to target model"
% {'name':oscap.oval_variable_get_id(defn)})
+
+ return True
+
def import_benchmark(self, benchmark_file, oval_path="", store_path=None):
"""
Function: Imports an XCCDF benchmark
@@ -394,23 +453,6 @@ class Secstate:
oscap.xccdf_benchmark_free(benchmark)
return True
- def combine_def_models(self, target, source):
- """
- Function: Add all the definitions from the source model to the target model
- Input: Two oval_definition_model's
- Output: Success or failure of combination
- """
- definitions = oscap.oval_definition_model_get_definitions(source)
- for defn in oval_definition_generator(definitions):
- if oscap.oval_definition_model_get_definition(target,
oscap.oval_definition_get_id(defn)) == None:
- new_def = oscap.oval_definition_clone(target, defn)
- if new_def == None:
- self.log.error("Error adding definition %(name)s to target
model" % {'name':oscap.oval_definition_get_id(defn)})
- return False
- else:
- self.log.debug("Succesfully added %(name)s to target model"
% {'name':oscap.oval_definition_get_id(defn)})
- return True
-
def audit(self, interpreter, args, oval_only, def_models=None, verbose=False,
xml=None, html=None):
"""
Function: Run an audit on the system agains the given definition model
@@ -448,9 +490,10 @@ class Secstate:
self.log.error("Error importing benchmark: %(bench)s" %
{'bench':arg})
return False
+
if interpreter == "openscap":
sess = oscap.oval_agent_new_session(def_model)
- return evaluate_xccdf(benchmark, def_model, benchmark_path, sess,
f_xml=xml, f_html=html)
+ return evaluate_xccdf(benchmark, def_model, arg, sess, f_xml=xml,
f_html=html)
def search(self, search_string, verbose=False):
"""
diff --git a/src/secstate/util.py b/src/secstate/util.py
index 3b27a79..c9784ce 100644
--- a/src/secstate/util.py
+++ b/src/secstate/util.py
@@ -60,7 +60,7 @@ xccdf_generator_list_types = ['xccdf_item',
'xccdf_notice', 'xccdf_status', 'xcc
'xccdf_fixtext', 'xccdf_check_content_ref',
'xccdf_check_import',
'xccdf_fix', 'xccdf_check_export',
'xccdf_warning', 'xccdf_instance',
'xccdf_message', 'xccdf_override',
'xccdf_rule_result', 'xccdf_score',
- 'xccdf_target_fact', 'xccdf_plain_text']
+ 'xccdf_target_fact', 'xccdf_plain_text',
'xccdf_model']
for type in xccdf_generator_list_types:
gen_func, list_func = iterator_to_generator_and_list('%s_iterator' % type)
@@ -177,6 +177,10 @@ def xccdf_callback(model, rule_id, id, bindings, usr):
return True
+def callback(id, result, arg):
+ print "Rule '%(id)s' result: %(res)s" % {'id':id,
'res':oscap.xccdf_test_result_type_get_text(result)}
+ return 0
+
def evaluate_xccdf(benchmark, def_model, url_XCCDF, sess, s_profile=None, f_xml=None,
f_html=None):
policy = None
policy_model = oscap.xccdf_policy_model_new(benchmark)
@@ -193,49 +197,53 @@ def evaluate_xccdf(benchmark, def_model, url_XCCDF, sess,
s_profile=None, f_xml=
sys.stderr.write("No policy to evaluate.\n")
return -1
- usr = { 'result_id':"secstate_audit-test",
- 'asess':sess }
+ usr = oscap.oval_agent_cb_data_new()
+ oscap.oval_agent_cb_data_set_session(usr, sess)
+ oscap.oval_agent_cb_data_set_callback_py(usr, None, None)
+ oscap.oval_agent_cb_data_set_usr(usr, policy_model)
+
+ oscap.xccdf_policy_model_register_output_callback_py(policy_model, callback, None)
+ oscap.xccdf_policy_model_register_callback_py(policy_model,
"http://oval.mitre.org/XMLSchema/oval-definitions-5",
+ oscap.oval_agent_eval_rule_py, usr)
- ritem = oscap.xccdf_result_new()
- oscap.xccdf_result_set_id(ritem, usr['result_id'])
+ ritem = oscap.xccdf_policy_evaluate(policy)
oscap.xccdf_result_set_benchmark_uri(ritem, url_XCCDF)
title = oscap.oscap_text_new()
oscap.oscap_text_set_text(title, "Secstate Audit Result")
oscap.xccdf_result_add_title(ritem, title)
oscap.xccdf_result_set_start_time(ritem, time.time())
- oscap.xccdf_policy_model_add_result(policy_model, ritem)
+ if policy != None:
+ id = oscap.xccdf_profile_get_id(oscap.xccdf_policy_get_profile(policy))
+ if id != None:
+ oscap.xccdf_result_set_profile(ritem, id)
+ oscap.oval_agent_export_sysinfo_to_xccdf_result(sess, ritem)
+
+ models = oscap.xccdf_benchmark_get_models(benchmark)
+ for model in xccdf_model_generator(models):
+ score = oscap.xccdf_policy_get_score(policy, ritem,
oscap.xccdf_model_get_system(model))
+ oscap.xccdf_result_add_score(ritem, score)
- oscap.xccdf_policy_model_register_callback_py(policy_model,
"http://oval.mitre.org/XMLSchema/oval-definitions-5",
- xccdf_callback, usr)
-
- oscap.xccdf_policy_evaluate(policy)
-
- res_model = oscap.oval_agent_get_results_model(usr['asess'])
- res_system =
oscap.oval_result_system_iterator_next(oscap.oval_results_model_get_systems(res_model))
- sys_model = oscap.oval_result_system_get_syschar_model(res_system)
- sysinfo = oscap.oval_syschar_model_get_sysinfo(sys_model)
-
- oscap.xccdf_result_set_test_system(ritem,
oscap.oval_sysinfo_get_primary_host_name(sysinfo))
- if (policy != None):
- profile = oscap.xccdf_policy_get_profile(policy)
- if oscap.xccdf_profile_get_id(profile) != None:
- oscap.xccdf_result_set_profile(ritem, oscap.xccdf_profile_get_id(profile))
-
- sysint_it = oscap.oval_sysinfo_get_interfaces(sysinfo)
- for sysint in oval_sysint_generator(sysint_it):
- oscap.xccdf_result_add_target_address(ritem,
oscap.oval_sysint_get_ip_address(sysint))
- if oscap.oval_sysint_get_mac_address(sysint) != None:
- fact = oscap.xccdf_target_fact_new()
- oscap.xccdf_target_fact_set_name(fact,
"urn:xccdf:fact:ethernet:MAC")
- oscap.xccdf_target_fact_set_string(fact,
oscap.oval_sysint_get_mac_address(sysint))
-
oscap.xccdf_result_set_end_time(ritem, time.time())
- if f_xml != None:
- oscap.xccdf_result_export(ritem, f_xml)
+ #if f_xml != None:
+ # oscap.xccdf_result_export(ritem, f_xml)
+
+ oscap.oval_agent_cb_data_free(usr)
+ oscap.xccdf_policy_model_free(policy_model)
+ return 0
+
+def oval_callback(id, result, usr):
+ if result == oscap.OVAL_RESULT_TRUE:
+ usr['True'] += 1
+ elif result == oscap.OVAL_RESULT_FALSE:
+ usr['False'] += 1
+ elif result == oscap.OVAL_RESULT_UNKNOWN:
+ usr['Unknown'] += 1
+ elif result == oscap.OVAL_RESULT_NOT_EVALUATED:
+ usr['Not Evaluated'] += 1
+ elif result == oscap.OVAL_RESULT_NOT_APPLICABLE:
+ usr['Not Applicable'] += 1
- oscap.oval_agent_destroy_session(usr['asess'])
- #oscap.xccdf_policy_model_free(policy_model)
return 0
def output_oval_results(res_model, res_directives, xml, html):
@@ -270,34 +278,16 @@ def output_oval_results(res_model, res_directives, xml, html):
return True
-def oval_callback(id, result, usr):
- if usr['verbose']:
- print "Evaluated definition %(id)s: %(res)s" % {'id':id,
'res':oscap.oval_result_get_text(result)}
+def evaluate_oval(def_model, sess, f_xml, f_html, verbose=True):
+ res_model = oscap.oval_agent_get_results_model(sess)
- if result == oscap.OVAL_RESULT_TRUE:
- usr['true'] += 1
- elif result == oscap.OVAL_RESULT_FALSE:
- usr['false'] += 1
- if result == oscap.OVAL_RESULT_INVALID:
- usr['invalid'] += 1
- if result == oscap.OVAL_RESULT_UNKNOWN:
- usr['unknown'] += 1
- if result == oscap.OVAL_RESULT_NOT_EVALUATED:
- usr['neval'] += 1
- if result == oscap.OVAL_RESULT_NOT_APPLICABLE:
- usr['napp'] += 1
+ usr = {'False':0,
+ 'True':0,
+ 'Invalid':0,
+ 'Unknown':0,
+ 'Not Evaluated':0,
+ 'Not Applicable':0}
- return 0
-
-def evaluate_oval(def_model, sess, f_xml, f_html, verbose=False):
- res_model = oscap.oval_agent_get_results_model(sess)
- usr = {'verbose':verbose,
- 'true':0,
- 'false':0,
- 'invalid':0,
- 'unknown':0,
- 'neval':0,
- 'napp':0}
ret = oscap.oval_agent_eval_system_py(sess, oval_callback, usr)
if verbose:
@@ -309,14 +299,11 @@ def evaluate_oval(def_model, sess, f_xml, f_html, verbose=False):
'desc':oscap.oscap_err_desc()})
return False
- print "Results:"
- print "True:\t%d" % usr['true']
- print "False:\t%d" % usr['false']
- print "Invalid:\t%d" % usr['invalid']
- print "Unknown:\t%d" % usr['unknown']
- print "Not Evaluated:\t%d" % usr['neval']
- print "Not Applicable:\t%d" % usr['napp']
-
+ if verbose:
+ print "Results:"
+ for key,val in usr.items():
+ print "%(key)s:\t\t%(val)d" % {'key':key,
'val':val}
+
if f_xml or f_html:
res_direct = oscap.oval_result_directives_new(res_model)
oscap.oval_result_directives_set_reported(res_direct, oscap.OVAL_RESULT_INVALID
|
--
1.7.0.1