Skip to content

Commit

Permalink
Add: New compliance filter keywords for results
Browse files Browse the repository at this point in the history
The filters of the get_reports and get_results commands now support two
new keywords for filtering results by their compliance status:
The option "compliance_levels" that allows a selection applying to the
whole filter similar to "levels" for severity and a "compliant" column
that can be used with boolean operator keywords.
  • Loading branch information
timopollmeier authored and a-h-abdelsalam committed Dec 7, 2023
1 parent 5a18eb9 commit d2d4ee5
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 7 deletions.
84 changes: 78 additions & 6 deletions src/manage_sql.c
Original file line number Diff line number Diff line change
Expand Up @@ -22031,6 +22031,63 @@ where_levels_auto (const char *levels, const char *new_severity_sql)
return levels_sql;
}

/**
* @brief Return SQL WHERE for restricting a SELECT to compliance levels.
*
* @param[in] levels String describing compliance levels to include in
* report (for example, "yniu" for "yes, "no", "incomplete"
* and "undefined"). All levels if NULL.
*
* @return WHERE clause for compliance levels if one is required, else NULL.
*/
static gchar*
where_compliance_levels (const char *levels)
{
int count;
GString *levels_sql;

if (levels == NULL)
return NULL;

levels_sql = g_string_new ("");
count = 0;

g_string_append_printf (levels_sql,
" AND coalesce("
" lower(substring(description, '^Compliant:[\\s]*([A-Z_]*)')),"
" 'undefined') IN (");

if (strchr (levels, 'y'))
{
g_string_append (levels_sql, "'yes'");
count++;
}
if (strchr (levels, 'n'))
{
g_string_append (levels_sql, count ? ", 'no'" : "'no'");
count++;
}
if (strchr (levels, 'i'))
{
g_string_append (levels_sql, count ? ", 'incomplete'" : "'incomplete'");
count++;
}
if (strchr (levels, 'u'))
{
g_string_append (levels_sql, count ? ", 'undefined'" : "'undefined'");
count++;
}
g_string_append (levels_sql, ")");

if (count == 4)
{
/* All compliance levels selected, so no restriction is necessary. */
g_string_free (levels_sql, TRUE);
return NULL;
}
return g_string_free (levels_sql, FALSE);
}

/**
* @brief Return SQL WHERE for restricting a SELECT to a minimum QoD.
*
Expand Down Expand Up @@ -22061,7 +22118,7 @@ where_qod (int min_qod)
"description", "task", "report", "cvss_base", "nvt_version", \
"severity", "original_severity", "vulnerability", "date", "report_id", \
"solution_type", "qod", "qod_type", "task_id", "cve", "hostname", \
"path", NULL }
"path", "compliant", NULL }

// TODO Combine with RESULT_ITERATOR_COLUMNS.
/**
Expand Down Expand Up @@ -22173,6 +22230,10 @@ where_qod (int min_qod)
KEYWORD_TYPE_INTEGER }, \
{ "(SELECT name FROM tasks WHERE tasks.id = task)", \
"task", \
KEYWORD_TYPE_STRING }, \
{ "coalesce(lower(substring(description, '^Compliant:[\\s]*([A-Z_]*)'))," \
" 'undefined')", \
"compliant", \
KEYWORD_TYPE_STRING },

/**
Expand Down Expand Up @@ -22349,6 +22410,10 @@ where_qod (int min_qod)
{ "nvts.tag", \
NULL, \
KEYWORD_TYPE_STRING }, \
{ "coalesce(lower(substring(description, '^Compliant:[\\s]*([A-Z_]*)'))," \
" 'undefined')", \
"compliant", \
KEYWORD_TYPE_STRING }, \

/**
* @brief Result iterator columns.
Expand Down Expand Up @@ -22599,8 +22664,9 @@ results_extra_where (int trash, report_t report, const gchar* host,
{
gchar *extra_where;
int min_qod;
gchar *levels;
gchar *levels, *compliance_levels;
gchar *report_clause, *host_clause, *min_qod_clause;
gchar *compliance_levels_clause;
GString *levels_clause;
gchar *new_severity_sql;

Expand All @@ -22609,6 +22675,7 @@ results_extra_where (int trash, report_t report, const gchar* host,
levels = filter_term_value (filter, "levels");
if (levels == NULL)
levels = g_strdup ("hmlgdf");
compliance_levels = filter_term_value (filter, "compliance_levels");

// Build clause fragments

Expand Down Expand Up @@ -22637,19 +22704,24 @@ results_extra_where (int trash, report_t report, const gchar* host,
given_new_severity_sql
? given_new_severity_sql
: new_severity_sql);

compliance_levels_clause = where_compliance_levels (compliance_levels);

g_free (levels);
g_free (new_severity_sql);

extra_where = g_strdup_printf("%s%s%s%s",
extra_where = g_strdup_printf("%s%s%s%s%s",
report_clause ? report_clause : "",
host_clause ? host_clause : "",
levels_clause->str,
min_qod_clause ? min_qod_clause : "");
min_qod_clause ? min_qod_clause : "",
compliance_levels_clause ?: "");

g_free (min_qod_clause);
g_string_free (levels_clause, TRUE);
g_free (report_clause);
g_free (host_clause);
g_free (compliance_levels_clause);

return extra_where;
}
Expand Down Expand Up @@ -23606,7 +23678,7 @@ gchar **
result_iterator_cert_bunds (iterator_t* iterator)
{
if (iterator->done) return 0;
return iterator_array (iterator, GET_ITERATOR_COLUMN_COUNT + 35);
return iterator_array (iterator, GET_ITERATOR_COLUMN_COUNT + 36);
}

/**
Expand All @@ -23620,7 +23692,7 @@ gchar **
result_iterator_dfn_certs (iterator_t* iterator)
{
if (iterator->done) return 0;
return iterator_array (iterator, GET_ITERATOR_COLUMN_COUNT + 36);
return iterator_array (iterator, GET_ITERATOR_COLUMN_COUNT + 37);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/manage_sql.h
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ typedef struct
/**
* @brief Delta results columns offset for result iterator.
*/
#define RESULT_ITERATOR_DELTA_COLUMN_OFFSET GET_ITERATOR_COLUMN_COUNT + 37
#define RESULT_ITERATOR_DELTA_COLUMN_OFFSET GET_ITERATOR_COLUMN_COUNT + 38


/* Variables */
Expand Down
44 changes: 44 additions & 0 deletions src/schema_formats/XML/GMP.xml.in
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
</description>
<pattern>text</pattern>
</type>
<type>
<name>compliance_levels</name>
<summary>A string selecting compliance levels that may include the characters y, n, i and u</summary>
<description>
The meanings of the letters for each level are: "y" for "yes" (compliant),
"n" for "no" (not compliant), "i" for "incomplete" and "u" for "undefined"
(without compliance information).
</description>
<pattern>xsd:token { pattern = "y?n?i?u?" }</pattern>
</type>
<type>
<name>ctime</name>
<summary>A date and time, in the C `ctime' format</summary>
Expand Down Expand Up @@ -15535,6 +15545,11 @@ END:VCALENDAR
<type>boolean</type>
<summary>Whether to apply Overrides</summary>
</option>
<option>
<name>compliance_levels</name>
<type>compliance_levels</type>
<summary>Compliance levels to select</summary>
</option>
<option>
<name>delta_states</name>
<type>delta_states</type>
Expand Down Expand Up @@ -15605,6 +15620,18 @@ END:VCALENDAR
<type>name</type>
<summary>Name of the owner</summary>
</column>
<column>
<name>compliant</name>
<type>
<alts>
<alt>yes</alt>
<alt>no</alt>
<alt>incomplete</alt>
<alt>undefined</alt>
</alts>
</type>
<summary>Compliance status</summary>
</column>
<column>
<name>host</name>
<type>text</type>
Expand Down Expand Up @@ -17057,6 +17084,11 @@ END:VCALENDAR
<type>boolean</type>
<summary>Whether to apply Overrides</summary>
</option>
<option>
<name>compliance_levels</name>
<type>compliance_levels</type>
<summary>Compliance levels to select</summary>
</option>
<option>
<name>levels</name>
<type>levels</type>
Expand Down Expand Up @@ -17122,6 +17154,18 @@ END:VCALENDAR
<type>name</type>
<summary>Name of the owner</summary>
</column>
<column>
<name>compliant</name>
<type>
<alts>
<alt>yes</alt>
<alt>no</alt>
<alt>incomplete</alt>
<alt>undefined</alt>
</alts>
</type>
<summary>Compliance status</summary>
</column>
<column>
<name>host</name>
<type>text</type>
Expand Down

0 comments on commit d2d4ee5

Please sign in to comment.