Skip to content

Commit

Permalink
Change: Store CPE XML for details in database
Browse files Browse the repository at this point in the history
  • Loading branch information
timopollmeier authored Apr 5, 2023
2 parents 4f92cdc + 1a12bcd commit 477a4cb
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 33 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ include (CPack)

set (GVMD_DATABASE_VERSION 251)

set (GVMD_SCAP_DATABASE_VERSION 19)
set (GVMD_SCAP_DATABASE_VERSION 20)

set (GVMD_CERT_DATABASE_VERSION 8)

Expand Down
2 changes: 1 addition & 1 deletion src/gmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -13122,7 +13122,7 @@ handle_get_info (gmp_parser_t *gmp_parser, GError **error)
manage_read_info (get_info_data->type, nonconst_id,
nonconst_name, &raw_data);
g_string_append_printf (result, "<raw_data>%s</raw_data>",
raw_data);
raw_data ? raw_data : "");
g_free(nonconst_id);
g_free(nonconst_name);
g_free(raw_data);
Expand Down
22 changes: 1 addition & 21 deletions src/manage.c
Original file line number Diff line number Diff line change
Expand Up @@ -5328,18 +5328,6 @@ set_schedule_timeout (int new_timeout)
/* Defined in gmp.c. */
void buffer_config_preference_xml (GString *, iterator_t *, config_t, int);

/**
* @brief Return the path to the CPE dictionary.
*
* @return A dynamically allocated string (to be g_free'd) containing the
* path to the desired file.
*/
static char *
get_cpe_filename ()
{
return g_strdup (CPE_DICT_FILENAME);
}

/**
* @brief Compute the filename where a given CVE can be found.
*
Expand Down Expand Up @@ -5898,15 +5886,7 @@ manage_read_info (gchar *type, gchar *uid, gchar *name, gchar **result)

if (g_ascii_strcasecmp ("CPE", type) == 0)
{
fname = get_cpe_filename ();
if (fname)
{
gchar *cpe;
cpe = xsl_transform (CPE_GETBYNAME_XSL, fname, pnames, pvalues);
g_free (fname);
if (cpe)
*result = cpe;
}
*result = cpe_details_xml(uid);
}
else if (g_ascii_strcasecmp ("CVE", type) == 0)
{
Expand Down
3 changes: 3 additions & 0 deletions src/manage.h
Original file line number Diff line number Diff line change
Expand Up @@ -3160,6 +3160,9 @@ cpe_info_iterator_cve_refs (iterator_t*);
const char*
cpe_info_iterator_nvd_id (iterator_t*);

gchar *
cpe_details_xml (const char*);

/* CVE. */

const char*
Expand Down
8 changes: 8 additions & 0 deletions src/manage_pg.c
Original file line number Diff line number Diff line change
Expand Up @@ -3275,6 +3275,11 @@ manage_db_init (const gchar *name)
" cve_refs INTEGER DEFAULT 0,"
" nvd_id text);");

sql ("CREATE TABLE scap2.cpe_details"
" (id SERIAL PRIMARY KEY,"
" cpe_id text,"
" details_xml text);");

sql ("CREATE TABLE scap2.affected_products"
" (cve INTEGER,"
" cpe INTEGER);");
Expand Down Expand Up @@ -3314,6 +3319,9 @@ manage_db_add_constraints (const gchar *name)
sql ("ALTER TABLE scap2.cpes"
" ADD UNIQUE (uuid);");

sql ("ALTER TABLE scap2.cpe_details"
" ADD UNIQUE (cpe_id);");

sql ("ALTER TABLE scap2.affected_products"
" ALTER cve SET NOT NULL,"
" ALTER cpe SET NOT NULL,"
Expand Down
118 changes: 108 additions & 10 deletions src/manage_sql_secinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,25 @@ DEF_ACCESS (cpe_info_iterator_cve_refs, GET_ITERATOR_COLUMN_COUNT + 4);
*/
DEF_ACCESS (cpe_info_iterator_nvd_id, GET_ITERATOR_COLUMN_COUNT + 5);

/**
* @brief Get the XML details / raw data for a given CPE ID.
*
* @param[in] cpe_id ID of the CPE to get the raw XML of.
*
* @return newly allocated XML details string
*/
char *
cpe_details_xml (const char *cpe_id) {
gchar *quoted_cpe_id, *details_xml;
quoted_cpe_id = sql_quote (cpe_id);
details_xml = sql_string ("SELECT details_xml"
" FROM scap.cpe_details"
" WHERE cpe_id = '%s'",
cpe_id);
g_free (quoted_cpe_id);
return details_xml;
}


/* CVE data. */

Expand Down Expand Up @@ -1841,6 +1860,20 @@ update_cert_bund_advisories (int last_cert_update)

/* SCAP update: CPEs. */

static gchar *
decode_and_quote_cpe_name (const char *name)
{
gchar *name_decoded, *name_tilde, *quoted_name;

name_decoded = g_uri_unescape_string (name, NULL);
name_tilde = string_replace (name_decoded,
"~", "%7E", "%7e", NULL);
g_free (name_decoded);
quoted_name = sql_quote (name_tilde);
g_free (name_tilde);
return quoted_name;
}

/**
* @brief Insert a SCAP CPE.
*
Expand All @@ -1857,7 +1890,6 @@ insert_scap_cpe (inserts_t *inserts, element_t cpe_item, element_t item_metadata
{
gchar *name, *status, *deprecated, *nvd_id;
gchar *quoted_name, *quoted_title, *quoted_status, *quoted_nvd_id;
gchar *name_decoded, *name_tilde;
element_t title;
int first;

Expand Down Expand Up @@ -1928,13 +1960,8 @@ insert_scap_cpe (inserts_t *inserts, element_t cpe_item, element_t item_metadata
title = element_next (title);
}

name_decoded = g_uri_unescape_string (name, NULL);
quoted_name = decode_and_quote_cpe_name (name);
g_free (name);
name_tilde = string_replace (name_decoded,
"~", "%7E", "%7e", NULL);
g_free (name_decoded);
quoted_name = sql_quote (name_tilde);
g_free (name_tilde);
quoted_status = sql_quote (status);
g_free (status);
quoted_nvd_id = sql_quote (nvd_id);
Expand Down Expand Up @@ -1965,6 +1992,51 @@ insert_scap_cpe (inserts_t *inserts, element_t cpe_item, element_t item_metadata
return 0;
}

/**
* @brief Insert a SCAP CPE.
*
* @param[in] inserts Pointer to SQL buffer.
* @param[in] cpe_item CPE item XML element.
* @param[in] item_metadata Item's metadata element.
* @param[in] modification_time Modification time of item.
*
* @return 0 success, -1 error.
*/
static int
insert_scap_cpe_details (inserts_t *inserts, element_t cpe_item)
{
gchar *name, *details_xml, *quoted_name, *quoted_details_xml;
int first;

assert (inserts);

name = element_attribute (cpe_item, "name");
if (name == NULL)
{
g_warning ("%s: name missing", __func__);
return -1;
}

quoted_name = decode_and_quote_cpe_name (name);
g_free (name);

details_xml = element_to_string (cpe_item);
quoted_details_xml = sql_quote (details_xml);
g_free (details_xml);

first = inserts_check_size (inserts);

g_string_append_printf (inserts->statement,
"%s ('%s', '%s')",
first ? "" : ",",
quoted_name,
quoted_details_xml);

inserts->current_chunk_size++;

return 0;
}

/**
* @brief Update SCAP CPEs from a file.
*
Expand All @@ -1979,7 +2051,7 @@ update_scap_cpes_from_file (const gchar *path)
element_t element, cpe_list, cpe_item;
gchar *xml;
gsize xml_len;
inserts_t inserts;
inserts_t inserts, details_inserts;

g_debug ("%s: parsing %s", __func__, path);

Expand Down Expand Up @@ -2064,11 +2136,37 @@ update_scap_cpes_from_file (const gchar *path)
cpe_item = element_next (cpe_item);
}

inserts_run (&inserts);
sql_commit ();

// Extract and save details XML.
inserts_init (&details_inserts,
CPE_MAX_CHUNK_SIZE,
"INSERT INTO scap2.cpe_details"
" (cpe_id, details_xml)"
" VALUES",
" ON CONFLICT (cpe_id) DO UPDATE"
" SET details_xml = EXCLUDED.details_xml");
cpe_item = element_first_child (cpe_list);
while (cpe_item)
{
if (strcmp (element_name (cpe_item), "cpe-item"))
{
cpe_item = element_next (cpe_item);
continue;
}

if (insert_scap_cpe_details (&details_inserts, cpe_item))
goto fail;
cpe_item = element_next (cpe_item);
}

element_free (element);

inserts_run (&inserts);
sql_begin_immediate();
inserts_run (&details_inserts);
sql_commit();

sql_commit ();
return 0;

fail:
Expand Down

0 comments on commit 477a4cb

Please sign in to comment.