From beb48f1b9fbc7bdd44b98db92359d2c8abdd82e5 Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Fri, 3 Sep 2021 16:05:03 +0200 Subject: [PATCH 01/13] Check if config should by synced to a new function The function sync_config_with_feed now checks whether a config file has to be synced with the new function should_sync_config_from_path. This will allow a general check if any configs need to be updated later. --- src/manage_configs.c | 70 +++++++++++++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 21 deletions(-) diff --git a/src/manage_configs.c b/src/manage_configs.c index 520305a72..0946ac1c9 100644 --- a/src/manage_configs.c +++ b/src/manage_configs.c @@ -300,17 +300,19 @@ create_config_from_file (const gchar *path) } /** - * @brief Sync a single config with the feed. + * @brief Gets if a config must be synced a file path in the feed. * - * @param[in] path Path to config XML in feed. + * @param[in] path Path to config XML in feed. + * @param[out] config Config row id if it already exists, 0 if config is new. + * + * @return 1 if config should be synced, 0 otherwise */ -static void -sync_config_with_feed (const gchar *path) +static int +should_sync_config_from_path (const char *path, config_t *config) { gchar **split, *full_path, *uuid; - config_t config; - g_debug ("%s: considering %s", __func__, path); + *config = 0; split = g_regex_split_simple (/* Full-and-Fast--daba56c8-73ec-11df-a475-002264764cea.xml */ @@ -321,45 +323,71 @@ sync_config_with_feed (const gchar *path) { g_strfreev (split); g_warning ("%s: path not in required format: %s", __func__, path); - return; + return 0; } - full_path = g_build_filename (feed_dir_configs (), path, NULL); - uuid = g_strdup_printf ("%s-%s-%s-%s-%s", split[1], split[2], split[3], split[4], split[5]); g_strfreev (split); - if (find_config_no_acl (uuid, &config) == 0 - && config) + if (find_config_no_acl (uuid, config) == 0 + && *config) { + full_path = g_build_filename (feed_dir_configs (), path, NULL); + g_free (uuid); g_debug ("%s: considering %s for update", __func__, path); - if (config_updated_in_feed (config, full_path)) + if (config_updated_in_feed (*config, full_path)) { - g_debug ("%s: updating %s", __func__, path); - update_config_from_file (config, full_path); + return 1; } g_free (full_path); - return; + return 0; } - if (find_trash_config_no_acl (uuid, &config) == 0 - && config) + if (find_trash_config_no_acl (uuid, config) == 0 + && *config) { g_free (uuid); - return; + *config = 0; + return 0; } g_free (uuid); + *config = 0; + return 1; +} - g_debug ("%s: adding %s", __func__, path); +/** + * @brief Sync a single config with the feed. + * + * @param[in] path Path to config XML in feed. + */ +static void +sync_config_with_feed (const gchar *path) +{ + config_t config; - create_config_from_file (full_path); + g_debug ("%s: considering %s", __func__, path); - g_free (full_path); + if (should_sync_config_from_path (path, &config)) + { + gchar *full_path; + full_path = g_build_filename (feed_dir_configs (), path, NULL); + switch (config) + { + case 0: + g_debug ("%s: adding %s", __func__, path); + create_config_from_file (full_path); + break; + default: + g_debug ("%s: updating %s", __func__, path); + update_config_from_file (config, full_path); + } + g_free (full_path); + } } /** From a9da48aeff91b9604c7bf9dba2428b15bdd06d2f Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Fri, 3 Sep 2021 16:50:57 +0200 Subject: [PATCH 02/13] Move report format and port list sync needed tests The test if a sync is necessary for a report format or port list is moved to a separate function like it was done for configs. --- src/manage_port_lists.c | 72 +++++++++++++++++++++++++----------- src/manage_report_formats.c | 74 +++++++++++++++++++++++++------------ 2 files changed, 101 insertions(+), 45 deletions(-) diff --git a/src/manage_port_lists.c b/src/manage_port_lists.c index 2d0d7f8d8..bdaa6cbb0 100644 --- a/src/manage_port_lists.c +++ b/src/manage_port_lists.c @@ -235,20 +235,22 @@ update_port_list_from_file (port_list_t port_list, const gchar *path) } /** - * @brief Sync a single port_list with the feed. + * @brief Gets if a port list must be synced to a file path in the feed. * - * @param[in] path Path to port_list XML in feed. + * @param[in] path Path to port list XML in feed. + * @param[out] port_list Port list row id if it already exists, 0 if new. + * + * @return 1 if port list should be synced, 0 otherwise */ -static void -sync_port_list_with_feed (const gchar *path) +static int +should_sync_port_list_from_path (const char *path, port_list_t *port_list) { gchar **split, *full_path, *uuid; - port_list_t port_list; - g_debug ("%s: considering %s", __func__, path); + *port_list = 0; split = g_regex_split_simple - (/* All-TCP--daba56c8-73ec-11df-a475-002264764cea.xml */ + (/* Full-and-Fast--daba56c8-73ec-11df-a475-002264764cea.xml */ "^.*([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{12}).xml$", path, 0, 0); @@ -256,45 +258,71 @@ sync_port_list_with_feed (const gchar *path) { g_strfreev (split); g_warning ("%s: path not in required format: %s", __func__, path); - return; + return 0; } - full_path = g_build_filename (feed_dir_port_lists (), path, NULL); - uuid = g_strdup_printf ("%s-%s-%s-%s-%s", split[1], split[2], split[3], split[4], split[5]); g_strfreev (split); - if (find_port_list_no_acl (uuid, &port_list) == 0 - && port_list) + if (find_port_list_no_acl (uuid, port_list) == 0 + && *port_list) { + full_path = g_build_filename (feed_dir_port_lists (), path, NULL); + g_free (uuid); g_debug ("%s: considering %s for update", __func__, path); - if (port_list_updated_in_feed (port_list, full_path)) + if (port_list_updated_in_feed (*port_list, full_path)) { - g_debug ("%s: updating %s", __func__, path); - update_port_list_from_file (port_list, full_path); + return 1; } g_free (full_path); - return; + return 0; } - if (find_trash_port_list_no_acl (uuid, &port_list) == 0 - && port_list) + if (find_trash_port_list_no_acl (uuid, port_list) == 0 + && *port_list) { g_free (uuid); - return; + *port_list = 0; + return 0; } g_free (uuid); + *port_list = 0; + return 1; +} - g_debug ("%s: adding %s", __func__, path); +/** + * @brief Sync a single port_list with the feed. + * + * @param[in] path Path to port_list XML in feed. + */ +static void +sync_port_list_with_feed (const gchar *path) +{ + port_list_t port_list; - create_port_list_from_file (full_path); + g_debug ("%s: considering %s", __func__, path); - g_free (full_path); + if (should_sync_port_list_from_path (path, &port_list)) + { + gchar *full_path; + full_path = g_build_filename (feed_dir_port_lists (), path, NULL); + switch (port_list) + { + case 0: + g_debug ("%s: adding %s", __func__, path); + create_port_list_from_file (full_path); + break; + default: + g_debug ("%s: updating %s", __func__, path); + update_port_list_from_file (port_list, full_path); + } + g_free (full_path); + } } /** diff --git a/src/manage_report_formats.c b/src/manage_report_formats.c index acfa13ea4..ef40a92e6 100644 --- a/src/manage_report_formats.c +++ b/src/manage_report_formats.c @@ -594,21 +594,23 @@ create_report_format_from_file (const gchar *path) } /** - * @brief Sync a single report format with the feed. + * @brief Gets if a report format must be synced to a file path in the feed. * - * @param[in] path Path to report format XML in feed. + * @param[in] path Path to report format XML in feed. + * @param[out] report_format Report format id if it already exists, 0 if new. + * + * @return 1 if report format should be synced, 0 otherwise */ -static void -sync_report_format_with_feed (const gchar *path) +static int +should_sync_report_format_from_path (const char *path, + report_format_t *report_format) { gchar **split, *full_path, *uuid; - report_format_t report_format; - g_debug ("%s: considering %s", __func__, path); + *report_format = 0; split = g_regex_split_simple - (/* Format is: [AnYtHiNg]uuid.xml - * For example: PDF--daba56c8-73ec-11df-a475-002264764cea.xml */ + (/* Full-and-Fast--daba56c8-73ec-11df-a475-002264764cea.xml */ "^.*([0-9a-f]{8})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{4})-([0-9a-f]{12}).xml$", path, 0, 0); @@ -616,45 +618,71 @@ sync_report_format_with_feed (const gchar *path) { g_strfreev (split); g_warning ("%s: path not in required format: %s", __func__, path); - return; + return 0; } - full_path = g_build_filename (feed_dir_report_formats (), path, NULL); - uuid = g_strdup_printf ("%s-%s-%s-%s-%s", split[1], split[2], split[3], split[4], split[5]); g_strfreev (split); - if (find_report_format_no_acl (uuid, &report_format) == 0 - && report_format) + if (find_report_format_no_acl (uuid, report_format) == 0 + && *report_format) { + full_path = g_build_filename (feed_dir_report_formats (), path, NULL); + g_free (uuid); g_debug ("%s: considering %s for update", __func__, path); - if (report_format_updated_in_feed (report_format, full_path)) + if (report_format_updated_in_feed (*report_format, full_path)) { - g_debug ("%s: updating %s", __func__, path); - update_report_format_from_file (report_format, full_path); + return 1; } g_free (full_path); - return; + return 0; } - if (find_trash_report_format_no_acl (uuid, &report_format) == 0 - && report_format) + if (find_trash_report_format_no_acl (uuid, report_format) == 0 + && *report_format) { g_free (uuid); - return; + *report_format = 0; + return 0; } g_free (uuid); + *report_format = 0; + return 1; +} - g_debug ("%s: adding %s", __func__, path); +/** + * @brief Sync a single report format with the feed. + * + * @param[in] path Path to report format XML in feed. + */ +static void +sync_report_format_with_feed (const gchar *path) +{ + report_format_t report_format; - create_report_format_from_file (full_path); + g_debug ("%s: considering %s", __func__, path); - g_free (full_path); + if (should_sync_report_format_from_path (path, &report_format)) + { + gchar *full_path; + full_path = g_build_filename (feed_dir_report_formats (), path, NULL); + switch (report_format) + { + case 0: + g_debug ("%s: adding %s", __func__, path); + create_report_format_from_file (full_path); + break; + default: + g_debug ("%s: updating %s", __func__, path); + update_report_format_from_file (report_format, full_path); + } + g_free (full_path); + } } /** From 7a7cb823c5c31ccec9bd71513fc48fd165bd8150 Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Mon, 6 Sep 2021 09:07:32 +0200 Subject: [PATCH 03/13] Open data object feed dirs in separate functions The feed directories for configs, port lists and report formats are now opened in a separate function which can later be reused for a quick feed status check. --- src/manage_configs.c | 69 ++++++++++++++++++++++++++++--------- src/manage_port_lists.c | 59 +++++++++++++++++++++++-------- src/manage_report_formats.c | 59 +++++++++++++++++++++++-------- 3 files changed, 142 insertions(+), 45 deletions(-) diff --git a/src/manage_configs.c b/src/manage_configs.c index 0946ac1c9..49cb0850f 100644 --- a/src/manage_configs.c +++ b/src/manage_configs.c @@ -391,26 +391,30 @@ sync_config_with_feed (const gchar *path) } /** - * @brief Sync all configs with the feed. - * - * Create configs that exists in the feed but not in the db. - * Update configs in the db that have changed on the feed. - * Do nothing to configs in db that have been removed from the feed. + * @brief Open the configs feed directory if it is available and the + * feed owner is set. Also set the current user to the feed owner. + * + * The sync will be skipped if the feed directory does not exist or + * the feed owner is not set. + * For configs the NVTs also have to exist. + * + * @param[out] dir The directory as GDir if available and feed owner is set, + * NULL otherwise. * - * @return 0 success, -1 error. + * @return 0 success, 1 no feed directory or owner, 2 NVTs missing, -1 error */ -int -sync_configs_with_feed () +static int +try_open_configs_feed_dir (GDir **dir) { GError *error; - GDir *dir; - const gchar *config_path; gchar *nvt_feed_version; - + + *dir = NULL; + /* Test if base feed directory exists */ if (configs_feed_dir_exists () == FALSE) - return 0; + return 1; /* Only sync if NVTs are up to date. */ @@ -418,7 +422,7 @@ sync_configs_with_feed () if (nvt_feed_version == NULL) { g_debug ("%s: no NVTs so not syncing from feed", __func__); - return 0; + return 2; } g_free (nvt_feed_version); @@ -431,21 +435,21 @@ sync_configs_with_feed () { /* Sync is disabled by having no "Feed Import Owner". */ g_debug ("%s: no Feed Import Owner so not syncing from feed", __func__); - return 0; + return 1; } current_credentials.username = user_name (current_credentials.uuid); if (current_credentials.username == NULL) { g_debug ("%s: unknown Feed Import Owner so not syncing from feed", __func__); - return 0; + return 1; } /* Open feed import directory. */ error = NULL; - dir = g_dir_open (feed_dir_configs (), 0, &error); - if (dir == NULL) + *dir = g_dir_open (feed_dir_configs (), 0, &error); + if (*dir == NULL) { g_warning ("%s: Failed to open directory '%s': %s", __func__, feed_dir_configs (), error->message); @@ -456,6 +460,37 @@ sync_configs_with_feed () current_credentials.username = NULL; return -1; } + return 0; +} + +/** + * @brief Sync all configs with the feed. + * + * Create configs that exists in the feed but not in the db. + * Update configs in the db that have changed on the feed. + * Do nothing to configs in db that have been removed from the feed. + * + * @return 0 success, -1 error. + */ +int +sync_configs_with_feed () +{ + GDir *dir; + const gchar *config_path; + + switch (try_open_configs_feed_dir (&dir)) + { + case 0: + // Successfully opened directory + break; + case 1: + case 2: + // No feed directory, feed owner, or NVTs + return 0; + default: + // Error + return -1; + } /* Sync each file in the directory. */ diff --git a/src/manage_port_lists.c b/src/manage_port_lists.c index bdaa6cbb0..5bd42584f 100644 --- a/src/manage_port_lists.c +++ b/src/manage_port_lists.c @@ -326,20 +326,21 @@ sync_port_list_with_feed (const gchar *path) } /** - * @brief Sync all port lists with the feed. - * - * Create port lists that exists in the feed but not in the db. - * Update port lists in the db that have changed on the feed. - * Do nothing to db port lists that have been removed from the feed. + * @brief Open the port lists feed directory if it is available and the + * feed owner is set. Also set the current user to the feed owner. + * + * The sync will be skipped if the feed directory does not exist or + * the feed owner is not set. + * + * @param[out] dir The directory as GDir if available and feed owner is set, + * NULL otherwise. * - * @return 0 success, -1 error. + * @return 0 success, 1 no feed directory or owner, -1 error */ -int -sync_port_lists_with_feed () +static int +try_open_port_lists_feed_dir (GDir **dir) { GError *error; - GDir *dir; - const gchar *port_list_path; /* Test if base feed directory exists */ @@ -355,21 +356,21 @@ sync_port_lists_with_feed () { /* Sync is disabled by having no "Feed Import Owner". */ g_debug ("%s: no Feed Import Owner so not syncing from feed", __func__); - return 0; + return 1; } current_credentials.username = user_name (current_credentials.uuid); if (current_credentials.username == NULL) { g_debug ("%s: unknown Feed Import Owner so not syncing from feed", __func__); - return 0; + return 1; } /* Open feed import directory. */ error = NULL; - dir = g_dir_open (feed_dir_port_lists (), 0, &error); - if (dir == NULL) + *dir = g_dir_open (feed_dir_port_lists (), 0, &error); + if (*dir == NULL) { g_warning ("%s: Failed to open directory '%s': %s", __func__, feed_dir_port_lists (), error->message); @@ -380,6 +381,36 @@ sync_port_lists_with_feed () current_credentials.username = NULL; return -1; } + return 0; +} + +/** + * @brief Sync all port lists with the feed. + * + * Create port lists that exists in the feed but not in the db. + * Update port lists in the db that have changed on the feed. + * Do nothing to db port lists that have been removed from the feed. + * + * @return 0 success, -1 error. + */ +int +sync_port_lists_with_feed () +{ + GDir *dir; + const gchar *port_list_path; + + switch (try_open_port_lists_feed_dir (&dir)) + { + case 0: + // Successfully opened directory + break; + case 1: + // No feed directory or feed owner + return 0; + default: + // Error + return -1; + } /* Sync each file in the directory. */ diff --git a/src/manage_report_formats.c b/src/manage_report_formats.c index ef40a92e6..561eb6e64 100644 --- a/src/manage_report_formats.c +++ b/src/manage_report_formats.c @@ -686,20 +686,21 @@ sync_report_format_with_feed (const gchar *path) } /** - * @brief Sync all report formats with the feed. - * - * Create report formats that exists in the feed but not in the db. - * Update report formats in the db that have changed on the feed. - * Do nothing to report formats in db that have been removed from the feed. + * @brief Open the report formats feed directory if it is available and the + * feed owner is set. Also set the current user to the feed owner. + * + * The sync will be skipped if the feed directory does not exist or + * the feed owner is not set. + * + * @param[out] dir The directory as GDir if available and feed owner is set, + * NULL otherwise. * - * @return 0 success, -1 error. + * @return 0 success, 1 no feed directory or owner, -1 error */ -int -sync_report_formats_with_feed () +static int +try_open_report_formats_feed_dir (GDir **dir) { GError *error; - GDir *dir; - const gchar *report_format_path; /* Test if base feed directory exists */ @@ -715,7 +716,7 @@ sync_report_formats_with_feed () { /* Sync is disabled by having no "Feed Import Owner". */ g_debug ("%s: no Feed Import Owner so not syncing from feed", __func__); - return 0; + return 1; } current_credentials.username = user_name (current_credentials.uuid); @@ -723,14 +724,14 @@ sync_report_formats_with_feed () { g_debug ("%s: unknown Feed Import Owner so not syncing from feed", __func__); - return 0; + return 1; } /* Open feed import directory. */ error = NULL; - dir = g_dir_open (feed_dir_report_formats (), 0, &error); - if (dir == NULL) + *dir = g_dir_open (feed_dir_report_formats (), 0, &error); + if (*dir == NULL) { g_warning ("%s: Failed to open directory '%s': %s", __func__, feed_dir_report_formats (), error->message); @@ -741,6 +742,36 @@ sync_report_formats_with_feed () current_credentials.username = NULL; return -1; } + return 0; +} + +/** + * @brief Sync all report formats with the feed. + * + * Create report formats that exists in the feed but not in the db. + * Update report formats in the db that have changed on the feed. + * Do nothing to report formats in db that have been removed from the feed. + * + * @return 0 success, -1 error. + */ +int +sync_report_formats_with_feed () +{ + GDir *dir; + const gchar *report_format_path; + + switch (try_open_report_formats_feed_dir (&dir)) + { + case 0: + // Successfully opened directory + break; + case 1: + // No feed directory or feed owner + return 0; + default: + // Error + return -1; + } /* Sync each file in the directory. */ From e41dc4f2e6aabe63f59f4fc33edd89fd3b00f495 Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Mon, 6 Sep 2021 09:35:07 +0200 Subject: [PATCH 04/13] Make setting user optional when opening feed dirs Setting the current user is now optional when opening the feed directories for data objects. --- src/manage_configs.c | 31 +++++++++++++++++++++++-------- src/manage_port_lists.c | 37 +++++++++++++++++++++++++------------ src/manage_report_formats.c | 37 +++++++++++++++++++++++++------------ 3 files changed, 73 insertions(+), 32 deletions(-) diff --git a/src/manage_configs.c b/src/manage_configs.c index 49cb0850f..84b37bf75 100644 --- a/src/manage_configs.c +++ b/src/manage_configs.c @@ -392,7 +392,8 @@ sync_config_with_feed (const gchar *path) /** * @brief Open the configs feed directory if it is available and the - * feed owner is set. Also set the current user to the feed owner. + * feed owner is set. + * Optionally set the current user to the feed owner on success. * * The sync will be skipped if the feed directory does not exist or * the feed owner is not set. @@ -400,12 +401,14 @@ sync_config_with_feed (const gchar *path) * * @param[out] dir The directory as GDir if available and feed owner is set, * NULL otherwise. + * @param[in] set_current_user Whether to set current user to feed owner. * * @return 0 success, 1 no feed directory or owner, 2 NVTs missing, -1 error */ static int -try_open_configs_feed_dir (GDir **dir) +try_open_configs_feed_dir (GDir **dir, gboolean set_current_user) { + char *feed_owner_uuid, *feed_owner_name; GError *error; gchar *nvt_feed_version; @@ -428,18 +431,18 @@ try_open_configs_feed_dir (GDir **dir) /* Setup owner. */ - setting_value (SETTING_UUID_FEED_IMPORT_OWNER, ¤t_credentials.uuid); + setting_value (SETTING_UUID_FEED_IMPORT_OWNER, &feed_owner_uuid); - if (current_credentials.uuid == NULL - || strlen (current_credentials.uuid) == 0) + if (feed_owner_uuid == NULL + || strlen (feed_owner_uuid) == 0) { /* Sync is disabled by having no "Feed Import Owner". */ g_debug ("%s: no Feed Import Owner so not syncing from feed", __func__); return 1; } - current_credentials.username = user_name (current_credentials.uuid); - if (current_credentials.username == NULL) + feed_owner_name = user_name (feed_owner_uuid); + if (feed_owner_name == NULL) { g_debug ("%s: unknown Feed Import Owner so not syncing from feed", __func__); return 1; @@ -460,6 +463,18 @@ try_open_configs_feed_dir (GDir **dir) current_credentials.username = NULL; return -1; } + + if (set_current_user) + { + current_credentials.uuid = feed_owner_uuid; + current_credentials.username = feed_owner_name; + } + else + { + free (feed_owner_uuid); + free (feed_owner_name); + } + return 0; } @@ -478,7 +493,7 @@ sync_configs_with_feed () GDir *dir; const gchar *config_path; - switch (try_open_configs_feed_dir (&dir)) + switch (try_open_configs_feed_dir (&dir, TRUE)) { case 0: // Successfully opened directory diff --git a/src/manage_port_lists.c b/src/manage_port_lists.c index 5bd42584f..84199356c 100644 --- a/src/manage_port_lists.c +++ b/src/manage_port_lists.c @@ -327,19 +327,22 @@ sync_port_list_with_feed (const gchar *path) /** * @brief Open the port lists feed directory if it is available and the - * feed owner is set. Also set the current user to the feed owner. + * feed owner is set. + * Optionally set the current user to the feed owner on success. * * The sync will be skipped if the feed directory does not exist or * the feed owner is not set. * * @param[out] dir The directory as GDir if available and feed owner is set, * NULL otherwise. + * @param[in] set_current_user Whether to set current user to feed owner. * * @return 0 success, 1 no feed directory or owner, -1 error */ static int -try_open_port_lists_feed_dir (GDir **dir) +try_open_port_lists_feed_dir (GDir **dir, gboolean set_current_user) { + char *feed_owner_uuid, *feed_owner_name; GError *error; /* Test if base feed directory exists */ @@ -349,18 +352,18 @@ try_open_port_lists_feed_dir (GDir **dir) /* Setup owner. */ - setting_value (SETTING_UUID_FEED_IMPORT_OWNER, ¤t_credentials.uuid); + setting_value (SETTING_UUID_FEED_IMPORT_OWNER, &feed_owner_uuid); - if (current_credentials.uuid == NULL - || strlen (current_credentials.uuid) == 0) + if (feed_owner_uuid == NULL + || strlen (feed_owner_uuid) == 0) { /* Sync is disabled by having no "Feed Import Owner". */ g_debug ("%s: no Feed Import Owner so not syncing from feed", __func__); return 1; } - current_credentials.username = user_name (current_credentials.uuid); - if (current_credentials.username == NULL) + feed_owner_name = user_name (feed_owner_uuid); + if (feed_owner_name == NULL) { g_debug ("%s: unknown Feed Import Owner so not syncing from feed", __func__); return 1; @@ -375,12 +378,22 @@ try_open_port_lists_feed_dir (GDir **dir) g_warning ("%s: Failed to open directory '%s': %s", __func__, feed_dir_port_lists (), error->message); g_error_free (error); - g_free (current_credentials.uuid); - g_free (current_credentials.username); - current_credentials.uuid = NULL; - current_credentials.username = NULL; + free (feed_owner_uuid); + free (feed_owner_name); return -1; } + + if (set_current_user) + { + current_credentials.uuid = feed_owner_uuid; + current_credentials.username = feed_owner_name; + } + else + { + free (feed_owner_uuid); + free (feed_owner_name); + } + return 0; } @@ -399,7 +412,7 @@ sync_port_lists_with_feed () GDir *dir; const gchar *port_list_path; - switch (try_open_port_lists_feed_dir (&dir)) + switch (try_open_port_lists_feed_dir (&dir, TRUE)) { case 0: // Successfully opened directory diff --git a/src/manage_report_formats.c b/src/manage_report_formats.c index 561eb6e64..e3c5c4575 100644 --- a/src/manage_report_formats.c +++ b/src/manage_report_formats.c @@ -687,19 +687,22 @@ sync_report_format_with_feed (const gchar *path) /** * @brief Open the report formats feed directory if it is available and the - * feed owner is set. Also set the current user to the feed owner. + * feed owner is set. + * Optionally set the current user to the feed owner on success. * * The sync will be skipped if the feed directory does not exist or * the feed owner is not set. * * @param[out] dir The directory as GDir if available and feed owner is set, * NULL otherwise. + * @param[in] set_current_user Whether to set current user to feed owner. * * @return 0 success, 1 no feed directory or owner, -1 error */ static int -try_open_report_formats_feed_dir (GDir **dir) +try_open_report_formats_feed_dir (GDir **dir, gboolean set_current_user) { + char *feed_owner_uuid, *feed_owner_name; GError *error; /* Test if base feed directory exists */ @@ -709,18 +712,18 @@ try_open_report_formats_feed_dir (GDir **dir) /* Setup owner. */ - setting_value (SETTING_UUID_FEED_IMPORT_OWNER, ¤t_credentials.uuid); + setting_value (SETTING_UUID_FEED_IMPORT_OWNER, &feed_owner_uuid); - if (current_credentials.uuid == NULL - || strlen (current_credentials.uuid) == 0) + if (feed_owner_uuid == NULL + || strlen (feed_owner_uuid) == 0) { /* Sync is disabled by having no "Feed Import Owner". */ g_debug ("%s: no Feed Import Owner so not syncing from feed", __func__); return 1; } - current_credentials.username = user_name (current_credentials.uuid); - if (current_credentials.username == NULL) + feed_owner_name = user_name (feed_owner_uuid); + if (feed_owner_name == NULL) { g_debug ("%s: unknown Feed Import Owner so not syncing from feed", __func__); @@ -736,12 +739,22 @@ try_open_report_formats_feed_dir (GDir **dir) g_warning ("%s: Failed to open directory '%s': %s", __func__, feed_dir_report_formats (), error->message); g_error_free (error); - g_free (current_credentials.uuid); - g_free (current_credentials.username); - current_credentials.uuid = NULL; - current_credentials.username = NULL; + free (feed_owner_uuid); + free (feed_owner_name); return -1; } + + if (set_current_user) + { + current_credentials.uuid = feed_owner_uuid; + current_credentials.username = feed_owner_name; + } + else + { + free (feed_owner_uuid); + free (feed_owner_name); + } + return 0; } @@ -760,7 +773,7 @@ sync_report_formats_with_feed () GDir *dir; const gchar *report_format_path; - switch (try_open_report_formats_feed_dir (&dir)) + switch (try_open_report_formats_feed_dir (&dir, TRUE)) { case 0: // Successfully opened directory From 1a5415c05ce1c7d3550b259af66c20bf2f40aa8f Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Mon, 6 Sep 2021 11:08:05 +0200 Subject: [PATCH 05/13] Check if data object sync is needed, add feed lock Before trying to sync the data objects, check if the feed has any updates first. Also acquire the feed lock for updating the data objects to avoid conflicts with manually triggered updates that are to be added. --- src/manage.c | 16 ++++++++++++---- src/manage_configs.c | 23 +++++++++++++++++++++++ src/manage_configs.h | 3 +++ src/manage_port_lists.c | 23 +++++++++++++++++++++++ src/manage_port_lists.h | 3 +++ src/manage_report_formats.c | 24 ++++++++++++++++++++++++ src/manage_report_formats.h | 3 +++ 7 files changed, 91 insertions(+), 4 deletions(-) diff --git a/src/manage.c b/src/manage.c index d3e169607..681a2ebea 100644 --- a/src/manage.c +++ b/src/manage.c @@ -5006,11 +5006,19 @@ manage_sync (sigset_t *sigmask_current, } } - if (try_gvmd_data_sync) + if (try_gvmd_data_sync + && (should_sync_configs () + || should_sync_port_lists () + || should_sync_report_formats ())) { - manage_sync_configs (); - manage_sync_port_lists (); - manage_sync_report_formats (); + if (feed_lockfile_lock (&lockfile) == 0) + { + manage_sync_configs (); + manage_sync_port_lists (); + manage_sync_report_formats (); + + lockfile_unlock (&lockfile); + } } } diff --git a/src/manage_configs.c b/src/manage_configs.c index 84b37bf75..a5d177c64 100644 --- a/src/manage_configs.c +++ b/src/manage_configs.c @@ -545,3 +545,26 @@ manage_sync_configs () { sync_configs_with_feed (); } + +/** + * @brief Checks if the configs should be synced with the feed. + */ +gboolean +should_sync_configs () +{ + GDir *dir; + const gchar *config_path; + config_t config; + + if (try_open_configs_feed_dir (&dir, FALSE)) + return FALSE; + + while ((config_path = g_dir_read_name (dir))) + if (g_str_has_prefix (config_path, ".") == 0 + && strlen (config_path) >= (36 /* UUID */ + strlen (".xml")) + && g_str_has_suffix (config_path, ".xml") + && should_sync_config_from_path (config_path, &config)) + return TRUE; + + return FALSE; +} diff --git a/src/manage_configs.h b/src/manage_configs.h index b6f8e0800..350f7708a 100644 --- a/src/manage_configs.h +++ b/src/manage_configs.h @@ -197,4 +197,7 @@ configs_feed_dir_exists (); void manage_sync_configs (); +gboolean +should_sync_configs (); + #endif /* not _GVMD_MANAGE_CONFIGS_H */ diff --git a/src/manage_port_lists.c b/src/manage_port_lists.c index 84199356c..6ee82d9ab 100644 --- a/src/manage_port_lists.c +++ b/src/manage_port_lists.c @@ -463,3 +463,26 @@ manage_sync_port_lists () { sync_port_lists_with_feed (); } + +/** + * @brief Checks if the port lists should be synced with the feed. + */ +gboolean +should_sync_port_lists () +{ + GDir *dir; + const gchar *port_list_path; + port_list_t port_list; + + if (try_open_port_lists_feed_dir (&dir, FALSE)) + return FALSE; + + while ((port_list_path = g_dir_read_name (dir))) + if (g_str_has_prefix (port_list_path, ".") == 0 + && strlen (port_list_path) >= (36 /* UUID */ + strlen (".xml")) + && g_str_has_suffix (port_list_path, ".xml") + && should_sync_port_list_from_path (port_list_path, &port_list)) + return TRUE; + + return FALSE; +} diff --git a/src/manage_port_lists.h b/src/manage_port_lists.h index a0414020a..3fe0a1db4 100644 --- a/src/manage_port_lists.h +++ b/src/manage_port_lists.h @@ -133,4 +133,7 @@ port_lists_feed_dir_exists (); void manage_sync_port_lists (); +gboolean +should_sync_port_lists (); + #endif /* not _GVMD_MANAGE_PORT_LISTS_H */ diff --git a/src/manage_report_formats.c b/src/manage_report_formats.c index e3c5c4575..898cc5f48 100644 --- a/src/manage_report_formats.c +++ b/src/manage_report_formats.c @@ -824,3 +824,27 @@ manage_sync_report_formats () { sync_report_formats_with_feed (); } + +/** + * @brief Checks if the report formats should be synced with the feed. + */ +gboolean +should_sync_report_formats () +{ + GDir *dir; + const gchar *report_format_path; + report_format_t report_format; + + if (try_open_report_formats_feed_dir (&dir, FALSE)) + return FALSE; + + while ((report_format_path = g_dir_read_name (dir))) + if (g_str_has_prefix (report_format_path, ".") == 0 + && strlen (report_format_path) >= (36 /* UUID */ + strlen (".xml")) + && g_str_has_suffix (report_format_path, ".xml") + && should_sync_report_format_from_path (report_format_path, + &report_format)) + return TRUE; + + return FALSE; +} \ No newline at end of file diff --git a/src/manage_report_formats.h b/src/manage_report_formats.h index 2e0e2dde7..143771b13 100644 --- a/src/manage_report_formats.h +++ b/src/manage_report_formats.h @@ -234,4 +234,7 @@ report_formats_feed_dir_exists (); void manage_sync_report_formats (); +gboolean +should_sync_report_formats (); + #endif /* not _GVMD_MANAGE_REPORT_FORMATS_H */ From 260d73ef699cf55cf1a3199ab93ae2b8b895b4ed Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Mon, 6 Sep 2021 11:46:11 +0200 Subject: [PATCH 06/13] Return expected failures in sync_..._with_feed () The functions sync_configs_with_feed, sync_port_lists_with_feed and sync_report_formats_with_feed will now return postive failure codes if the feed directory or owner does not exist or the NVTs are missing for configs. --- src/manage_configs.c | 13 +++++-------- src/manage_port_lists.c | 12 +++++------- src/manage_report_formats.c | 12 +++++------- src/manage_sql_configs.c | 2 +- src/manage_sql_port_lists.c | 2 +- src/manage_sql_report_formats.c | 2 +- 6 files changed, 18 insertions(+), 25 deletions(-) diff --git a/src/manage_configs.c b/src/manage_configs.c index a5d177c64..2b306c428 100644 --- a/src/manage_configs.c +++ b/src/manage_configs.c @@ -485,26 +485,23 @@ try_open_configs_feed_dir (GDir **dir, gboolean set_current_user) * Update configs in the db that have changed on the feed. * Do nothing to configs in db that have been removed from the feed. * - * @return 0 success, -1 error. + * @return 0 success, 1 no feed directory or owner, 2 NVTs missing, -1 error. */ int sync_configs_with_feed () { + int ret; GDir *dir; const gchar *config_path; - switch (try_open_configs_feed_dir (&dir, TRUE)) + ret = try_open_configs_feed_dir (&dir, TRUE); + switch (ret) { case 0: // Successfully opened directory break; - case 1: - case 2: - // No feed directory, feed owner, or NVTs - return 0; default: - // Error - return -1; + return ret; } /* Sync each file in the directory. */ diff --git a/src/manage_port_lists.c b/src/manage_port_lists.c index 6ee82d9ab..3842bf45a 100644 --- a/src/manage_port_lists.c +++ b/src/manage_port_lists.c @@ -404,25 +404,23 @@ try_open_port_lists_feed_dir (GDir **dir, gboolean set_current_user) * Update port lists in the db that have changed on the feed. * Do nothing to db port lists that have been removed from the feed. * - * @return 0 success, -1 error. + * @return 0 success, 1 no feed directory or owner, -1 error. */ int sync_port_lists_with_feed () { + int ret; GDir *dir; const gchar *port_list_path; - switch (try_open_port_lists_feed_dir (&dir, TRUE)) + ret = try_open_port_lists_feed_dir (&dir, TRUE); + switch (ret) { case 0: // Successfully opened directory break; - case 1: - // No feed directory or feed owner - return 0; default: - // Error - return -1; + return ret; } /* Sync each file in the directory. */ diff --git a/src/manage_report_formats.c b/src/manage_report_formats.c index 898cc5f48..8268ee532 100644 --- a/src/manage_report_formats.c +++ b/src/manage_report_formats.c @@ -765,25 +765,23 @@ try_open_report_formats_feed_dir (GDir **dir, gboolean set_current_user) * Update report formats in the db that have changed on the feed. * Do nothing to report formats in db that have been removed from the feed. * - * @return 0 success, -1 error. + * @return 0 success, 1 no feed directory or owner, -1 error. */ int sync_report_formats_with_feed () { + int ret; GDir *dir; const gchar *report_format_path; - switch (try_open_report_formats_feed_dir (&dir, TRUE)) + ret = try_open_report_formats_feed_dir (&dir, TRUE); + switch (ret) { case 0: // Successfully opened directory break; - case 1: - // No feed directory or feed owner - return 0; default: - // Error - return -1; + return ret; } /* Sync each file in the directory. */ diff --git a/src/manage_sql_configs.c b/src/manage_sql_configs.c index 8689bb2f2..a14267539 100644 --- a/src/manage_sql_configs.c +++ b/src/manage_sql_configs.c @@ -4936,7 +4936,7 @@ check_db_configs () { migrate_predefined_configs (); - if (sync_configs_with_feed ()) + if (sync_configs_with_feed () <= -1) g_warning ("%s: Failed to sync configs with feed", __func__); /* Warn about feed resources in the trash. */ diff --git a/src/manage_sql_port_lists.c b/src/manage_sql_port_lists.c index 42dee462e..b50a997de 100644 --- a/src/manage_sql_port_lists.c +++ b/src/manage_sql_port_lists.c @@ -2596,7 +2596,7 @@ check_db_port_lists () { migrate_predefined_port_lists (); - if (sync_port_lists_with_feed ()) + if (sync_port_lists_with_feed () <= -1) g_warning ("%s: Failed to sync port lists with feed", __func__); /* diff --git a/src/manage_sql_report_formats.c b/src/manage_sql_report_formats.c index 58f9cd656..a156c96b8 100644 --- a/src/manage_sql_report_formats.c +++ b/src/manage_sql_report_formats.c @@ -4553,7 +4553,7 @@ check_db_report_formats () if (migrate_predefined_report_formats ()) return -1; - if (sync_report_formats_with_feed ()) + if (sync_report_formats_with_feed () <= -1) g_warning ("%s: Failed to sync report formats with feed", __func__); if (check_db_trash_report_formats ()) From cf4a405f082c032084477a7c476d80e777fa33bf Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Mon, 6 Sep 2021 11:57:43 +0200 Subject: [PATCH 07/13] Adjust try_open_..._feed_dir return codes The return codes of the functions try_open_configs_feed_dir, try_open_port_lists_feed_dir, try_open_report_formats_feed_dir and the corresponding sync_..._with_feed functions now distinguish between missing feed directory and missing feed owner. --- src/manage_configs.c | 12 +++++++----- src/manage_port_lists.c | 8 ++++---- src/manage_report_formats.c | 8 ++++---- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/manage_configs.c b/src/manage_configs.c index 2b306c428..c54e04dde 100644 --- a/src/manage_configs.c +++ b/src/manage_configs.c @@ -403,7 +403,8 @@ sync_config_with_feed (const gchar *path) * NULL otherwise. * @param[in] set_current_user Whether to set current user to feed owner. * - * @return 0 success, 1 no feed directory or owner, 2 NVTs missing, -1 error + * @return 0 success, 1 no feed directory, 2 no feed owner, 3 NVTs missing, + * -1 error. */ static int try_open_configs_feed_dir (GDir **dir, gboolean set_current_user) @@ -425,7 +426,7 @@ try_open_configs_feed_dir (GDir **dir, gboolean set_current_user) if (nvt_feed_version == NULL) { g_debug ("%s: no NVTs so not syncing from feed", __func__); - return 2; + return 3; } g_free (nvt_feed_version); @@ -438,14 +439,14 @@ try_open_configs_feed_dir (GDir **dir, gboolean set_current_user) { /* Sync is disabled by having no "Feed Import Owner". */ g_debug ("%s: no Feed Import Owner so not syncing from feed", __func__); - return 1; + return 2; } feed_owner_name = user_name (feed_owner_uuid); if (feed_owner_name == NULL) { g_debug ("%s: unknown Feed Import Owner so not syncing from feed", __func__); - return 1; + return 2; } /* Open feed import directory. */ @@ -485,7 +486,8 @@ try_open_configs_feed_dir (GDir **dir, gboolean set_current_user) * Update configs in the db that have changed on the feed. * Do nothing to configs in db that have been removed from the feed. * - * @return 0 success, 1 no feed directory or owner, 2 NVTs missing, -1 error. + * @return 0 success, 1 no feed directory, 2 no feed owner, 3 NVTs missing, + * -1 error. */ int sync_configs_with_feed () diff --git a/src/manage_port_lists.c b/src/manage_port_lists.c index 3842bf45a..62d3436d5 100644 --- a/src/manage_port_lists.c +++ b/src/manage_port_lists.c @@ -337,7 +337,7 @@ sync_port_list_with_feed (const gchar *path) * NULL otherwise. * @param[in] set_current_user Whether to set current user to feed owner. * - * @return 0 success, 1 no feed directory or owner, -1 error + * @return 0 success, 1 no feed directory, 2 no feed owner, -1 error. */ static int try_open_port_lists_feed_dir (GDir **dir, gboolean set_current_user) @@ -348,7 +348,7 @@ try_open_port_lists_feed_dir (GDir **dir, gboolean set_current_user) /* Test if base feed directory exists */ if (port_lists_feed_dir_exists () == FALSE) - return 0; + return 1; /* Setup owner. */ @@ -359,14 +359,14 @@ try_open_port_lists_feed_dir (GDir **dir, gboolean set_current_user) { /* Sync is disabled by having no "Feed Import Owner". */ g_debug ("%s: no Feed Import Owner so not syncing from feed", __func__); - return 1; + return 2; } feed_owner_name = user_name (feed_owner_uuid); if (feed_owner_name == NULL) { g_debug ("%s: unknown Feed Import Owner so not syncing from feed", __func__); - return 1; + return 2; } /* Open feed import directory. */ diff --git a/src/manage_report_formats.c b/src/manage_report_formats.c index 8268ee532..40760cb15 100644 --- a/src/manage_report_formats.c +++ b/src/manage_report_formats.c @@ -697,7 +697,7 @@ sync_report_format_with_feed (const gchar *path) * NULL otherwise. * @param[in] set_current_user Whether to set current user to feed owner. * - * @return 0 success, 1 no feed directory or owner, -1 error + * @return 0 success, 1 no feed directory, 2 no feed owner, -1 error. */ static int try_open_report_formats_feed_dir (GDir **dir, gboolean set_current_user) @@ -708,7 +708,7 @@ try_open_report_formats_feed_dir (GDir **dir, gboolean set_current_user) /* Test if base feed directory exists */ if (report_formats_feed_dir_exists () == FALSE) - return 0; + return 1; /* Setup owner. */ @@ -719,7 +719,7 @@ try_open_report_formats_feed_dir (GDir **dir, gboolean set_current_user) { /* Sync is disabled by having no "Feed Import Owner". */ g_debug ("%s: no Feed Import Owner so not syncing from feed", __func__); - return 1; + return 2; } feed_owner_name = user_name (feed_owner_uuid); @@ -727,7 +727,7 @@ try_open_report_formats_feed_dir (GDir **dir, gboolean set_current_user) { g_debug ("%s: unknown Feed Import Owner so not syncing from feed", __func__); - return 1; + return 2; } /* Open feed import directory. */ From 2c0c22c5c47bb9de52fcea076dfd21eecfd4d236 Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Mon, 6 Sep 2021 16:26:36 +0200 Subject: [PATCH 08/13] Allow to skip timestamp checks in data object sync The functions for syncing configs, port lists and report formats now have a `rebuild` parameter to skip the modification time check to force a rebuild. --- src/manage_configs.c | 24 ++++++++++++++++-------- src/manage_port_lists.c | 24 ++++++++++++++++-------- src/manage_report_formats.c | 21 +++++++++++++++------ 3 files changed, 47 insertions(+), 22 deletions(-) diff --git a/src/manage_configs.c b/src/manage_configs.c index c54e04dde..7b4b108d7 100644 --- a/src/manage_configs.c +++ b/src/manage_configs.c @@ -303,12 +303,14 @@ create_config_from_file (const gchar *path) * @brief Gets if a config must be synced a file path in the feed. * * @param[in] path Path to config XML in feed. + * @param[in] rebuild Whether ignore timestamps to force a rebuild. * @param[out] config Config row id if it already exists, 0 if config is new. * * @return 1 if config should be synced, 0 otherwise */ static int -should_sync_config_from_path (const char *path, config_t *config) +should_sync_config_from_path (const char *path, gboolean rebuild, + config_t *config) { gchar **split, *full_path, *uuid; @@ -332,6 +334,9 @@ should_sync_config_from_path (const char *path, config_t *config) if (find_config_no_acl (uuid, config) == 0 && *config) { + if (rebuild) + return 1; + full_path = g_build_filename (feed_dir_configs (), path, NULL); g_free (uuid); @@ -363,16 +368,17 @@ should_sync_config_from_path (const char *path, config_t *config) /** * @brief Sync a single config with the feed. * - * @param[in] path Path to config XML in feed. + * @param[in] path Path to config XML in feed. + * @param[in] rebuild Whether ignore timestamps to force a rebuild. */ static void -sync_config_with_feed (const gchar *path) +sync_config_with_feed (const gchar *path, gboolean rebuild) { config_t config; g_debug ("%s: considering %s", __func__, path); - if (should_sync_config_from_path (path, &config)) + if (should_sync_config_from_path (path, rebuild, &config)) { gchar *full_path; full_path = g_build_filename (feed_dir_configs (), path, NULL); @@ -486,11 +492,13 @@ try_open_configs_feed_dir (GDir **dir, gboolean set_current_user) * Update configs in the db that have changed on the feed. * Do nothing to configs in db that have been removed from the feed. * + * @param[in] rebuild Whether ignore timestamps to force a rebuild. + * * @return 0 success, 1 no feed directory, 2 no feed owner, 3 NVTs missing, * -1 error. */ int -sync_configs_with_feed () +sync_configs_with_feed (gboolean rebuild) { int ret; GDir *dir; @@ -512,7 +520,7 @@ sync_configs_with_feed () if (g_str_has_prefix (config_path, ".") == 0 && strlen (config_path) >= (36 /* UUID */ + strlen (".xml")) && g_str_has_suffix (config_path, ".xml")) - sync_config_with_feed (config_path); + sync_config_with_feed (config_path, rebuild); /* Cleanup. */ @@ -542,7 +550,7 @@ configs_feed_dir_exists () void manage_sync_configs () { - sync_configs_with_feed (); + sync_configs_with_feed (FALSE); } /** @@ -562,7 +570,7 @@ should_sync_configs () if (g_str_has_prefix (config_path, ".") == 0 && strlen (config_path) >= (36 /* UUID */ + strlen (".xml")) && g_str_has_suffix (config_path, ".xml") - && should_sync_config_from_path (config_path, &config)) + && should_sync_config_from_path (config_path, FALSE, &config)) return TRUE; return FALSE; diff --git a/src/manage_port_lists.c b/src/manage_port_lists.c index 62d3436d5..93dce7273 100644 --- a/src/manage_port_lists.c +++ b/src/manage_port_lists.c @@ -238,12 +238,14 @@ update_port_list_from_file (port_list_t port_list, const gchar *path) * @brief Gets if a port list must be synced to a file path in the feed. * * @param[in] path Path to port list XML in feed. + * @param[in] rebuild Whether ignore timestamps to force a rebuild. * @param[out] port_list Port list row id if it already exists, 0 if new. * * @return 1 if port list should be synced, 0 otherwise */ static int -should_sync_port_list_from_path (const char *path, port_list_t *port_list) +should_sync_port_list_from_path (const char *path, gboolean rebuild, + port_list_t *port_list) { gchar **split, *full_path, *uuid; @@ -267,6 +269,9 @@ should_sync_port_list_from_path (const char *path, port_list_t *port_list) if (find_port_list_no_acl (uuid, port_list) == 0 && *port_list) { + if (rebuild) + return 1; + full_path = g_build_filename (feed_dir_port_lists (), path, NULL); g_free (uuid); @@ -298,16 +303,17 @@ should_sync_port_list_from_path (const char *path, port_list_t *port_list) /** * @brief Sync a single port_list with the feed. * - * @param[in] path Path to port_list XML in feed. + * @param[in] path Path to port_list XML in feed. + * @param[in] rebuild Whether ignore timestamps to force a rebuild. */ static void -sync_port_list_with_feed (const gchar *path) +sync_port_list_with_feed (const gchar *path, gboolean rebuild) { port_list_t port_list; g_debug ("%s: considering %s", __func__, path); - if (should_sync_port_list_from_path (path, &port_list)) + if (should_sync_port_list_from_path (path, rebuild, &port_list)) { gchar *full_path; full_path = g_build_filename (feed_dir_port_lists (), path, NULL); @@ -404,10 +410,12 @@ try_open_port_lists_feed_dir (GDir **dir, gboolean set_current_user) * Update port lists in the db that have changed on the feed. * Do nothing to db port lists that have been removed from the feed. * + * @param[in] rebuild Whether ignore timestamps to force a rebuild. + * * @return 0 success, 1 no feed directory or owner, -1 error. */ int -sync_port_lists_with_feed () +sync_port_lists_with_feed (gboolean rebuild) { int ret; GDir *dir; @@ -429,7 +437,7 @@ sync_port_lists_with_feed () if (g_str_has_prefix (port_list_path, ".") == 0 && strlen (port_list_path) >= (36 /* UUID */ + strlen (".xml")) && g_str_has_suffix (port_list_path, ".xml")) - sync_port_list_with_feed (port_list_path); + sync_port_list_with_feed (port_list_path, rebuild); /* Cleanup. */ @@ -459,7 +467,7 @@ port_lists_feed_dir_exists () void manage_sync_port_lists () { - sync_port_lists_with_feed (); + sync_port_lists_with_feed (FALSE); } /** @@ -479,7 +487,7 @@ should_sync_port_lists () if (g_str_has_prefix (port_list_path, ".") == 0 && strlen (port_list_path) >= (36 /* UUID */ + strlen (".xml")) && g_str_has_suffix (port_list_path, ".xml") - && should_sync_port_list_from_path (port_list_path, &port_list)) + && should_sync_port_list_from_path (port_list_path, FALSE, &port_list)) return TRUE; return FALSE; diff --git a/src/manage_report_formats.c b/src/manage_report_formats.c index 40760cb15..cc5a69857 100644 --- a/src/manage_report_formats.c +++ b/src/manage_report_formats.c @@ -597,12 +597,14 @@ create_report_format_from_file (const gchar *path) * @brief Gets if a report format must be synced to a file path in the feed. * * @param[in] path Path to report format XML in feed. + * @param[in] rebuild Whether ignore timestamps to force a rebuild. * @param[out] report_format Report format id if it already exists, 0 if new. * * @return 1 if report format should be synced, 0 otherwise */ static int should_sync_report_format_from_path (const char *path, + gboolean rebuild, report_format_t *report_format) { gchar **split, *full_path, *uuid; @@ -627,6 +629,9 @@ should_sync_report_format_from_path (const char *path, if (find_report_format_no_acl (uuid, report_format) == 0 && *report_format) { + if (rebuild) + return 1; + full_path = g_build_filename (feed_dir_report_formats (), path, NULL); g_free (uuid); @@ -658,16 +663,17 @@ should_sync_report_format_from_path (const char *path, /** * @brief Sync a single report format with the feed. * - * @param[in] path Path to report format XML in feed. + * @param[in] path Path to report format XML in feed. + * @param[in] rebuild Whether ignore timestamps to force a rebuild. */ static void -sync_report_format_with_feed (const gchar *path) +sync_report_format_with_feed (const gchar *path, gboolean rebuild) { report_format_t report_format; g_debug ("%s: considering %s", __func__, path); - if (should_sync_report_format_from_path (path, &report_format)) + if (should_sync_report_format_from_path (path, rebuild, &report_format)) { gchar *full_path; full_path = g_build_filename (feed_dir_report_formats (), path, NULL); @@ -765,10 +771,12 @@ try_open_report_formats_feed_dir (GDir **dir, gboolean set_current_user) * Update report formats in the db that have changed on the feed. * Do nothing to report formats in db that have been removed from the feed. * + * @param[in] rebuild Whether ignore timestamps to force a rebuild. + * * @return 0 success, 1 no feed directory or owner, -1 error. */ int -sync_report_formats_with_feed () +sync_report_formats_with_feed (gboolean rebuild) { int ret; GDir *dir; @@ -790,7 +798,7 @@ sync_report_formats_with_feed () if (g_str_has_prefix (report_format_path, ".") == 0 && strlen (report_format_path) >= (36 /* UUID */ + strlen (".xml")) && g_str_has_suffix (report_format_path, ".xml")) - sync_report_format_with_feed (report_format_path); + sync_report_format_with_feed (report_format_path, rebuild); /* Cleanup. */ @@ -820,7 +828,7 @@ report_formats_feed_dir_exists () void manage_sync_report_formats () { - sync_report_formats_with_feed (); + sync_report_formats_with_feed (FALSE); } /** @@ -841,6 +849,7 @@ should_sync_report_formats () && strlen (report_format_path) >= (36 /* UUID */ + strlen (".xml")) && g_str_has_suffix (report_format_path, ".xml") && should_sync_report_format_from_path (report_format_path, + FALSE, &report_format)) return TRUE; From 8d757d7c9dd124b30d66c779ed2697c118ecc125 Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Tue, 7 Sep 2021 09:36:59 +0200 Subject: [PATCH 09/13] Add option --rebuild-gvmd-data This option allows forcing a rebuild of the gvmd data via CLI. --- src/gvmd.c | 33 ++++++++ src/manage.c | 150 ++++++++++++++++++++++++++++++++++++ src/manage.h | 6 ++ src/manage_configs.c | 12 +++ src/manage_configs.h | 3 + src/manage_port_lists.c | 13 +++- src/manage_port_lists.h | 3 + src/manage_report_formats.c | 13 +++- src/manage_report_formats.h | 3 + 9 files changed, 234 insertions(+), 2 deletions(-) diff --git a/src/gvmd.c b/src/gvmd.c index d699db061..c07733574 100644 --- a/src/gvmd.c +++ b/src/gvmd.c @@ -1836,6 +1836,7 @@ gvmd (int argc, char** argv) static gchar *rc_name = NULL; static gchar *relay_mapper = NULL; static gboolean rebuild = FALSE; + static gchar *rebuild_gvmd_data = NULL; static gboolean rebuild_scap = FALSE; static gchar *role = NULL; static gchar *disable = NULL; @@ -2046,6 +2047,12 @@ gvmd (int argc, char** argv) &rebuild, "Remove NVT db, and rebuild it from the scanner.", NULL }, + { "rebuild-gvmd-data", '\0', 0, G_OPTION_ARG_STRING, + &rebuild_gvmd_data, + "Reload all gvmd data objects of a given types from feed." + " The types must be \"all\" or a comma-separated of the following:" + " \"configs\", \"port_lists\" and \"report_formats\"", + "" }, { "rebuild-scap", '\0', 0, G_OPTION_ARG_NONE, &rebuild_scap, "Rebuild all SCAP data.", @@ -2565,6 +2572,32 @@ gvmd (int argc, char** argv) } return EXIT_SUCCESS; } + + if (rebuild_gvmd_data) + { + int ret; + gchar *error_msg; + + error_msg = NULL; + + proctitle_set ("gvmd: --rebuild-gvmd-data"); + + if (option_lock (&lockfile_checking)) + return EXIT_FAILURE; + + ret = manage_rebuild_gvmd_data_from_feed (rebuild_gvmd_data, + log_config, + &database, + &error_msg); + log_config_free (); + if (ret) + { + printf ("Failed to rebuild gvmd data: %s\n", error_msg); + g_free (error_msg); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; + } if (rebuild_scap) { diff --git a/src/manage.c b/src/manage.c index 681a2ebea..bab9bfc85 100644 --- a/src/manage.c +++ b/src/manage.c @@ -5022,6 +5022,156 @@ manage_sync (sigset_t *sigmask_current, } } +#define REBUILD_SWITCH(type) \ + switch (ret) \ + { \ + case 0: \ + g_message ("Rebuilt %s from feed.", type); \ + break; \ + case 1: \ + if (error_msg) \ + *error_msg = g_strdup_printf ("No %s feed directory.", \ + type); \ + return -1; \ + case 2: \ + if (error_msg) \ + *error_msg = g_strdup_printf ("Feed owner not set or invalid" \ + " while rebuilding %s.", \ + type); \ + return -1; \ + case 3: \ + if (error_msg) \ + *error_msg = g_strdup_printf ("NVTs must be available" \ + " while rebuilding %s.", \ + type); \ + return -1; \ + default: \ + if (error_msg) \ + *error_msg = g_strdup_printf ("Internal error" \ + " while rebuilding %s.", \ + type); \ + return -1; \ + } + +/** + * @brief Rebuild configs, port lists and report formats from feed. + * + * @param[in] types Comma-separated lists of types to rebuild or "all". + * @param[in] log_config Logging configuration list. + * @param[in] database Connection info for manage database. + * @param[out] error_msg Error message. + * + * @return 0 success, -1 failed. + */ +int +manage_rebuild_gvmd_data_from_feed (const char *types, + GSList *log_config, + const db_conn_info_t *database, + gchar **error_msg) +{ + int ret; + lockfile_t lockfile; + gboolean sync_configs, sync_port_lists, sync_report_formats; + + sync_configs = sync_port_lists = sync_report_formats = FALSE; + + if (strcasecmp (types, "all") == 0) + { + sync_configs = TRUE; + sync_port_lists = TRUE; + sync_report_formats = TRUE; + } + else + { + gchar **split, **split_iter; + split = g_strsplit (types, ",", -1); + + if (*split == NULL) + { + g_free (split); + if (error_msg) + *error_msg = g_strdup ("No types given."); + return -1; + } + + split_iter = split; + while (*split_iter) + { + gchar *type = g_strstrip (*split_iter); + + if (strcasecmp (type, "configs") == 0) + sync_configs = TRUE; + else if (strcasecmp (type, "port_lists") == 0) + sync_port_lists = TRUE; + else if (strcasecmp (type, "report_formats") == 0) + sync_report_formats = TRUE; + else + { + if (error_msg) + *error_msg = g_strdup_printf ("Invalid type \"%s\"" + " (must be \"configs\"," + " \"port_lists\"," + " \"report_formats\"" + " or \"all\")", + type); + g_strfreev (split); + return -1; + } + split_iter ++; + } + g_strfreev (split); + } + + ret = feed_lockfile_lock_timeout (&lockfile); + if (ret == 1) + { + if (error_msg) + *error_msg = g_strdup ("Feed locked."); + return -1; + } + else if (ret) + { + if (error_msg) + *error_msg = g_strdup ("Error acquiring feed lock."); + return -1; + } + + ret = manage_option_setup (log_config, database); + if (ret) + { + if (error_msg) + *error_msg = g_strdup ("Error setting up log config or" + " database connection."); + return -1; + } + + if (sync_configs) + { + g_message ("Rebuilding configs from feed..."); + ret = manage_rebuild_configs (); + REBUILD_SWITCH ("configs") + } + + if (sync_port_lists) + { + g_message ("Rebuilding port lists from feed..."); + ret = manage_rebuild_port_lists (); + REBUILD_SWITCH ("port lists") + } + + if (sync_report_formats) + { + g_message ("Rebuilding report formats from feed..."); + ret = manage_rebuild_report_formats (); + REBUILD_SWITCH ("report formats") + } + + feed_lockfile_unlock (&lockfile); + return 0; +} + +#undef REBUILD_SWITCH + /** * @brief Schedule any actions that are due. * diff --git a/src/manage.h b/src/manage.h index 6ca56faff..58edaaf26 100644 --- a/src/manage.h +++ b/src/manage.h @@ -2717,6 +2717,12 @@ set_scheduled_user_uuid (const gchar* uuid); void manage_sync (sigset_t *, int (*fork_update_nvt_cache) (), gboolean); +int +manage_rebuild_gvmd_data_from_feed (const char *, + GSList *, + const db_conn_info_t *, + gchar **); + int manage_schedule (manage_connection_forker_t, gboolean, diff --git a/src/manage_configs.c b/src/manage_configs.c index 7b4b108d7..1674ccac0 100644 --- a/src/manage_configs.c +++ b/src/manage_configs.c @@ -553,6 +553,18 @@ manage_sync_configs () sync_configs_with_feed (FALSE); } +/** + * @brief Rebuild configs from the feed. + * + * @return 0 success, 1 no feed directory, 2 no feed owner, 3 NVTs missing, + * -1 error. + */ +int +manage_rebuild_configs () +{ + return sync_configs_with_feed (TRUE); +} + /** * @brief Checks if the configs should be synced with the feed. */ diff --git a/src/manage_configs.h b/src/manage_configs.h index 350f7708a..23f3a70f6 100644 --- a/src/manage_configs.h +++ b/src/manage_configs.h @@ -197,6 +197,9 @@ configs_feed_dir_exists (); void manage_sync_configs (); +int +manage_rebuild_configs (); + gboolean should_sync_configs (); diff --git a/src/manage_port_lists.c b/src/manage_port_lists.c index 93dce7273..41c564be8 100644 --- a/src/manage_port_lists.c +++ b/src/manage_port_lists.c @@ -412,7 +412,7 @@ try_open_port_lists_feed_dir (GDir **dir, gboolean set_current_user) * * @param[in] rebuild Whether ignore timestamps to force a rebuild. * - * @return 0 success, 1 no feed directory or owner, -1 error. + * @return 0 success, 1 no feed directory, 2 no feed owner, -1 error. */ int sync_port_lists_with_feed (gboolean rebuild) @@ -470,6 +470,17 @@ manage_sync_port_lists () sync_port_lists_with_feed (FALSE); } +/** + * @brief Rebuild port lists from the feed. + * + * @return 0 success, 1 no feed directory, 2 no feed owner, -1 error. + */ +int +manage_rebuild_port_lists () +{ + return sync_port_lists_with_feed (TRUE); +} + /** * @brief Checks if the port lists should be synced with the feed. */ diff --git a/src/manage_port_lists.h b/src/manage_port_lists.h index 3fe0a1db4..61b52d537 100644 --- a/src/manage_port_lists.h +++ b/src/manage_port_lists.h @@ -133,6 +133,9 @@ port_lists_feed_dir_exists (); void manage_sync_port_lists (); +int +manage_rebuild_port_lists (); + gboolean should_sync_port_lists (); diff --git a/src/manage_report_formats.c b/src/manage_report_formats.c index cc5a69857..6f9c734b8 100644 --- a/src/manage_report_formats.c +++ b/src/manage_report_formats.c @@ -773,7 +773,7 @@ try_open_report_formats_feed_dir (GDir **dir, gboolean set_current_user) * * @param[in] rebuild Whether ignore timestamps to force a rebuild. * - * @return 0 success, 1 no feed directory or owner, -1 error. + * @return 0 success, 1 no feed directory, 2 no feed owner, -1 error. */ int sync_report_formats_with_feed (gboolean rebuild) @@ -831,6 +831,17 @@ manage_sync_report_formats () sync_report_formats_with_feed (FALSE); } +/** + * @brief Rebuild port lists from the feed. + * + * @return 0 success, 1 no feed directory, 2 no feed owner, -1 error. + */ +int +manage_rebuild_report_formats () +{ + return sync_report_formats_with_feed (TRUE); +} + /** * @brief Checks if the report formats should be synced with the feed. */ diff --git a/src/manage_report_formats.h b/src/manage_report_formats.h index 143771b13..beba82b5b 100644 --- a/src/manage_report_formats.h +++ b/src/manage_report_formats.h @@ -234,6 +234,9 @@ report_formats_feed_dir_exists (); void manage_sync_report_formats (); +int +manage_rebuild_report_formats (); + gboolean should_sync_report_formats (); From d7a779b8a539008059a2f944596ffb00cfcfc3a9 Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Tue, 7 Sep 2021 09:45:14 +0200 Subject: [PATCH 10/13] Add --rebuild-gvmd-data to man page --- doc/gvmd.8 | 5 +++++ doc/gvmd.8.xml | 13 +++++++++++++ doc/gvmd.html | 16 ++++++++++++++-- 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/doc/gvmd.8 b/doc/gvmd.8 index a49ea030d..8d4889284 100644 --- a/doc/gvmd.8 +++ b/doc/gvmd.8 @@ -139,6 +139,11 @@ Use port number NUMBER. \fB--port2=\fINUMBER\fB\f1 Use port number NUMBER for address 2. .TP +\fB--rebuild-gvmd-data=\fITYPES\fB\f1 +Reload all gvmd data objects of a given types from feed. + +The types must be "all" or a comma-separated of the following: "configs", "port_lists" and "report_formats". +.TP \fB--rebuild-scap\f1 Rebuild all SCAP data. .TP diff --git a/doc/gvmd.8.xml b/doc/gvmd.8.xml index 66b1e6ec1..0a8697934 100644 --- a/doc/gvmd.8.xml +++ b/doc/gvmd.8.xml @@ -315,6 +315,19 @@ along with this program. If not, see .

Use port number NUMBER for address 2.

+