|
|
8b65ee |
From 84e2041d3b6d9a240ddab3f39c7baed8e718bfab Mon Sep 17 00:00:00 2001
|
|
|
8b65ee |
From: =?UTF-8?q?Jan=20=C4=8Cern=C3=BD?= <jcerny@redhat.com>
|
|
|
8b65ee |
Date: Tue, 20 Nov 2018 12:00:48 +0100
|
|
|
8b65ee |
Subject: [PATCH 1/4] Prevent duplicate variables in Ansible Playbooks
|
|
|
8b65ee |
|
|
|
8b65ee |
The same XCCDF value can appear in multiple rules, which means
|
|
|
8b65ee |
there can be same variable in multiple Ansible task. But when
|
|
|
8b65ee |
we generate a Playbook we should put the variable only once.
|
|
|
8b65ee |
Ansible produces a warning if there are multiple definitions
|
|
|
8b65ee |
of the same variable.
|
|
|
8b65ee |
---
|
|
|
8b65ee |
src/XCCDF_POLICY/xccdf_policy_remediate.c | 180 ++++++++++++----------
|
|
|
8b65ee |
1 file changed, 95 insertions(+), 85 deletions(-)
|
|
|
8b65ee |
|
|
|
8b65ee |
diff --git a/src/XCCDF_POLICY/xccdf_policy_remediate.c b/src/XCCDF_POLICY/xccdf_policy_remediate.c
|
|
|
8b65ee |
index 65544c7f74..6ac566225c 100644
|
|
|
8b65ee |
--- a/src/XCCDF_POLICY/xccdf_policy_remediate.c
|
|
|
8b65ee |
+++ b/src/XCCDF_POLICY/xccdf_policy_remediate.c
|
|
|
8b65ee |
@@ -134,11 +134,11 @@ static int _write_remediation_to_fd_and_free(int output_fd, const char* template
|
|
|
8b65ee |
free(text);
|
|
|
8b65ee |
return 1;
|
|
|
8b65ee |
}
|
|
|
8b65ee |
- }
|
|
|
8b65ee |
|
|
|
8b65ee |
- if (_write_text_to_fd(output_fd, "\n") != 0) {
|
|
|
8b65ee |
- free(text);
|
|
|
8b65ee |
- return 1;
|
|
|
8b65ee |
+ if (_write_text_to_fd(output_fd, "\n") != 0) {
|
|
|
8b65ee |
+ free(text);
|
|
|
8b65ee |
+ return 1;
|
|
|
8b65ee |
+ }
|
|
|
8b65ee |
}
|
|
|
8b65ee |
|
|
|
8b65ee |
if (next_delim != NULL) {
|
|
|
8b65ee |
@@ -610,7 +610,7 @@ static int _write_fix_missing_warning_to_fd(const char *sys, int output_fd, stru
|
|
|
8b65ee |
}
|
|
|
8b65ee |
}
|
|
|
8b65ee |
|
|
|
8b65ee |
-static inline int _xccdf_policy_rule_generate_fix_ansible(const char *template, int output_fd, const char *fix_text, bool ansible_variable_mode)
|
|
|
8b65ee |
+static inline int _parse_ansible_fix(const char *fix_text, struct oscap_list *variables, struct oscap_list *tasks)
|
|
|
8b65ee |
{
|
|
|
8b65ee |
#if defined USE_REGEX_PCRE
|
|
|
8b65ee |
// TODO: Tolerate different indentation styles in this regex
|
|
|
8b65ee |
@@ -649,69 +649,53 @@ static inline int _xccdf_policy_rule_generate_fix_ansible(const char *template,
|
|
|
8b65ee |
return 1;
|
|
|
8b65ee |
}
|
|
|
8b65ee |
|
|
|
8b65ee |
- if (ansible_variable_mode) {
|
|
|
8b65ee |
- // ovector[0] and [1] hold the start and end of the whole needle match
|
|
|
8b65ee |
- // ovector[2] and [3] hold the start and end of the first capture group
|
|
|
8b65ee |
- // ovector[4] and [5] hold the start and end of the second capture group
|
|
|
8b65ee |
- char *variable_name = malloc((ovector[3] - ovector[2] + 1) * sizeof(char));
|
|
|
8b65ee |
- memcpy(variable_name, &fix_text[ovector[2]], ovector[3] - ovector[2]);
|
|
|
8b65ee |
- variable_name[ovector[3] - ovector[2]] = '\0';
|
|
|
8b65ee |
+ // ovector[0] and [1] hold the start and end of the whole needle match
|
|
|
8b65ee |
+ // ovector[2] and [3] hold the start and end of the first capture group
|
|
|
8b65ee |
+ // ovector[4] and [5] hold the start and end of the second capture group
|
|
|
8b65ee |
+ char *variable_name = malloc((ovector[3] - ovector[2] + 1) * sizeof(char));
|
|
|
8b65ee |
+ memcpy(variable_name, &fix_text[ovector[2]], ovector[3] - ovector[2]);
|
|
|
8b65ee |
+ variable_name[ovector[3] - ovector[2]] = '\0';
|
|
|
8b65ee |
|
|
|
8b65ee |
- char *variable_value = malloc((ovector[5] - ovector[4] + 1) * sizeof(char));
|
|
|
8b65ee |
- memcpy(variable_value, &fix_text[ovector[4]], ovector[5] - ovector[4]);
|
|
|
8b65ee |
- variable_value[ovector[5] - ovector[4]] = '\0';
|
|
|
8b65ee |
+ char *variable_value = malloc((ovector[5] - ovector[4] + 1) * sizeof(char));
|
|
|
8b65ee |
+ memcpy(variable_value, &fix_text[ovector[4]], ovector[5] - ovector[4]);
|
|
|
8b65ee |
+ variable_value[ovector[5] - ovector[4]] = '\0';
|
|
|
8b65ee |
|
|
|
8b65ee |
- char *var_line = oscap_sprintf(" %s: %s", variable_name, variable_value);
|
|
|
8b65ee |
+ char *var_line = oscap_sprintf(" %s: %s\n", variable_name, variable_value);
|
|
|
8b65ee |
|
|
|
8b65ee |
- free(variable_name);
|
|
|
8b65ee |
- free(variable_value);
|
|
|
8b65ee |
+ free(variable_name);
|
|
|
8b65ee |
+ free(variable_value);
|
|
|
8b65ee |
|
|
|
8b65ee |
- if (_write_remediation_to_fd_and_free(output_fd, template, var_line) != 0) {
|
|
|
8b65ee |
- pcre_free(re);
|
|
|
8b65ee |
- return 1;
|
|
|
8b65ee |
- }
|
|
|
8b65ee |
- }
|
|
|
8b65ee |
- else {
|
|
|
8b65ee |
- // Remarks: ovector doesn't contain values relative to start_offset, it contains
|
|
|
8b65ee |
- // absolute indices of fix_text.
|
|
|
8b65ee |
- const int length_between_matches = ovector[0] - start_offset;
|
|
|
8b65ee |
- char *remediation_part = malloc((length_between_matches + 1) * sizeof(char));
|
|
|
8b65ee |
- memcpy(remediation_part, &fix_text[start_offset], length_between_matches);
|
|
|
8b65ee |
- remediation_part[length_between_matches] = '\0';
|
|
|
8b65ee |
- if (_write_remediation_to_fd_and_free(output_fd, template, remediation_part) != 0) {
|
|
|
8b65ee |
- pcre_free(re);
|
|
|
8b65ee |
- return 1;
|
|
|
8b65ee |
- }
|
|
|
8b65ee |
+ if (!oscap_list_contains(variables, var_line, (oscap_cmp_func) oscap_streq)) {
|
|
|
8b65ee |
+ oscap_list_add(variables, var_line);
|
|
|
8b65ee |
}
|
|
|
8b65ee |
|
|
|
8b65ee |
+ // Remarks: ovector doesn't contain values relative to start_offset, it contains
|
|
|
8b65ee |
+ // absolute indices of fix_text.
|
|
|
8b65ee |
+ const int length_between_matches = ovector[0] - start_offset;
|
|
|
8b65ee |
+ char *remediation_part = malloc((length_between_matches + 1) * sizeof(char));
|
|
|
8b65ee |
+ memcpy(remediation_part, &fix_text[start_offset], length_between_matches);
|
|
|
8b65ee |
+ remediation_part[length_between_matches] = '\0';
|
|
|
8b65ee |
+ oscap_list_add(tasks, remediation_part);
|
|
|
8b65ee |
+
|
|
|
8b65ee |
start_offset = ovector[1]; // next time start after the entire pattern
|
|
|
8b65ee |
}
|
|
|
8b65ee |
|
|
|
8b65ee |
- if (!ansible_variable_mode && fix_text_len - start_offset > 0) {
|
|
|
8b65ee |
+ if (fix_text_len - start_offset > 0) {
|
|
|
8b65ee |
char *remediation_part = malloc((fix_text_len - start_offset + 1) * sizeof(char));
|
|
|
8b65ee |
memcpy(remediation_part, &fix_text[start_offset], fix_text_len - start_offset);
|
|
|
8b65ee |
remediation_part[fix_text_len - start_offset] = '\0';
|
|
|
8b65ee |
-
|
|
|
8b65ee |
- if (_write_remediation_to_fd_and_free(output_fd, template, remediation_part) != 0) {
|
|
|
8b65ee |
- pcre_free(re);
|
|
|
8b65ee |
- return 1;
|
|
|
8b65ee |
- }
|
|
|
8b65ee |
+ oscap_list_add(tasks, remediation_part);
|
|
|
8b65ee |
}
|
|
|
8b65ee |
|
|
|
8b65ee |
pcre_free(re);
|
|
|
8b65ee |
return 0;
|
|
|
8b65ee |
#else
|
|
|
8b65ee |
// TODO: Implement the post-process for posix regex as well
|
|
|
8b65ee |
- if (ansible_variable_mode) {
|
|
|
8b65ee |
- // this is not implemented so we don't write anything out for variables
|
|
|
8b65ee |
- return 0;
|
|
|
8b65ee |
- }
|
|
|
8b65ee |
- else
|
|
|
8b65ee |
- return _write_remediation_to_fd_and_free(output_fd, template, fix_text);
|
|
|
8b65ee |
+ oscap_list_add(tasks, strdup(fix_text));
|
|
|
8b65ee |
#endif
|
|
|
8b65ee |
}
|
|
|
8b65ee |
|
|
|
8b65ee |
-static inline int _xccdf_policy_rule_generate_fix(struct xccdf_policy *policy, struct xccdf_rule *rule, const char *template, int output_fd, unsigned int current, unsigned int total, bool ansible_variable_mode)
|
|
|
8b65ee |
+static int _xccdf_policy_rule_get_fix_text(struct xccdf_policy *policy, struct xccdf_rule *rule, const char *template, char **fix_text)
|
|
|
8b65ee |
{
|
|
|
8b65ee |
// Ensure that given Rule is selected and applicable (CPE).
|
|
|
8b65ee |
const bool is_selected = xccdf_policy_is_item_selected(policy, xccdf_rule_get_id(rule));
|
|
|
8b65ee |
@@ -722,15 +706,8 @@ static inline int _xccdf_policy_rule_generate_fix(struct xccdf_policy *policy, s
|
|
|
8b65ee |
// Find the most suitable fix.
|
|
|
8b65ee |
const struct xccdf_fix *fix = _find_fix_for_template(policy, rule, template);
|
|
|
8b65ee |
if (fix == NULL) {
|
|
|
8b65ee |
- int ret = _write_fix_header_to_fd(template, output_fd, rule, current, total);
|
|
|
8b65ee |
- if (ret != 0)
|
|
|
8b65ee |
- return ret;
|
|
|
8b65ee |
- ret = _write_fix_missing_warning_to_fd(template, output_fd, rule);
|
|
|
8b65ee |
- if (ret != 0)
|
|
|
8b65ee |
- return ret;
|
|
|
8b65ee |
- ret = _write_fix_footer_to_fd(template, output_fd, rule);
|
|
|
8b65ee |
dI("No fix element was found for Rule/@id=\"%s\"", xccdf_rule_get_id(rule));
|
|
|
8b65ee |
- return ret;
|
|
|
8b65ee |
+ return 0;
|
|
|
8b65ee |
}
|
|
|
8b65ee |
dI("Processing a fix for Rule/@id=\"%s\"", xccdf_rule_get_id(rule));
|
|
|
8b65ee |
|
|
|
8b65ee |
@@ -744,37 +721,55 @@ static inline int _xccdf_policy_rule_generate_fix(struct xccdf_policy *policy, s
|
|
|
8b65ee |
return res == 1; // Value 2 indicates warning.
|
|
|
8b65ee |
}
|
|
|
8b65ee |
// Refine. Resolve XML comments, CDATA and remaining elements
|
|
|
8b65ee |
- char *fix_text = NULL;
|
|
|
8b65ee |
- if (_xccdf_fix_decode_xml(cfix, &fix_text) != 0) {
|
|
|
8b65ee |
+ if (_xccdf_fix_decode_xml(cfix, fix_text) != 0) {
|
|
|
8b65ee |
oscap_seterr(OSCAP_EFAMILY_OSCAP, "A fix element for Rule/@id=\"%s\" contains unresolved child elements.",
|
|
|
8b65ee |
xccdf_rule_get_id(rule));
|
|
|
8b65ee |
xccdf_fix_free(cfix);
|
|
|
8b65ee |
return 1;
|
|
|
8b65ee |
}
|
|
|
8b65ee |
xccdf_fix_free(cfix);
|
|
|
8b65ee |
+ return 0;
|
|
|
8b65ee |
+}
|
|
|
8b65ee |
|
|
|
8b65ee |
- int ret = _write_fix_header_to_fd(template, output_fd, rule, current, total);
|
|
|
8b65ee |
+static int _xccdf_policy_rule_generate_fix(struct xccdf_policy *policy, struct xccdf_rule *rule, const char *template, int output_fd, unsigned int current, unsigned int total, bool ansible_variable_mode)
|
|
|
8b65ee |
+{
|
|
|
8b65ee |
+ char *fix_text = NULL;
|
|
|
8b65ee |
+ int ret = _xccdf_policy_rule_get_fix_text(policy, rule, template, &fix_text);
|
|
|
8b65ee |
+ if (fix_text == NULL || ret != 0) {
|
|
|
8b65ee |
+ ret = _write_fix_header_to_fd(template, output_fd, rule, current, total);
|
|
|
8b65ee |
+ if (ret != 0) {
|
|
|
8b65ee |
+ return ret;
|
|
|
8b65ee |
+ }
|
|
|
8b65ee |
+ ret = _write_fix_missing_warning_to_fd(template, output_fd, rule);
|
|
|
8b65ee |
+ if (ret != 0) {
|
|
|
8b65ee |
+ return ret;
|
|
|
8b65ee |
+ }
|
|
|
8b65ee |
+ ret = _write_fix_footer_to_fd(template, output_fd, rule);
|
|
|
8b65ee |
+ return ret;
|
|
|
8b65ee |
+ }
|
|
|
8b65ee |
+ ret = _write_fix_header_to_fd(template, output_fd, rule, current, total);
|
|
|
8b65ee |
if (ret != 0) {
|
|
|
8b65ee |
free(fix_text);
|
|
|
8b65ee |
return ret;
|
|
|
8b65ee |
}
|
|
|
8b65ee |
+ ret = _write_remediation_to_fd_and_free(output_fd, template, fix_text);
|
|
|
8b65ee |
+ if (ret != 0) {
|
|
|
8b65ee |
+ return ret;
|
|
|
8b65ee |
+ }
|
|
|
8b65ee |
+ ret = _write_fix_footer_to_fd(template, output_fd, rule);
|
|
|
8b65ee |
+ return ret;
|
|
|
8b65ee |
+}
|
|
|
8b65ee |
|
|
|
8b65ee |
- if (oscap_streq(template, "urn:xccdf:fix:script:ansible")) {
|
|
|
8b65ee |
- // Ansible is special because we have two output modes, variable and
|
|
|
8b65ee |
- // task mode. In both cases we have to do post processing.
|
|
|
8b65ee |
|
|
|
8b65ee |
- // We can't recover the return value (it is rewritten by a later call) to _write_fix_footer_to_fd
|
|
|
8b65ee |
- _xccdf_policy_rule_generate_fix_ansible(template, output_fd, fix_text, ansible_variable_mode);
|
|
|
8b65ee |
- free(fix_text);
|
|
|
8b65ee |
- }
|
|
|
8b65ee |
- else {
|
|
|
8b65ee |
- ret = _write_remediation_to_fd_and_free(output_fd, template, fix_text);
|
|
|
8b65ee |
- if (ret != 0) {
|
|
|
8b65ee |
- return ret;
|
|
|
8b65ee |
- }
|
|
|
8b65ee |
+static int _xccdf_policy_rule_generate_ansible_fix(struct xccdf_policy *policy, struct xccdf_rule *rule, const char *template, struct oscap_list *variables, struct oscap_list *tasks)
|
|
|
8b65ee |
+{
|
|
|
8b65ee |
+ char *fix_text = NULL;
|
|
|
8b65ee |
+ int ret = _xccdf_policy_rule_get_fix_text(policy, rule, template, &fix_text);
|
|
|
8b65ee |
+ if (fix_text == NULL) {
|
|
|
8b65ee |
+ return ret;
|
|
|
8b65ee |
}
|
|
|
8b65ee |
-
|
|
|
8b65ee |
- ret = _write_fix_footer_to_fd(template, output_fd, rule);
|
|
|
8b65ee |
+ ret = _parse_ansible_fix(fix_text, variables, tasks);
|
|
|
8b65ee |
+ free(fix_text);
|
|
|
8b65ee |
return ret;
|
|
|
8b65ee |
}
|
|
|
8b65ee |
|
|
|
8b65ee |
@@ -988,30 +983,45 @@ int xccdf_policy_generate_fix(struct xccdf_policy *policy, struct xccdf_result *
|
|
|
8b65ee |
|
|
|
8b65ee |
// In Ansible we have to generate variables first and then tasks
|
|
|
8b65ee |
if (strcmp(sys, "urn:xccdf:fix:script:ansible") == 0) {
|
|
|
8b65ee |
+ struct oscap_list *variables = oscap_list_new();
|
|
|
8b65ee |
+ struct oscap_list *tasks = oscap_list_new();
|
|
|
8b65ee |
+ struct oscap_iterator *rules_to_fix_it = oscap_iterator_new(rules_to_fix);
|
|
|
8b65ee |
+ while (oscap_iterator_has_more(rules_to_fix_it)) {
|
|
|
8b65ee |
+ struct xccdf_rule *rule = (struct xccdf_rule*)oscap_iterator_next(rules_to_fix_it);
|
|
|
8b65ee |
+ ret = _xccdf_policy_rule_generate_ansible_fix(policy, rule, sys, variables, tasks);
|
|
|
8b65ee |
+ if (ret != 0)
|
|
|
8b65ee |
+ break;
|
|
|
8b65ee |
+ }
|
|
|
8b65ee |
+ oscap_iterator_free(rules_to_fix_it);
|
|
|
8b65ee |
+
|
|
|
8b65ee |
_write_text_to_fd(output_fd, " vars:\n");
|
|
|
8b65ee |
+ struct oscap_iterator *variables_it = oscap_iterator_new(variables);
|
|
|
8b65ee |
+ while(oscap_iterator_has_more(variables_it)) {
|
|
|
8b65ee |
+ char *var_line = (char *) oscap_iterator_next(variables_it);
|
|
|
8b65ee |
+ _write_text_to_fd(output_fd, var_line);
|
|
|
8b65ee |
+ }
|
|
|
8b65ee |
+ oscap_iterator_free(variables_it);
|
|
|
8b65ee |
+ oscap_list_free(variables, free);
|
|
|
8b65ee |
|
|
|
8b65ee |
+ _write_text_to_fd(output_fd, " tasks:\n");
|
|
|
8b65ee |
+ struct oscap_iterator *tasks_it = oscap_iterator_new(tasks);
|
|
|
8b65ee |
+ while(oscap_iterator_has_more(tasks_it)) {
|
|
|
8b65ee |
+ char *var_line = strdup((char *) oscap_iterator_next(tasks_it));
|
|
|
8b65ee |
+ _write_remediation_to_fd_and_free(output_fd, sys, var_line);
|
|
|
8b65ee |
+ }
|
|
|
8b65ee |
+ oscap_iterator_free(tasks_it);
|
|
|
8b65ee |
+ oscap_list_free(tasks, free);
|
|
|
8b65ee |
+ } else {
|
|
|
8b65ee |
unsigned int current = 1;
|
|
|
8b65ee |
struct oscap_iterator *rules_to_fix_it = oscap_iterator_new(rules_to_fix);
|
|
|
8b65ee |
while (oscap_iterator_has_more(rules_to_fix_it)) {
|
|
|
8b65ee |
struct xccdf_rule *rule = (struct xccdf_rule*)oscap_iterator_next(rules_to_fix_it);
|
|
|
8b65ee |
- ret = _xccdf_policy_rule_generate_fix(policy, rule, sys, output_fd, current++, total, true);
|
|
|
8b65ee |
+ ret = _xccdf_policy_rule_generate_fix(policy, rule, sys, output_fd, current++, total, false);
|
|
|
8b65ee |
if (ret != 0)
|
|
|
8b65ee |
break;
|
|
|
8b65ee |
}
|
|
|
8b65ee |
oscap_iterator_free(rules_to_fix_it);
|
|
|
8b65ee |
-
|
|
|
8b65ee |
- _write_text_to_fd(output_fd, " tasks:\n");
|
|
|
8b65ee |
- }
|
|
|
8b65ee |
-
|
|
|
8b65ee |
- unsigned int current = 1;
|
|
|
8b65ee |
- struct oscap_iterator *rules_to_fix_it = oscap_iterator_new(rules_to_fix);
|
|
|
8b65ee |
- while (oscap_iterator_has_more(rules_to_fix_it)) {
|
|
|
8b65ee |
- struct xccdf_rule *rule = (struct xccdf_rule*)oscap_iterator_next(rules_to_fix_it);
|
|
|
8b65ee |
- ret = _xccdf_policy_rule_generate_fix(policy, rule, sys, output_fd, current++, total, false);
|
|
|
8b65ee |
- if (ret != 0)
|
|
|
8b65ee |
- break;
|
|
|
8b65ee |
}
|
|
|
8b65ee |
- oscap_iterator_free(rules_to_fix_it);
|
|
|
8b65ee |
|
|
|
8b65ee |
oscap_list_free(rules_to_fix, NULL);
|
|
|
8b65ee |
|
|
|
8b65ee |
|
|
|
8b65ee |
From 8badfbf30f423ca2f9452ab3ac6daf8bb8d850e3 Mon Sep 17 00:00:00 2001
|
|
|
8b65ee |
From: =?UTF-8?q?Jan=20=C4=8Cern=C3=BD?= <jcerny@redhat.com>
|
|
|
8b65ee |
Date: Thu, 22 Nov 2018 13:43:40 +0100
|
|
|
8b65ee |
Subject: [PATCH 2/4] Remove unused parameter
|
|
|
8b65ee |
|
|
|
8b65ee |
This parameter is not used in this function. The function is static
|
|
|
8b65ee |
and it is used only at one place, so we can safely omit this parameter.
|
|
|
8b65ee |
---
|
|
|
8b65ee |
src/XCCDF_POLICY/xccdf_policy_remediate.c | 4 ++--
|
|
|
8b65ee |
1 file changed, 2 insertions(+), 2 deletions(-)
|
|
|
8b65ee |
|
|
|
8b65ee |
diff --git a/src/XCCDF_POLICY/xccdf_policy_remediate.c b/src/XCCDF_POLICY/xccdf_policy_remediate.c
|
|
|
8b65ee |
index 6ac566225c..520e9ff4de 100644
|
|
|
8b65ee |
--- a/src/XCCDF_POLICY/xccdf_policy_remediate.c
|
|
|
8b65ee |
+++ b/src/XCCDF_POLICY/xccdf_policy_remediate.c
|
|
|
8b65ee |
@@ -731,7 +731,7 @@ static int _xccdf_policy_rule_get_fix_text(struct xccdf_policy *policy, struct x
|
|
|
8b65ee |
return 0;
|
|
|
8b65ee |
}
|
|
|
8b65ee |
|
|
|
8b65ee |
-static int _xccdf_policy_rule_generate_fix(struct xccdf_policy *policy, struct xccdf_rule *rule, const char *template, int output_fd, unsigned int current, unsigned int total, bool ansible_variable_mode)
|
|
|
8b65ee |
+static int _xccdf_policy_rule_generate_fix(struct xccdf_policy *policy, struct xccdf_rule *rule, const char *template, int output_fd, unsigned int current, unsigned int total)
|
|
|
8b65ee |
{
|
|
|
8b65ee |
char *fix_text = NULL;
|
|
|
8b65ee |
int ret = _xccdf_policy_rule_get_fix_text(policy, rule, template, &fix_text);
|
|
|
8b65ee |
@@ -1016,7 +1016,7 @@ int xccdf_policy_generate_fix(struct xccdf_policy *policy, struct xccdf_result *
|
|
|
8b65ee |
struct oscap_iterator *rules_to_fix_it = oscap_iterator_new(rules_to_fix);
|
|
|
8b65ee |
while (oscap_iterator_has_more(rules_to_fix_it)) {
|
|
|
8b65ee |
struct xccdf_rule *rule = (struct xccdf_rule*)oscap_iterator_next(rules_to_fix_it);
|
|
|
8b65ee |
- ret = _xccdf_policy_rule_generate_fix(policy, rule, sys, output_fd, current++, total, false);
|
|
|
8b65ee |
+ ret = _xccdf_policy_rule_generate_fix(policy, rule, sys, output_fd, current++, total);
|
|
|
8b65ee |
if (ret != 0)
|
|
|
8b65ee |
break;
|
|
|
8b65ee |
}
|
|
|
8b65ee |
|
|
|
8b65ee |
From 90e0354c3eef165d8b467e6d843e9dfe1d264416 Mon Sep 17 00:00:00 2001
|
|
|
8b65ee |
From: =?UTF-8?q?Jan=20=C4=8Cern=C3=BD?= <jcerny@redhat.com>
|
|
|
8b65ee |
Date: Mon, 26 Nov 2018 18:18:47 +0100
|
|
|
8b65ee |
Subject: [PATCH 3/4] Refactor: Extract functions
|
|
|
8b65ee |
|
|
|
8b65ee |
To improve the readability of the code we can refactor the code
|
|
|
8b65ee |
that is specific to Ansible to a separate method. We can also make
|
|
|
8b65ee |
a similar change in the `else` branch.
|
|
|
8b65ee |
---
|
|
|
8b65ee |
src/XCCDF_POLICY/xccdf_policy_remediate.c | 94 +++++++++++++----------
|
|
|
8b65ee |
1 file changed, 54 insertions(+), 40 deletions(-)
|
|
|
8b65ee |
|
|
|
8b65ee |
diff --git a/src/XCCDF_POLICY/xccdf_policy_remediate.c b/src/XCCDF_POLICY/xccdf_policy_remediate.c
|
|
|
8b65ee |
index 520e9ff4de..bf36523dfd 100644
|
|
|
8b65ee |
--- a/src/XCCDF_POLICY/xccdf_policy_remediate.c
|
|
|
8b65ee |
+++ b/src/XCCDF_POLICY/xccdf_policy_remediate.c
|
|
|
8b65ee |
@@ -929,6 +929,56 @@ static int _write_script_header_to_fd(struct xccdf_policy *policy, struct xccdf_
|
|
|
8b65ee |
}
|
|
|
8b65ee |
}
|
|
|
8b65ee |
|
|
|
8b65ee |
+static int _xccdf_policy_generate_fix_ansible(struct oscap_list *rules_to_fix, struct xccdf_policy *policy, const char *sys, int output_fd)
|
|
|
8b65ee |
+{
|
|
|
8b65ee |
+ int ret = 0;
|
|
|
8b65ee |
+ struct oscap_list *variables = oscap_list_new();
|
|
|
8b65ee |
+ struct oscap_list *tasks = oscap_list_new();
|
|
|
8b65ee |
+ struct oscap_iterator *rules_to_fix_it = oscap_iterator_new(rules_to_fix);
|
|
|
8b65ee |
+ while (oscap_iterator_has_more(rules_to_fix_it)) {
|
|
|
8b65ee |
+ struct xccdf_rule *rule = (struct xccdf_rule*)oscap_iterator_next(rules_to_fix_it);
|
|
|
8b65ee |
+ ret = _xccdf_policy_rule_generate_ansible_fix(policy, rule, sys, variables, tasks);
|
|
|
8b65ee |
+ if (ret != 0)
|
|
|
8b65ee |
+ break;
|
|
|
8b65ee |
+ }
|
|
|
8b65ee |
+ oscap_iterator_free(rules_to_fix_it);
|
|
|
8b65ee |
+
|
|
|
8b65ee |
+ _write_text_to_fd(output_fd, " vars:\n");
|
|
|
8b65ee |
+ struct oscap_iterator *variables_it = oscap_iterator_new(variables);
|
|
|
8b65ee |
+ while(oscap_iterator_has_more(variables_it)) {
|
|
|
8b65ee |
+ char *var_line = (char *) oscap_iterator_next(variables_it);
|
|
|
8b65ee |
+ _write_text_to_fd(output_fd, var_line);
|
|
|
8b65ee |
+ }
|
|
|
8b65ee |
+ oscap_iterator_free(variables_it);
|
|
|
8b65ee |
+ oscap_list_free(variables, free);
|
|
|
8b65ee |
+
|
|
|
8b65ee |
+ _write_text_to_fd(output_fd, " tasks:\n");
|
|
|
8b65ee |
+ struct oscap_iterator *tasks_it = oscap_iterator_new(tasks);
|
|
|
8b65ee |
+ while(oscap_iterator_has_more(tasks_it)) {
|
|
|
8b65ee |
+ char *var_line = strdup((char *) oscap_iterator_next(tasks_it));
|
|
|
8b65ee |
+ _write_remediation_to_fd_and_free(output_fd, sys, var_line);
|
|
|
8b65ee |
+ }
|
|
|
8b65ee |
+ oscap_iterator_free(tasks_it);
|
|
|
8b65ee |
+ oscap_list_free(tasks, free);
|
|
|
8b65ee |
+ return ret;
|
|
|
8b65ee |
+}
|
|
|
8b65ee |
+
|
|
|
8b65ee |
+static int _xccdf_policy_generate_fix_other(struct oscap_list *rules_to_fix, struct xccdf_policy *policy, const char *sys, int output_fd)
|
|
|
8b65ee |
+{
|
|
|
8b65ee |
+ int ret = 0;
|
|
|
8b65ee |
+ const unsigned int total = oscap_list_get_itemcount(rules_to_fix);
|
|
|
8b65ee |
+ unsigned int current = 1;
|
|
|
8b65ee |
+ struct oscap_iterator *rules_to_fix_it = oscap_iterator_new(rules_to_fix);
|
|
|
8b65ee |
+ while (oscap_iterator_has_more(rules_to_fix_it)) {
|
|
|
8b65ee |
+ struct xccdf_rule *rule = (struct xccdf_rule *) oscap_iterator_next(rules_to_fix_it);
|
|
|
8b65ee |
+ ret = _xccdf_policy_rule_generate_fix(policy, rule, sys, output_fd, current++, total);
|
|
|
8b65ee |
+ if (ret != 0)
|
|
|
8b65ee |
+ break;
|
|
|
8b65ee |
+ }
|
|
|
8b65ee |
+ oscap_iterator_free(rules_to_fix_it);
|
|
|
8b65ee |
+ return ret;
|
|
|
8b65ee |
+}
|
|
|
8b65ee |
+
|
|
|
8b65ee |
int xccdf_policy_generate_fix(struct xccdf_policy *policy, struct xccdf_result *result, const char *sys, int output_fd)
|
|
|
8b65ee |
{
|
|
|
8b65ee |
__attribute__nonnull__(policy);
|
|
|
8b65ee |
@@ -979,48 +1029,12 @@ int xccdf_policy_generate_fix(struct xccdf_policy *policy, struct xccdf_result *
|
|
|
8b65ee |
xccdf_rule_result_iterator_free(rr_it);
|
|
|
8b65ee |
}
|
|
|
8b65ee |
|
|
|
8b65ee |
- const unsigned int total = oscap_list_get_itemcount(rules_to_fix);
|
|
|
8b65ee |
-
|
|
|
8b65ee |
- // In Ansible we have to generate variables first and then tasks
|
|
|
8b65ee |
+ // Ansible Playbooks are generated using a different function because
|
|
|
8b65ee |
+ // in Ansible we have to generate variables first and then tasks
|
|
|
8b65ee |
if (strcmp(sys, "urn:xccdf:fix:script:ansible") == 0) {
|
|
|
8b65ee |
- struct oscap_list *variables = oscap_list_new();
|
|
|
8b65ee |
- struct oscap_list *tasks = oscap_list_new();
|
|
|
8b65ee |
- struct oscap_iterator *rules_to_fix_it = oscap_iterator_new(rules_to_fix);
|
|
|
8b65ee |
- while (oscap_iterator_has_more(rules_to_fix_it)) {
|
|
|
8b65ee |
- struct xccdf_rule *rule = (struct xccdf_rule*)oscap_iterator_next(rules_to_fix_it);
|
|
|
8b65ee |
- ret = _xccdf_policy_rule_generate_ansible_fix(policy, rule, sys, variables, tasks);
|
|
|
8b65ee |
- if (ret != 0)
|
|
|
8b65ee |
- break;
|
|
|
8b65ee |
- }
|
|
|
8b65ee |
- oscap_iterator_free(rules_to_fix_it);
|
|
|
8b65ee |
-
|
|
|
8b65ee |
- _write_text_to_fd(output_fd, " vars:\n");
|
|
|
8b65ee |
- struct oscap_iterator *variables_it = oscap_iterator_new(variables);
|
|
|
8b65ee |
- while(oscap_iterator_has_more(variables_it)) {
|
|
|
8b65ee |
- char *var_line = (char *) oscap_iterator_next(variables_it);
|
|
|
8b65ee |
- _write_text_to_fd(output_fd, var_line);
|
|
|
8b65ee |
- }
|
|
|
8b65ee |
- oscap_iterator_free(variables_it);
|
|
|
8b65ee |
- oscap_list_free(variables, free);
|
|
|
8b65ee |
-
|
|
|
8b65ee |
- _write_text_to_fd(output_fd, " tasks:\n");
|
|
|
8b65ee |
- struct oscap_iterator *tasks_it = oscap_iterator_new(tasks);
|
|
|
8b65ee |
- while(oscap_iterator_has_more(tasks_it)) {
|
|
|
8b65ee |
- char *var_line = strdup((char *) oscap_iterator_next(tasks_it));
|
|
|
8b65ee |
- _write_remediation_to_fd_and_free(output_fd, sys, var_line);
|
|
|
8b65ee |
- }
|
|
|
8b65ee |
- oscap_iterator_free(tasks_it);
|
|
|
8b65ee |
- oscap_list_free(tasks, free);
|
|
|
8b65ee |
+ ret = _xccdf_policy_generate_fix_ansible(rules_to_fix, policy, sys, output_fd);
|
|
|
8b65ee |
} else {
|
|
|
8b65ee |
- unsigned int current = 1;
|
|
|
8b65ee |
- struct oscap_iterator *rules_to_fix_it = oscap_iterator_new(rules_to_fix);
|
|
|
8b65ee |
- while (oscap_iterator_has_more(rules_to_fix_it)) {
|
|
|
8b65ee |
- struct xccdf_rule *rule = (struct xccdf_rule*)oscap_iterator_next(rules_to_fix_it);
|
|
|
8b65ee |
- ret = _xccdf_policy_rule_generate_fix(policy, rule, sys, output_fd, current++, total);
|
|
|
8b65ee |
- if (ret != 0)
|
|
|
8b65ee |
- break;
|
|
|
8b65ee |
- }
|
|
|
8b65ee |
- oscap_iterator_free(rules_to_fix_it);
|
|
|
8b65ee |
+ ret = _xccdf_policy_generate_fix_other(rules_to_fix, policy, sys, output_fd);
|
|
|
8b65ee |
}
|
|
|
8b65ee |
|
|
|
8b65ee |
oscap_list_free(rules_to_fix, NULL);
|
|
|
8b65ee |
|
|
|
8b65ee |
From 2a11da0a6a1643669caadb72f1a217fafcfea6d5 Mon Sep 17 00:00:00 2001
|
|
|
8b65ee |
From: =?UTF-8?q?Jan=20=C4=8Cern=C3=BD?= <jcerny@redhat.com>
|
|
|
8b65ee |
Date: Wed, 28 Nov 2018 14:19:12 +0100
|
|
|
8b65ee |
Subject: [PATCH 4/4] Refactor: Remove duplicate code
|
|
|
8b65ee |
|
|
|
8b65ee |
---
|
|
|
8b65ee |
src/XCCDF_POLICY/xccdf_policy_remediate.c | 23 +++++++----------------
|
|
|
8b65ee |
1 file changed, 7 insertions(+), 16 deletions(-)
|
|
|
8b65ee |
|
|
|
8b65ee |
diff --git a/src/XCCDF_POLICY/xccdf_policy_remediate.c b/src/XCCDF_POLICY/xccdf_policy_remediate.c
|
|
|
8b65ee |
index bf36523dfd..15f9453938 100644
|
|
|
8b65ee |
--- a/src/XCCDF_POLICY/xccdf_policy_remediate.c
|
|
|
8b65ee |
+++ b/src/XCCDF_POLICY/xccdf_policy_remediate.c
|
|
|
8b65ee |
@@ -733,26 +733,17 @@ static int _xccdf_policy_rule_get_fix_text(struct xccdf_policy *policy, struct x
|
|
|
8b65ee |
|
|
|
8b65ee |
static int _xccdf_policy_rule_generate_fix(struct xccdf_policy *policy, struct xccdf_rule *rule, const char *template, int output_fd, unsigned int current, unsigned int total)
|
|
|
8b65ee |
{
|
|
|
8b65ee |
+ int ret = _write_fix_header_to_fd(template, output_fd, rule, current, total);
|
|
|
8b65ee |
+ if (ret != 0) {
|
|
|
8b65ee |
+ return ret;
|
|
|
8b65ee |
+ }
|
|
|
8b65ee |
char *fix_text = NULL;
|
|
|
8b65ee |
- int ret = _xccdf_policy_rule_get_fix_text(policy, rule, template, &fix_text);
|
|
|
8b65ee |
+ ret = _xccdf_policy_rule_get_fix_text(policy, rule, template, &fix_text);
|
|
|
8b65ee |
if (fix_text == NULL || ret != 0) {
|
|
|
8b65ee |
- ret = _write_fix_header_to_fd(template, output_fd, rule, current, total);
|
|
|
8b65ee |
- if (ret != 0) {
|
|
|
8b65ee |
- return ret;
|
|
|
8b65ee |
- }
|
|
|
8b65ee |
ret = _write_fix_missing_warning_to_fd(template, output_fd, rule);
|
|
|
8b65ee |
- if (ret != 0) {
|
|
|
8b65ee |
- return ret;
|
|
|
8b65ee |
- }
|
|
|
8b65ee |
- ret = _write_fix_footer_to_fd(template, output_fd, rule);
|
|
|
8b65ee |
- return ret;
|
|
|
8b65ee |
- }
|
|
|
8b65ee |
- ret = _write_fix_header_to_fd(template, output_fd, rule, current, total);
|
|
|
8b65ee |
- if (ret != 0) {
|
|
|
8b65ee |
- free(fix_text);
|
|
|
8b65ee |
- return ret;
|
|
|
8b65ee |
+ } else {
|
|
|
8b65ee |
+ ret = _write_remediation_to_fd_and_free(output_fd, template, fix_text);
|
|
|
8b65ee |
}
|
|
|
8b65ee |
- ret = _write_remediation_to_fd_and_free(output_fd, template, fix_text);
|
|
|
8b65ee |
if (ret != 0) {
|
|
|
8b65ee |
return ret;
|
|
|
8b65ee |
}
|