diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bd0b92c2f5..45dae6a97e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -120,10 +120,12 @@ add_executable (manage-utils-test manage_acl.c manage_configs.c manage_get.c manage_license.c manage_port_lists.c manage_preferences.c + manage_report_configs.c manage_report_formats.c manage_authentication.c manage_sql.c manage_sql_nvts.c manage_sql_secinfo.c manage_sql_port_lists.c manage_sql_configs.c + manage_sql_report_configs.c manage_sql_report_formats.c manage_sql_tickets.c manage_sql_tls_certificates.c manage_tls_certificates.c @@ -132,7 +134,9 @@ add_executable (manage-utils-test lsc_user.c lsc_crypt.c utils.c gmp.c gmp_base.c gmp_configs.c gmp_delete.c gmp_get.c gmp_license.c gmp_logout.c - gmp_port_lists.c gmp_report_formats.c gmp_tickets.c + gmp_port_lists.c + gmp_report_configs.c + gmp_report_formats.c gmp_tickets.c gmp_tls_certificates.c) add_test (manage-utils-test manage-utils-test) @@ -147,10 +151,12 @@ add_executable (manage-test manage_acl.c manage_configs.c manage_get.c manage_license.c manage_port_lists.c manage_preferences.c + manage_report_configs.c manage_report_formats.c manage_authentication.c manage_sql.c manage_sql_nvts.c manage_sql_secinfo.c manage_sql_port_lists.c manage_sql_configs.c + manage_sql_report_configs.c manage_sql_report_formats.c manage_sql_tickets.c manage_sql_tls_certificates.c manage_tls_certificates.c @@ -159,7 +165,9 @@ add_executable (manage-test lsc_user.c lsc_crypt.c utils.c gmp.c gmp_base.c gmp_configs.c gmp_delete.c gmp_get.c gmp_license.c gmp_logout.c - gmp_port_lists.c gmp_report_formats.c gmp_tickets.c + gmp_port_lists.c + gmp_report_configs.c + gmp_report_formats.c gmp_tickets.c gmp_tls_certificates.c) add_test (manage-test manage-test) @@ -174,10 +182,12 @@ add_executable (manage-sql-test manage_acl.c manage_configs.c manage_get.c manage_license.c manage_port_lists.c manage_preferences.c + manage_report_configs.c manage_report_formats.c manage_authentication.c manage_sql_nvts.c manage_sql_secinfo.c manage_sql_port_lists.c manage_sql_configs.c + manage_sql_report_configs.c manage_sql_report_formats.c manage_sql_tickets.c manage_sql_tls_certificates.c manage_tls_certificates.c @@ -186,7 +196,9 @@ add_executable (manage-sql-test lsc_user.c lsc_crypt.c utils.c gmp.c gmp_base.c gmp_configs.c gmp_delete.c gmp_get.c gmp_license.c gmp_logout.c - gmp_port_lists.c gmp_report_formats.c gmp_tickets.c + gmp_port_lists.c + gmp_report_configs.c + gmp_report_formats.c gmp_tickets.c gmp_tls_certificates.c) add_test (manage-sql-test manage-sql-test) @@ -201,10 +213,12 @@ add_executable (gmp-tickets-test manage_acl.c manage_configs.c manage_get.c manage_license.c manage_port_lists.c manage_preferences.c + manage_report_configs.c manage_report_formats.c manage_authentication.c manage_sql.c manage_sql_nvts.c manage_sql_secinfo.c manage_sql_port_lists.c manage_sql_configs.c + manage_sql_report_configs.c manage_sql_report_formats.c manage_sql_tickets.c manage_sql_tls_certificates.c manage_tls_certificates.c @@ -213,7 +227,10 @@ add_executable (gmp-tickets-test lsc_user.c lsc_crypt.c utils.c gmp.c gmp_base.c gmp_configs.c gmp_delete.c gmp_get.c gmp_license.c gmp_logout.c - gmp_port_lists.c gmp_report_formats.c gmp_tls_certificates.c) + gmp_port_lists.c + gmp_report_configs.c + gmp_report_formats.c gmp_tickets.c + gmp_tls_certificates.c) add_test (gmp-tickets-test gmp-tickets-test) @@ -227,10 +244,12 @@ add_executable (utils-test manage_acl.c manage_configs.c manage_get.c manage_license.c manage_port_lists.c manage_preferences.c + manage_report_configs.c manage_report_formats.c manage_authentication.c manage_sql.c manage_sql_nvts.c manage_sql_secinfo.c manage_sql_port_lists.c manage_sql_configs.c + manage_sql_report_configs.c manage_sql_report_formats.c manage_sql_tickets.c manage_sql_tls_certificates.c manage_tls_certificates.c @@ -239,7 +258,9 @@ add_executable (utils-test lsc_user.c lsc_crypt.c gmp.c gmp_base.c gmp_configs.c gmp_delete.c gmp_get.c gmp_license.c gmp_logout.c - gmp_port_lists.c gmp_report_formats.c gmp_tickets.c + gmp_port_lists.c + gmp_report_configs.c + gmp_report_formats.c gmp_tickets.c gmp_tls_certificates.c) add_test (utils-test utils-test) @@ -256,10 +277,12 @@ add_executable (gvmd manage_acl.c manage_configs.c manage_get.c manage_license.c manage_port_lists.c manage_preferences.c + manage_report_configs.c manage_report_formats.c manage_authentication.c manage_sql.c manage_sql_nvts.c manage_sql_secinfo.c manage_sql_port_lists.c manage_sql_configs.c + manage_sql_report_configs.c manage_sql_report_formats.c manage_sql_tickets.c manage_sql_tls_certificates.c manage_tls_certificates.c @@ -268,7 +291,9 @@ add_executable (gvmd lsc_user.c lsc_crypt.c utils.c gmp.c gmp_base.c gmp_configs.c gmp_delete.c gmp_get.c gmp_license.c gmp_logout.c - gmp_port_lists.c gmp_report_formats.c gmp_tickets.c + gmp_port_lists.c + gmp_report_configs.c + gmp_report_formats.c gmp_tickets.c gmp_tls_certificates.c) target_link_libraries (gvmd m diff --git a/src/gmp.c b/src/gmp.c index 06f5f743f9..4a94e4a4a4 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -91,12 +91,14 @@ #include "gmp_license.h" #include "gmp_logout.h" #include "gmp_port_lists.h" +#include "gmp_report_configs.h" #include "gmp_report_formats.h" #include "gmp_tickets.h" #include "gmp_tls_certificates.h" #include "manage.h" #include "manage_acl.h" #include "manage_port_lists.h" +#include "manage_report_configs.h" #include "manage_report_formats.h" #include "manage_tls_certificates.h" #include "utils.h" @@ -2001,6 +2003,27 @@ get_reports_data_reset (get_reports_data_t *data) memset (data, 0, sizeof (get_reports_data_t)); } +/** + * @brief Command data for the get_report_configs command. + */ +typedef struct +{ + get_data_t get; ///< Get args. + int alerts; ///< Boolean. Whether to include alerts that use Report Config +} get_report_configs_data_t; + +/** + * @brief Reset command data. + * + * @param[in] data Command data. + */ +static void +get_report_configs_data_reset (get_report_configs_data_t *data) +{ + get_data_reset (&data->get); + memset (data, 0, sizeof (get_report_configs_data_t)); +} + /** * @brief Command data for the get_report_formats command. */ @@ -2009,6 +2032,7 @@ typedef struct get_data_t get; ///< Get args. int alerts; ///< Boolean. Whether to include alerts that use Report Format int params; ///< Boolean. Whether to include params. + int report_configs; ///< Boolean. Whether to include report configs. } get_report_formats_data_t; /** @@ -3352,6 +3376,7 @@ typedef union get_port_lists_data_t get_port_lists; ///< get_port_lists get_preferences_data_t get_preferences; ///< get_preferences get_reports_data_t get_reports; ///< get_reports + get_report_configs_data_t get_report_configs; ///< get_report_configs get_report_formats_data_t get_report_formats; ///< get_report_formats get_resource_names_data_t get_resource_names; ///< get_resource_names get_results_data_t get_results; ///< get_results @@ -3738,6 +3763,12 @@ static get_preferences_data_t *get_preferences_data static get_reports_data_t *get_reports_data = &(command_data.get_reports); +/** + * @brief Parser callback data for GET_REPORT_CONFIGS. + */ +static get_report_configs_data_t *get_report_configs_data + = &(command_data.get_report_configs); + /** * @brief Parser callback data for GET_REPORT_FORMATS. */ @@ -4122,6 +4153,7 @@ typedef enum CLIENT_CREATE_PORT_RANGE_PORT_LIST, CLIENT_CREATE_PORT_RANGE_START, CLIENT_CREATE_PORT_RANGE_TYPE, + CLIENT_CREATE_REPORT_CONFIG, CLIENT_CREATE_REPORT_FORMAT, /* CREATE_REPORT. */ CLIENT_CREATE_REPORT, @@ -4307,6 +4339,7 @@ typedef enum CLIENT_DELETE_PORT_LIST, CLIENT_DELETE_PORT_RANGE, CLIENT_DELETE_REPORT, + CLIENT_DELETE_REPORT_CONFIG, CLIENT_DELETE_REPORT_FORMAT, CLIENT_DELETE_ROLE, CLIENT_DELETE_SCANNER, @@ -4340,6 +4373,7 @@ typedef enum CLIENT_GET_PORT_LISTS, CLIENT_GET_PREFERENCES, CLIENT_GET_REPORTS, + CLIENT_GET_REPORT_CONFIGS, CLIENT_GET_REPORT_FORMATS, CLIENT_GET_RESOURCE_NAMES, CLIENT_GET_RESULTS, @@ -4439,6 +4473,7 @@ typedef enum CLIENT_MODIFY_PORT_LIST, CLIENT_MODIFY_PORT_LIST_COMMENT, CLIENT_MODIFY_PORT_LIST_NAME, + CLIENT_MODIFY_REPORT_CONFIG, CLIENT_MODIFY_REPORT_FORMAT, CLIENT_MODIFY_REPORT_FORMAT_ACTIVE, CLIENT_MODIFY_REPORT_FORMAT_NAME, @@ -4778,6 +4813,12 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, } else if (strcasecmp ("CREATE_REPORT", element_name) == 0) set_client_state (CLIENT_CREATE_REPORT); + else if (strcasecmp ("CREATE_REPORT_CONFIG", element_name) == 0) + { + create_report_config_start (gmp_parser, attribute_names, + attribute_values); + set_client_state (CLIENT_CREATE_REPORT_CONFIG); + } else if (strcasecmp ("CREATE_REPORT_FORMAT", element_name) == 0) { create_report_format_start (gmp_parser, attribute_names, @@ -4956,6 +4997,12 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, &delete_report_data->report_id); set_client_state (CLIENT_DELETE_REPORT); } + else if (strcasecmp ("DELETE_REPORT_CONFIG", element_name) == 0) + { + delete_start ("report_config", "Report Config", + attribute_names, attribute_values); + set_client_state (CLIENT_DELETE_REPORT_CONFIG); + } else if (strcasecmp ("DELETE_REPORT_FORMAT", element_name) == 0) { const gchar* attribute; @@ -5515,6 +5562,22 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, set_client_state (CLIENT_GET_REPORTS); } + else if (strcasecmp ("GET_REPORT_CONFIGS", element_name) == 0) + { + const gchar* attribute; + + get_data_parse_attributes (&get_report_configs_data->get, + "report_config", + attribute_names, + attribute_values); + if (find_attribute (attribute_names, attribute_values, + "alerts", &attribute)) + get_report_configs_data->alerts = strcmp (attribute, "0"); + else + get_report_configs_data->alerts = 0; + + set_client_state (CLIENT_GET_REPORT_CONFIGS); + } else if (strcasecmp ("GET_REPORT_FORMATS", element_name) == 0) { const gchar* attribute; @@ -5535,6 +5598,12 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, else get_report_formats_data->params = 0; + if (find_attribute (attribute_names, attribute_values, + "report_configs", &attribute)) + get_report_formats_data->report_configs = strcmp (attribute, "0"); + else + get_report_formats_data->report_configs = 0; + set_client_state (CLIENT_GET_REPORT_FORMATS); } else if (strcasecmp ("GET_RESOURCE_NAMES", element_name) == 0) @@ -5848,6 +5917,12 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, &modify_permission_data->permission_id); set_client_state (CLIENT_MODIFY_PERMISSION); } + else if (strcasecmp ("MODIFY_REPORT_CONFIG", element_name) == 0) + { + modify_report_config_start (gmp_parser, attribute_names, + attribute_values); + set_client_state (CLIENT_MODIFY_REPORT_CONFIG); + } else if (strcasecmp ("MODIFY_REPORT_FORMAT", element_name) == 0) { append_attribute (attribute_names, attribute_values, @@ -6355,6 +6430,12 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, } ELSE_READ_OVER; + case CLIENT_MODIFY_REPORT_CONFIG: + modify_report_config_element_start (gmp_parser, element_name, + attribute_names, + attribute_values); + break; + case CLIENT_MODIFY_REPORT_FORMAT: if (strcasecmp ("ACTIVE", element_name) == 0) set_client_state (CLIENT_MODIFY_REPORT_FORMAT_ACTIVE); @@ -7394,6 +7475,12 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, set_client_state (CLIENT_CREATE_REPORT_TASK_NAME); ELSE_READ_OVER; + case CLIENT_CREATE_REPORT_CONFIG: + create_report_config_element_start (gmp_parser, element_name, + attribute_names, + attribute_values); + break; + case CLIENT_CREATE_REPORT_FORMAT: create_report_format_element_start (gmp_parser, element_name, attribute_names, @@ -14886,6 +14973,266 @@ handle_get_reports (gmp_parser_t *gmp_parser, GError **error) set_client_state (CLIENT_AUTHENTIC); } +/** + * @brief Print the params of a report config. + * + * @param[in] gmp_parser GMP parser. + * @param[out] error Error parameter. + * @param[in] report_config The report config to print params of. + * @param[in] trash Whether to get report config from trash. + */ +static void +print_report_config_params (gmp_parser_t *gmp_parser, GError **error, + report_config_t report_config, int trash) +{ + iterator_t params; + init_report_config_param_iterator (¶ms, report_config, trash); + while (next (¶ms)) + { + long long int min, max; + iterator_t options; + + SENDF_TO_CLIENT_OR_FAIL + ("" + "%s" + "%s", + report_config_param_iterator_name (¶ms), + report_config_param_iterator_type_name (¶ms)); + + min = report_config_param_iterator_type_min (¶ms); + if (min > LLONG_MIN) + SENDF_TO_CLIENT_OR_FAIL ("%lli", min); + + max = report_config_param_iterator_type_max (¶ms); + if (max < LLONG_MAX) + SENDF_TO_CLIENT_OR_FAIL ("%lli", max); + + if (report_config_param_iterator_type (¶ms) + == REPORT_FORMAT_PARAM_TYPE_REPORT_FORMAT_LIST) + { + const char *value; + const char *fallback; + value = report_config_param_iterator_value (¶ms); + fallback = report_config_param_iterator_fallback_value + (¶ms); + + SENDF_TO_CLIENT_OR_FAIL + ("%s", + report_config_param_iterator_using_default (¶ms), + value ? value : ""); + if (value) + { + gchar **ids, **current_id; + ids = g_strsplit (value, ",", -1); + current_id = ids; + while (*current_id) + { + report_format_t value_rf; + gchar *name; + find_report_format_with_permission + (*current_id, &value_rf, + "get_report_formats"); + name = value_rf ? report_format_name (value_rf) + : NULL; + + SENDF_TO_CLIENT_OR_FAIL + ("" + "%s" + "", + *current_id, + name ? name : ""); + + g_free (name); + current_id ++; + } + g_strfreev (ids); + } + + SENDF_TO_CLIENT_OR_FAIL + ("%s", + fallback ? fallback : ""); + if (fallback) + { + gchar **ids, **current_id; + ids = g_strsplit (fallback, ",", -1); + current_id = ids; + while (*current_id) + { + report_format_t value_rf; + gchar *name; + find_report_format_with_permission + (*current_id, &value_rf, + "get_report_formats"); + name = value_rf ? report_format_name (value_rf) + : NULL; + + SENDF_TO_CLIENT_OR_FAIL + ("" + "%s" + "", + *current_id, + name ? name : ""); + + g_free (name); + current_id ++; + } + g_strfreev (ids); + } + + SENDF_TO_CLIENT_OR_FAIL + (""); + } + else + { + SENDF_TO_CLIENT_OR_FAIL + ("" + "%s" + "%s", + report_config_param_iterator_using_default (¶ms), + report_config_param_iterator_value (¶ms), + report_config_param_iterator_fallback_value (¶ms)); + } + + if (report_config_param_iterator_type (¶ms) + == REPORT_FORMAT_PARAM_TYPE_SELECTION) + { + SEND_TO_CLIENT_OR_FAIL (""); + init_param_option_iterator + (&options, + report_config_param_iterator_format_param + (¶ms), + 1, + NULL); + while (next (&options)) + SENDF_TO_CLIENT_OR_FAIL + ("", + param_option_iterator_value (&options)); + cleanup_iterator (&options); + SEND_TO_CLIENT_OR_FAIL (""); + } + + SEND_TO_CLIENT_OR_FAIL (""); + } + cleanup_iterator (¶ms); +} + +/** + * @brief Handle end of GET_REPORT_CONFIGS element. + * + * @param[in] gmp_parser GMP parser. + * @param[in] error Error parameter. + */ +static void +handle_get_report_configs (gmp_parser_t *gmp_parser, GError **error) +{ + iterator_t report_configs; + int count, filtered, ret, first; + + INIT_GET (report_config, Report Config); + + ret = init_report_config_iterator (&report_configs, + &get_report_configs_data->get); + if (ret) + { + switch (ret) + { + case 1: + if (send_find_error_to_client ("get_report_configs", + "report_config", + get_report_configs_data->get.id, + gmp_parser)) + { + error_send_to_client (error); + return; + } + break; + case 2: + if (send_find_error_to_client + ("get_report_configs", "filter", + get_report_configs_data->get.filt_id, gmp_parser)) + { + error_send_to_client (error); + return; + } + break; + case -1: + SEND_TO_CLIENT_OR_FAIL + (XML_INTERNAL_ERROR ("get_report_configs")); + break; + } + get_report_configs_data_reset (get_report_configs_data); + set_client_state (CLIENT_AUTHENTIC); + return; + } + + SEND_GET_START ("report_config"); + while (1) + { + int orphan; + + ret = get_next (&report_configs, + &get_report_configs_data->get, &first, &count, + init_report_config_iterator); + if (ret == 1) + break; + if (ret == -1) + { + internal_error_send_to_client (error); + return; + } + + SEND_GET_COMMON (report_config, + &get_report_configs_data->get, + &report_configs); + + orphan = (report_config_iterator_report_format (&report_configs) == 0); + + if (orphan) + { + SEND_TO_CLIENT_OR_FAIL ("1"); + } + + SENDF_TO_CLIENT_OR_FAIL + ("", + report_config_iterator_report_format_id (&report_configs) + ); + + if (!orphan) + { + SENDF_TO_CLIENT_OR_FAIL + ("%s", + report_config_iterator_report_format_name (&report_configs) + ); + + if (report_config_iterator_report_format_readable (&report_configs) == 0) + { + SENDF_TO_CLIENT_OR_FAIL (""); + } + } + + SENDF_TO_CLIENT_OR_FAIL (""); + + print_report_config_params (gmp_parser, error, + report_config_param_iterator_rowid ( + &report_configs + ), + get_report_configs_data->get.trash); + + SEND_TO_CLIENT_OR_FAIL (""); + count++; + } + + cleanup_iterator (&report_configs); + filtered = get_report_configs_data->get.id + ? 1 + : report_config_count (&get_report_configs_data->get); + SEND_GET_END ("report_config", &get_report_configs_data->get, + count, filtered); + + get_report_configs_data_reset (get_report_configs_data); + set_client_state (CLIENT_AUTHENTIC); +} + /** * @brief Handle end of GET_REPORT_FORMATS element. * @@ -14970,7 +15317,8 @@ handle_get_report_formats (gmp_parser_t *gmp_parser, GError **error) "%s" "%s" "%s" - "%i", + "%i" + "%i", report_format_iterator_extension (&report_formats), report_format_iterator_content_type (&report_formats), report_format_iterator_summary (&report_formats), @@ -14979,7 +15327,8 @@ handle_get_report_formats (gmp_parser_t *gmp_parser, GError **error) ? trash_report_format_predefined (get_iterator_resource (&report_formats)) : report_format_predefined - (get_iterator_resource (&report_formats))); + (get_iterator_resource (&report_formats)), + report_format_iterator_configurable (&report_formats)); if (resource_id_deprecated ("report_format", get_iterator_uuid (&report_formats))) @@ -14990,6 +15339,7 @@ handle_get_report_formats (gmp_parser_t *gmp_parser, GError **error) if (get_report_formats_data->alerts) { iterator_t alerts; + int invisible_alerts = 0; SEND_TO_CLIENT_OR_FAIL (""); init_report_format_alert_iterator (&alerts, @@ -14998,22 +15348,61 @@ handle_get_report_formats (gmp_parser_t *gmp_parser, GError **error) while (next (&alerts)) { if (report_format_alert_iterator_readable (&alerts) == 0) - /* Only show alerts the user may see. */ - continue; + { + /* Only show alerts the user may see. */ + invisible_alerts ++; + continue; + } SENDF_TO_CLIENT_OR_FAIL ("" - "%s", + "%s" + "", report_format_alert_iterator_uuid (&alerts), report_format_alert_iterator_name (&alerts)); - if (report_format_alert_iterator_readable (&alerts)) - SEND_TO_CLIENT_OR_FAIL (""); - else - SEND_TO_CLIENT_OR_FAIL ("" - ""); } cleanup_iterator (&alerts); - SEND_TO_CLIENT_OR_FAIL (""); + SENDF_TO_CLIENT_OR_FAIL ("" + "" + "%d" + "", + invisible_alerts); + } + + if (get_report_formats_data->report_configs) + { + iterator_t report_configs; + int invisible_report_configs = 0; + + SEND_TO_CLIENT_OR_FAIL (""); + init_report_format_report_config_iterator (&report_configs, + get_iterator_uuid + (&report_formats)); + while (next (&report_configs)) + { + if (report_format_report_config_iterator_readable ( + &report_configs) == 0) + { + /* Only show report configs the user may see. */ + invisible_report_configs ++; + continue; + } + + SENDF_TO_CLIENT_OR_FAIL + ("" + "%s" + "", + report_format_report_config_iterator_uuid ( + &report_configs), + report_format_report_config_iterator_name ( + &report_configs)); + } + cleanup_iterator (&report_configs); + SENDF_TO_CLIENT_OR_FAIL ("" + "" + "%d" + "", + invisible_report_configs); } if (get_report_formats_data->params @@ -15283,6 +15672,10 @@ select_resource_iterator (get_resource_names_data_t *resource_names_data, { *iterator = (int (*) (iterator_t*, get_data_t *))init_report_iterator; } + else if (g_strcmp0 ("report_config", resource_names_data->type) == 0) + { + *iterator = (int (*) (iterator_t*, get_data_t *))init_report_config_iterator; + } else if (g_strcmp0 ("report_format", resource_names_data->type) == 0) { *iterator = (int (*) (iterator_t*, get_data_t *))init_report_format_iterator; @@ -19028,6 +19421,11 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, set_client_state (CLIENT_AUTHENTIC); break; + case CLIENT_DELETE_REPORT_CONFIG: + delete_run (gmp_parser, error); + set_client_state (CLIENT_AUTHENTIC); + break; + CASE_DELETE (REPORT_FORMAT, report_format, "Report format"); CASE_DELETE (ROLE, role, "Role"); CASE_DELETE (SCANNER, scanner, "Scanner"); @@ -19453,6 +19851,10 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, handle_get_reports (gmp_parser, error); break; + case CLIENT_GET_REPORT_CONFIGS: + handle_get_report_configs (gmp_parser, error); + break; + case CLIENT_GET_REPORT_FORMATS: handle_get_report_formats (gmp_parser, error); break; @@ -21611,6 +22013,10 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, CLOSE (CLIENT_CREATE_REPORT_TASK, COMMENT); CLOSE (CLIENT_CREATE_REPORT_TASK, NAME); + case CLIENT_CREATE_REPORT_CONFIG: + create_report_config_element_end (gmp_parser, error, element_name); + break; + case CLIENT_CREATE_REPORT_FORMAT: if (create_report_format_element_end (gmp_parser, error, element_name)) set_client_state (CLIENT_AUTHENTIC); @@ -24406,6 +24812,10 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, CLOSE (CLIENT_MODIFY_REPORT_FORMAT_PARAM, NAME); CLOSE (CLIENT_MODIFY_REPORT_FORMAT_PARAM, VALUE); + case CLIENT_MODIFY_REPORT_CONFIG: + modify_report_config_element_end (gmp_parser, error, element_name); + break; + case CLIENT_MODIFY_ROLE: { switch (modify_role @@ -26339,6 +26749,10 @@ gmp_xml_handle_text (/* unused */ GMarkupParseContext* context, &modify_credential_data->privacy_password); + case CLIENT_MODIFY_REPORT_CONFIG: + modify_report_config_element_text (text, text_len); + break; + APPEND (CLIENT_MODIFY_REPORT_FORMAT_ACTIVE, &modify_report_format_data->active); @@ -26771,6 +27185,11 @@ gmp_xml_handle_text (/* unused */ GMarkupParseContext* context, &create_report_data->host_start); + case CLIENT_CREATE_REPORT_CONFIG: + create_report_config_element_text (text, text_len); + break; + + case CLIENT_CREATE_REPORT_FORMAT: create_report_format_element_text (text, text_len); break; diff --git a/src/gmp_report_configs.c b/src/gmp_report_configs.c new file mode 100644 index 0000000000..b5d400f2ea --- /dev/null +++ b/src/gmp_report_configs.c @@ -0,0 +1,629 @@ +/* Copyright (C) 2024 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +/** + * @file gmp_report_configs.c + * @brief GVM GMP layer: Report Configs + * + * GMP report configurations. + */ + +#include "gmp_report_configs.h" +#include "gmp_base.h" +#include "gmp_get.h" +#include "manage_report_configs.h" +#include "utils.h" + +#include +#include +#include + + +/* General helper functions */ + +/** + * @brief Collect params from entity. + * + * @param[in] entity Entity to check for param elements. + * + * @return Array of params + */ +array_t * +params_from_entity (entity_t entity) +{ + array_t *params; + entities_t children; + entity_t param_entity; + + params = make_array (); + children = entity->entities; + while ((param_entity = first_entity (children))) + { + children = children->next; + + if (strcmp (entity_name (param_entity), "param") == 0) + { + report_config_param_data_t *param; + entity_t param_name, param_value; + + param = g_malloc0 (sizeof (*param)); + + param_name = entity_child (param_entity, "name"); + if (param_name) + { + param->name = g_strstrip (g_strdup (entity_text (param_name))); + if (strcmp (param->name, "") == 0) + { + g_warning ("%s: got param with empty name", __func__); + report_config_param_data_free (param); + continue; + } + } + else + { + g_warning ("%s: got param without name", __func__); + report_config_param_data_free (param); + continue; + } + + param_value = entity_child (param_entity, "value"); + if (param_value) + { + const char *use_default_str; + + param->value = g_strdup (entity_text (param_value)); + use_default_str = entity_attribute (param_value, "use_default"); + if (use_default_str) + { + param->use_default_value = (atoi(use_default_str) != 0); + } + } + else + { + g_warning ("%s: got param \"%s\" without value", + __func__, param_name->text); + report_config_param_data_free (param); + continue; + } + + + array_add (params, param); + } + } + + array_terminate (params); + return params; +} + +/** + * @brief Free an array of report config param structs and its elements + * + * @param[in] array Pointer to array. + */ +static void +param_array_free (GPtrArray *array) +{ + if (array) + { + guint index = array->len; + while (index--) + report_config_param_data_free (g_ptr_array_index (array, index)); + + g_ptr_array_free (array, TRUE); + } +} + + +/* CREATE_REPORT_CONFIG. */ + +/** + * @brief The create_report_config command. + */ +typedef struct +{ + context_data_t *context; ///< XML parser context. +} create_report_config_t; + +/** + * @brief Parser callback data. + * + * This is initially 0 because it's a global variable. + */ +static create_report_config_t create_report_config_data; + +/** + * @brief Reset command data. + */ +static void +create_report_config_reset () +{ + if (create_report_config_data.context->first) + { + free_entity (create_report_config_data.context->first->data); + g_slist_free_1 (create_report_config_data.context->first); + } + g_free (create_report_config_data.context); + memset (&create_report_config_data, 0, sizeof (create_report_config_t)); +} + +/** + * @brief Start a command. + * + * @param[in] gmp_parser GMP parser. + * @param[in] attribute_names All attribute names. + * @param[in] attribute_values All attribute values. + */ +void +create_report_config_start (gmp_parser_t *gmp_parser, + const gchar **attribute_names, + const gchar **attribute_values) +{ + memset (&create_report_config_data, 0, sizeof (create_report_config_t)); + create_report_config_data.context = g_malloc0 (sizeof (context_data_t)); + create_report_config_element_start (gmp_parser, "create_report_config", + attribute_names, attribute_values); +} + +/** + * @brief Start element. + * + * @param[in] gmp_parser GMP parser. + * @param[in] name Element name. + * @param[in] attribute_names All attribute names. + * @param[in] attribute_values All attribute values. + */ +void +create_report_config_element_start (gmp_parser_t *gmp_parser, + const gchar *name, + const gchar **attribute_names, + const gchar **attribute_values) +{ + xml_handle_start_element (create_report_config_data.context, name, + attribute_names, attribute_values); +} + +/** + * @brief Execute command. + * + * @param[in] gmp_parser GMP parser. + * @param[in] error Error parameter. + */ +void +create_report_config_run (gmp_parser_t *gmp_parser, GError **error) +{ + report_config_t new_report_config; + entity_t entity, name, copy, comment, report_format; + const char *report_format_id; + array_t *params; + int ret; + gchar *error_message = NULL; + + entity = (entity_t) create_report_config_data.context->first->data; + + copy = entity_child (entity, "copy"); + if (copy) + { + /* Copy from an existing report config. */ + + name = entity_child (entity, "name"); + + switch (copy_report_config (name ? entity_text (name) : NULL, + entity_text (copy), + &new_report_config)) + { + case 0: + { + char *uuid; + uuid = report_config_uuid (new_report_config); + SENDF_TO_CLIENT_OR_FAIL (XML_OK_CREATED_ID + ("create_report_config"), + uuid); + log_event ("report_config", "Report Config", uuid, "created"); + free (uuid); + break; + } + case 1: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_report_config", + "Report Config exists already")); + log_event_fail ("report_config", "Report Config", NULL, "created"); + break; + case 2: + if (send_find_error_to_client ("create_report_config", + "Report Config", + entity_text (copy), + gmp_parser)) + { + error_send_to_client (error); + return; + } + log_event_fail ("report_config", "Report Config", NULL, "created"); + break; + case 3: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_report_config", + "Report Format for Config must have params")); + log_event_fail ("report_config", "Report Config", NULL, "created"); + break; + case 99: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_report_config", + "Permission denied")); + log_event_fail ("report_config", "Report Config", NULL, "created"); + break; + case -1: + default: + SEND_TO_CLIENT_OR_FAIL + (XML_INTERNAL_ERROR ("create_report_config")); + log_event_fail ("report_config", "Report Config", NULL, "created"); + break; + } + + create_report_config_reset (); + return; + } + + /* Create new report config */ + + name = entity_child (entity, "name"); + comment = entity_child (entity, "comment"); + report_format = entity_child (entity, "report_format"); + report_format_id = NULL; + if (report_format) + report_format_id = entity_attribute (report_format, "id"); + + if (name == NULL) + { + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_report_config", + "A NAME element is required")); + create_report_config_reset (); + return; + } + else if (strlen (name->text) == 0) + { + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_report_config", + "The NAME element must not be empty")); + create_report_config_reset (); + return; + } + else if (report_format_id == NULL) + { + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_report_config", + "A REPORT_FORMAT element with an ID attribute" + " is required")); + create_report_config_reset (); + return; + } + + params = params_from_entity (entity); + + ret = create_report_config (name->text, + comment ? comment->text : NULL, + report_format_id, + params, + &new_report_config, + &error_message); + + switch (ret) + { + case 0: + { + char *uuid = report_config_uuid (new_report_config); + SENDF_TO_CLIENT_OR_FAIL + (XML_OK_CREATED_ID ("create_report_config"), uuid); + log_event ("report_config", "Report Config", uuid, "created"); + free (uuid); + break; + } + case 1: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_report_config", + "Report config with given name exists already")); + log_event_fail ("report_config", "Report Config", NULL, "created"); + break; + case 2: + if (send_find_error_to_client ("create_report_config", + "Report Format", + report_format_id, + gmp_parser)) + { + error_send_to_client (error); + return; + } + log_event_fail ("report_config", "Report Config", NULL, "created"); + break; + case 3: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_report_config", + "Given report format does not have any" + " configurable parameters.")); + log_event_fail ("report_config", "Report Config", NULL, "created"); + break; + case 4: + SENDF_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_report_config", + "Parameter validation failed: %s"), + error_message); + log_event_fail ("report_config", "Report Config", NULL, "created"); + break; + case 99: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_report_config", + "Permission config")); + log_event_fail ("report_config", "Report Config", NULL, "created"); + break; + default: + SEND_TO_CLIENT_OR_FAIL + (XML_INTERNAL_ERROR ("create_report_config")); + log_event_fail ("report_config", "Report Config", NULL, "created"); + break; + } + + g_free (error_message); + param_array_free (params); + create_report_config_reset (); +} + +/** + * @brief End element. + * + * @param[in] gmp_parser GMP parser. + * @param[in] error Error parameter. + * @param[in] name Element name. + * + * @return 0 success, 1 command finished. + */ +int +create_report_config_element_end (gmp_parser_t *gmp_parser, GError **error, + const gchar *name) +{ + xml_handle_end_element (create_report_config_data.context, name); + if (create_report_config_data.context->done) + { + create_report_config_run (gmp_parser, error); + return 1; + } + return 0; +} + +/** + * @brief Add text to element. + * + * @param[in] text Text. + * @param[in] text_len Text length. + */ +void +create_report_config_element_text (const gchar *text, gsize text_len) +{ + xml_handle_text (create_report_config_data.context, text, text_len); +} + + +/* MODIFY_REPORT_CONFIG */ + +/** + * @brief The modify_report_config command. + */ +typedef struct +{ + context_data_t *context; ///< XML parser context. +} modify_report_config_t; + +/** + * @brief Parser callback data. + * + * This is initially 0 because it's a global variable. + */ +static modify_report_config_t modify_report_config_data; + +/** + * @brief Reset command data. + */ +static void +modify_report_config_reset () +{ + if (modify_report_config_data.context->first) + { + free_entity (modify_report_config_data.context->first->data); + g_slist_free_1 (modify_report_config_data.context->first); + } + g_free (modify_report_config_data.context); + memset (&modify_report_config_data, 0, sizeof (create_report_config_t)); +} + +/** + * @brief Start a command. + * + * @param[in] gmp_parser GMP parser. + * @param[in] attribute_names All attribute names. + * @param[in] attribute_values All attribute values. + */ +void +modify_report_config_start (gmp_parser_t *gmp_parser, + const gchar **attribute_names, + const gchar **attribute_values) +{ + memset (&modify_report_config_data, 0, sizeof (modify_report_config_t)); + modify_report_config_data.context = g_malloc0 (sizeof (context_data_t)); + modify_report_config_element_start (gmp_parser, "modify_report_config", + attribute_names, attribute_values); +} + +/** + * @brief Start element. + * + * @param[in] gmp_parser GMP parser. + * @param[in] name Element name. + * @param[in] attribute_names All attribute names. + * @param[in] attribute_values All attribute values. + */ +void +modify_report_config_element_start (gmp_parser_t *gmp_parser, const gchar *name, + const gchar **attribute_names, + const gchar **attribute_values) +{ + xml_handle_start_element (modify_report_config_data.context, name, + attribute_names, attribute_values); +} + +/** + * @brief Execute command. + * + * @param[in] gmp_parser GMP parser. + * @param[in] error Error parameter. + */ +void +modify_report_config_run (gmp_parser_t *gmp_parser, GError **error) +{ + entity_t entity, name, comment; + const char *report_config_id; + array_t *params; + int ret; + gchar *error_message = NULL; + + entity = (entity_t) modify_report_config_data.context->first->data; + + report_config_id = entity_attribute(entity, "report_config_id"); + name = entity_child (entity, "name"); + comment = entity_child (entity, "comment"); + + if (report_config_id == NULL) + { + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("modify_report_config", + "A report_config_id attribute is required")); + modify_report_config_reset (); + return; + } + else if (name && strlen (name->text) == 0) + { + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("modify_report_config", + "The NAME element must not be empty")); + create_report_config_reset (); + return; + } + + params = params_from_entity (entity); + + ret = modify_report_config (report_config_id, + name ? name->text : NULL, + comment ? comment->text : NULL, + params, + &error_message); + + switch (ret) + { + case 0: + { + SENDF_TO_CLIENT_OR_FAIL + (XML_OK ("modify_report_config")); + log_event ("report_config", "Report Config", report_config_id, + "modified"); + break; + } + case 1: + if (send_find_error_to_client ("create_report_config", + "Report Config", + report_config_id, + gmp_parser)) + { + error_send_to_client (error); + return; + } + log_event_fail ("report_config", "Report Config", report_config_id, + "modified"); + break; + case 2: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_report_config", + "Report config with given name exists already")); + log_event_fail ("report_config", "Report Config", NULL, "created"); + break; + case 3: + SENDF_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("modify_report_config", + "Cannot modify params of" + " an orphaned report config")); + log_event_fail ("report_config", "Report Config", report_config_id, + "modified"); + break; + case 4: + SENDF_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("modify_report_config", + "Parameter validation failed: %s"), + error_message); + log_event_fail ("report_config", "Report Config", report_config_id, + "modified"); + break; + case 99: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("modify_report_config", + "Permission config")); + log_event_fail ("report_config", "Report Config", report_config_id, + "modified"); + break; + default: + SEND_TO_CLIENT_OR_FAIL + (XML_INTERNAL_ERROR ("modify_report_config")); + log_event_fail ("report_config", "Report Config", report_config_id, + "modified"); + break; + } + + g_free (error_message); + param_array_free (params); + modify_report_config_reset (); +} + +/** + * @brief End element. + * + * @param[in] gmp_parser GMP parser. + * @param[in] error Error parameter. + * @param[in] name Element name. + * + * @return 0 success, 1 command finished. + */ +int +modify_report_config_element_end (gmp_parser_t *gmp_parser, GError **error, + const gchar *name) +{ + xml_handle_end_element (modify_report_config_data.context, name); + if (modify_report_config_data.context->done) + { + modify_report_config_run (gmp_parser, error); + return 1; + } + return 0; +} + +/** + * @brief Add text to element. + * + * @param[in] text Text. + * @param[in] text_len Text length. + */ +void +modify_report_config_element_text (const gchar *text, gsize text_len) +{ + xml_handle_text (modify_report_config_data.context, text, text_len); +} diff --git a/src/gmp_report_configs.h b/src/gmp_report_configs.h new file mode 100644 index 0000000000..417f33a6d9 --- /dev/null +++ b/src/gmp_report_configs.h @@ -0,0 +1,59 @@ +/* Copyright (C) 2024 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +/** + * @file gmp_report_formats.h + * @brief GVM GMP layer: Report Configs headers + * + * Headers for GMP report configurations. + */ + +#ifndef _GVMD_GMP_REPORT_CONFIGS_H +#define _GVMD_GMP_REPORT_CONFIGS_H + +#include "gmp_base.h" + +#include +#include + +void +create_report_config_start (gmp_parser_t *, const gchar **, const gchar **); + +void +create_report_config_element_start (gmp_parser_t *, const gchar *, const gchar **, + const gchar **); + +int create_report_config_element_end (gmp_parser_t*, GError**, const gchar*); + +void +create_report_config_element_text (const gchar *, gsize); + +void +modify_report_config_start (gmp_parser_t *, const gchar **, const gchar **); + +void +modify_report_config_element_start (gmp_parser_t *, const gchar *, const gchar **, + const gchar **); + +int +modify_report_config_element_end (gmp_parser_t *, GError **error, const gchar *); + +void +modify_report_config_element_text (const gchar *, gsize); + +#endif /* not _GVMD_GMP_REPORT_CONFIGS_H */ \ No newline at end of file diff --git a/src/manage.c b/src/manage.c index 5c8357459a..249ab1522b 100644 --- a/src/manage.c +++ b/src/manage.c @@ -52,6 +52,7 @@ #include "manage_acl.h" #include "manage_configs.h" #include "manage_port_lists.h" +#include "manage_report_configs.h" #include "manage_report_formats.h" #include "manage_sql.h" #include "manage_sql_secinfo.h" @@ -7536,6 +7537,8 @@ manage_run_wizard (const gchar *wizard_name, int delete_resource (const char *type, const char *resource_id, int ultimate) { + if (strcasecmp (type, "report_config") == 0) + return delete_report_config (resource_id, ultimate); if (strcasecmp (type, "ticket") == 0) return delete_ticket (resource_id, ultimate); if (strcasecmp (type, "tls_certificate") == 0) diff --git a/src/manage.h b/src/manage.h index 0c6347d071..ed5d12519c 100644 --- a/src/manage.h +++ b/src/manage.h @@ -346,6 +346,8 @@ typedef resource_t tls_certificate_t; typedef resource_t result_t; typedef resource_t report_t; typedef resource_t report_host_t; +typedef resource_t report_config_t; +typedef resource_t report_config_param_t; typedef resource_t report_format_t; typedef resource_t report_format_param_t; typedef resource_t role_t; diff --git a/src/manage_pg.c b/src/manage_pg.c index 6f2dd95006..c261f4ca9a 100644 --- a/src/manage_pg.c +++ b/src/manage_pg.c @@ -2613,6 +2613,42 @@ create_tables () " (result_nvt INTEGER," " report INTEGER);"); + sql ("CREATE TABLE IF NOT EXISTS report_configs" + " (id SERIAL PRIMARY KEY," + " uuid text UNIQUE NOT NULL," + " owner integer REFERENCES users (id) ON DELETE RESTRICT," + " name text NOT NULL," + " comment text," + " creation_time integer," + " modification_time integer," + " report_format_id text);"); + + sql ("CREATE TABLE IF NOT EXISTS report_configs_trash" + " (id SERIAL PRIMARY KEY," + " uuid text UNIQUE NOT NULL," + " owner integer REFERENCES users (id) ON DELETE RESTRICT," + " name text NOT NULL," + " comment text," + " creation_time integer," + " modification_time integer," + " report_format_id text);"); + + sql ("CREATE TABLE IF NOT EXISTS report_config_params" + " (id SERIAL PRIMARY KEY," + " report_config integer" + " REFERENCES report_configs (id) ON DELETE RESTRICT," + " name text," + " value text," + " UNIQUE (report_config, name));"); + + sql ("CREATE TABLE IF NOT EXISTS report_config_params_trash" + " (id SERIAL PRIMARY KEY," + " report_config integer" + " REFERENCES report_configs_trash (id) ON DELETE RESTRICT," + " name text," + " value text," + " UNIQUE (report_config, name));"); + sql ("CREATE TABLE IF NOT EXISTS report_formats" " (id SERIAL PRIMARY KEY," " uuid text UNIQUE NOT NULL," diff --git a/src/manage_report_configs.c b/src/manage_report_configs.c new file mode 100644 index 0000000000..277f2592d4 --- /dev/null +++ b/src/manage_report_configs.c @@ -0,0 +1,95 @@ +/* Copyright (C) 2024 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +/** + * @file manage_report_configs.c + * @brief GVM management layer: Report configs. + * + * Non-SQL report config code for the GVM management layer. + */ + +#include "manage_sql.h" +#include "manage_report_configs.h" + +#undef G_LOG_DOMAIN +/** + * @brief GLib log domain. + */ +#define G_LOG_DOMAIN "md manage" + +/** + * @brief Find a report config for a specific permission, given a UUID. + * + * @param[in] uuid UUID of report config. + * @param[out] report_config Report config return, 0 if successfully failed to + * find report_config. + * @param[in] permission Permission. + * + * @return FALSE on success (including if failed to find report_config), TRUE + * on error. + */ +gboolean +find_report_config_with_permission (const char *uuid, + report_config_t *report_config, + const char *permission) +{ + return find_resource_with_permission ("report_config", uuid, report_config, + permission, 0); +} + +/** + * @brief Free a report config parameter data struct. + * + * @param[in] param The parameter to free. + */ +void +report_config_param_data_free (report_config_param_data_t *param) +{ + if (param == NULL) + return; + + g_free (param->name); + g_free (param->value); + g_free (param); +} + +/** + * @brief Return whether a report config is writable. + * + * @param[in] report_config Report Config. + * + * @return 1 if writable, else 0. + */ +int +report_config_writable (report_config_t report_config) +{ + return report_config_in_use (report_config) == 0; +} + +/** + * @brief Return whether a trashcan report config is writable. + * + * @param[in] report_config Report Config. + * + * @return 1 if writable, else 0. + */ +int +trash_report_config_writable (report_config_t report_config) +{ + return trash_report_config_in_use (report_config) == 0; +} diff --git a/src/manage_report_configs.h b/src/manage_report_configs.h new file mode 100644 index 0000000000..9011ffb5b1 --- /dev/null +++ b/src/manage_report_configs.h @@ -0,0 +1,137 @@ +/* Copyright (C) 2024 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +/** + * @file manage_report_formats.c + * @brief GVM management layer: Report formats. + * + * Non-SQL report format code for the GVM management layer. + */ + +#ifndef _GVMD_MANAGE_REPORT_CONFIGS_H +#define _GVMD_MANAGE_REPORT_CONFIGS_H + +#include "manage.h" +#include "manage_report_formats.h" + +#include + + +gboolean +find_report_config_with_permission (const char*, report_config_t*, + const char *); + +/** + * @brief Struct for defining a report format param. + */ +typedef struct +{ + gchar *name; ///< Name. + gchar *value; ///< Value of param. + int use_default_value; ///< Whether to use default value +} report_config_param_data_t; + +void +report_config_param_data_free (report_config_param_data_t*); + +int +create_report_config (const char *, const char *, const char *, array_t *, + report_config_t *, gchar **); + +int +copy_report_config (const char *, const char *, report_config_t*); + +int +modify_report_config (const char *, const char *, const char *, array_t *, + gchar **); + +int +delete_report_config (const char *, int); + +char * +report_config_uuid (report_config_t); + +report_format_t +report_config_report_format (report_config_t); + +int +report_config_in_use (report_config_t); + +int +trash_report_config_in_use (report_config_t); + +int +trash_report_config_writable (report_config_t); + +int +report_config_writable (report_config_t); + +int +report_config_count (const get_data_t *); + + +int +init_report_config_iterator (iterator_t*, const get_data_t *); + +const char* +report_config_iterator_report_format_id (iterator_t *); + +int +report_config_iterator_report_format_readable (iterator_t* iterator); + +const char* +report_config_iterator_report_format_name (iterator_t *); + +report_format_t +report_config_iterator_report_format (iterator_t *); + + +void +init_report_config_param_iterator(iterator_t*, report_config_t, int); + +report_config_param_t +report_config_param_iterator_rowid (iterator_t *); + +const char* +report_config_param_iterator_name (iterator_t *); + +report_format_param_type_t +report_config_param_iterator_type (iterator_t *); + +const char* +report_config_param_iterator_type_name (iterator_t *); + +const char* +report_config_param_iterator_value (iterator_t *); + +const char* +report_config_param_iterator_fallback_value (iterator_t *); + +long long int +report_config_param_iterator_type_min (iterator_t *); + +long long int +report_config_param_iterator_type_max (iterator_t *); + +report_format_param_t +report_config_param_iterator_format_param (iterator_t *); + +int +report_config_param_iterator_using_default (iterator_t *); + +#endif /* not _GVMD_MANAGE_REPORT_CONFIGS_H */ diff --git a/src/manage_report_formats.h b/src/manage_report_formats.h index a542fa0b71..9d593a1cd0 100644 --- a/src/manage_report_formats.h +++ b/src/manage_report_formats.h @@ -88,6 +88,10 @@ trash_report_format_predefined (report_format_t); int report_format_active (report_format_t); +int +report_format_validate_param_value (report_format_t, report_format_param_t, + const char*, const char*, gchar **); + int report_format_trust (report_format_t); @@ -133,6 +137,9 @@ report_format_iterator_summary (iterator_t *); time_t report_format_iterator_trust_time (iterator_t *); +int +report_format_iterator_configurable (iterator_t *); + void init_report_format_alert_iterator (iterator_t*, report_format_t); @@ -145,6 +152,18 @@ report_format_alert_iterator_uuid (iterator_t*); int report_format_alert_iterator_readable (iterator_t*); +void +init_report_format_report_config_iterator (iterator_t*, const char*); + +const char* +report_format_report_config_iterator_name (iterator_t*); + +const char* +report_format_report_config_iterator_uuid (iterator_t*); + +int +report_format_report_config_iterator_readable (iterator_t*); + /** * @brief A report format file iterator. */ diff --git a/src/manage_sql.c b/src/manage_sql.c index b394f57ede..ad2a8d2d8e 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -35,6 +35,7 @@ #include "manage_tickets.h" #include "manage_sql_configs.h" #include "manage_sql_port_lists.h" +#include "manage_sql_report_configs.h" #include "manage_sql_report_formats.h" #include "manage_sql_tickets.h" #include "manage_sql_tls_certificates.h" @@ -81,6 +82,7 @@ #include #include #include +#include "manage_report_configs.h" #undef G_LOG_DOMAIN /** @@ -468,6 +470,7 @@ command_t gmp_commands[] {"CREATE_PORT_LIST", "Create a port list."}, {"CREATE_PORT_RANGE", "Create a port range in a port list."}, {"CREATE_REPORT", "Create a report."}, + {"CREATE_REPORT_CONFIG", "Create a report config."}, {"CREATE_REPORT_FORMAT", "Create a report format."}, {"CREATE_ROLE", "Create a role."}, {"CREATE_SCANNER", "Create a scanner."}, @@ -490,6 +493,7 @@ command_t gmp_commands[] {"DELETE_PORT_LIST", "Delete a port list."}, {"DELETE_PORT_RANGE", "Delete a port range."}, {"DELETE_REPORT", "Delete a report."}, + {"DELETE_REPORT_CONFIG", "Delete a report config."}, {"DELETE_REPORT_FORMAT", "Delete a report format."}, {"DELETE_ROLE", "Delete a role."}, {"DELETE_SCANNER", "Delete a scanner."}, @@ -520,6 +524,7 @@ command_t gmp_commands[] {"GET_PORT_LISTS", "Get all port lists."}, {"GET_PREFERENCES", "Get preferences for all available NVTs."}, {"GET_REPORTS", "Get all reports."}, + {"GET_REPORT_CONFIGS", "Get all report configs."}, {"GET_REPORT_FORMATS", "Get all report formats."}, {"GET_RESULTS", "Get results."}, {"GET_ROLES", "Get all roles."}, @@ -548,6 +553,7 @@ command_t gmp_commands[] {"MODIFY_OVERRIDE", "Modify an existing override."}, {"MODIFY_PERMISSION", "Modify an existing permission."}, {"MODIFY_PORT_LIST", "Modify an existing port list."}, + {"MODIFY_REPORT_CONFIG", "Modify an existing report config."}, {"MODIFY_REPORT_FORMAT", "Modify an existing report format."}, {"MODIFY_ROLE", "Modify an existing role."}, {"MODIFY_SCANNER", "Modify an existing scanner."}, @@ -48106,6 +48112,11 @@ manage_restore (const char *id) if (ret != 2) return ret; + /* Report Config. */ + ret = restore_report_config (id); + if (ret != 2) + return ret; + /* Report Format. */ ret = restore_report_format (id); if (ret != 2) @@ -49119,6 +49130,12 @@ manage_empty_trashcan () " WHERE uuid = '%s'))" " AND subject_location = " G_STRINGIFY (LOCATION_TRASH) ";", current_credentials.uuid); + sql ("DELETE FROM report_config_params_trash" + " WHERE report_config IN (SELECT id FROM report_configs_trash" + " WHERE owner = (SELECT id FROM users" + " WHERE uuid = '%s'));", + current_credentials.uuid); + sql ("DELETE FROM report_configs_trash" WHERE_OWNER); sql ("DELETE FROM role_users_trash" " WHERE role IN (SELECT id from roles_trash" " WHERE owner = (SELECT id FROM users" @@ -52380,6 +52397,8 @@ modify_setting (const gchar *uuid, const gchar *name, setting_name = g_strdup ("Port Lists Filter"); else if (strcmp (uuid, "48ae588e-9085-41bc-abcb-3d6389cf7237") == 0) setting_name = g_strdup ("Reports Filter"); + else if (strcmp (uuid, "eca9738b-4339-4a3d-bd13-3c61173236ab") == 0) + setting_name = g_strdup ("Report Configs Filter"); else if (strcmp (uuid, "249c7a55-065c-47fb-b453-78e11a665565") == 0) setting_name = g_strdup ("Report Formats Filter"); else if (strcmp (uuid, "739ab810-163d-11e3-9af6-406186ea4fc5") == 0) @@ -54088,6 +54107,11 @@ delete_user (const char *user_id_arg, const char *name_arg, int ultimate, sql ("UPDATE roles_trash SET owner = %llu WHERE owner = %llu;", inheritor, user); + sql ("UPDATE report_configs SET owner = %llu WHERE owner = %llu;", + inheritor, user); + sql ("UPDATE report_configs_trash SET owner = %llu WHERE owner = %llu;", + inheritor, user); + /* Report Formats. */ has_rows = inherit_report_formats (user, inheritor, &rows); @@ -54421,6 +54445,10 @@ delete_user (const char *user_id_arg, const char *name_arg, int ultimate, sql ("DELETE FROM role_users WHERE \"user\" = %llu;", user); sql ("DELETE FROM role_users_trash WHERE \"user\" = %llu;", user); + /* Delete report configs */ + + delete_report_configs_user (user); + /* Delete report formats. */ has_rows = delete_report_formats_user (user, &rows); @@ -57325,6 +57353,8 @@ type_select_columns (const char *type) return port_list_select_columns (); if (strcasecmp (type, "REPORT") == 0) return report_columns; + if (strcasecmp (type, "REPORT_CONFIG") == 0) + return report_config_select_columns (); if (strcasecmp (type, "REPORT_FORMAT") == 0) return report_format_select_columns (); if (strcasecmp (type, "RESULT") == 0) @@ -57478,6 +57508,8 @@ type_filter_columns (const char *type) static const char *ret[] = REPORT_ITERATOR_FILTER_COLUMNS; return ret; } + if (strcasecmp (type, "REPORT_CONFIG") == 0) + return report_config_filter_columns (); if (strcasecmp (type, "REPORT_FORMAT") == 0) return report_format_filter_columns (); if (strcasecmp (type, "RESULT") == 0) diff --git a/src/manage_sql_report_configs.c b/src/manage_sql_report_configs.c new file mode 100644 index 0000000000..63dd971704 --- /dev/null +++ b/src/manage_sql_report_configs.c @@ -0,0 +1,1113 @@ +/* Copyright (C) 2024 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +/** + * @file manage_sql_report_formats.c + * @brief GVM management layer: Report configs SQL. + * + * SQL report config code for the GVM management layer. + */ + +#include "debug_utils.h" +#include "manage_report_configs.h" +#include "manage_sql_report_configs.h" +#include "manage_acl.h" +#include "manage_report_formats.h" +#include "sql.h" +#include "utils.h" +#include + +#undef G_LOG_DOMAIN +/** + * @brief GLib log domain. + */ +#define G_LOG_DOMAIN "md manage" + + +/** + * @brief Create Report Config from an existing Report Config. + * + * @param[in] name Name of new Report Config. NULL to copy + * from existing. + * @param[in] source_uuid UUID of existing Report Config. + * @param[out] new_report_format New Report Config. + * + * @return 0 success, 1 Report Config exists already, 2 failed to find existing + * Report Config, 99 permission denied, -1 error. + */ +int +copy_report_config (const char* name, const char* source_uuid, + report_config_t* new_report_format) +{ + report_format_t new, old; + int ret; + + assert (current_credentials.uuid); + + sql_begin_immediate (); + + ret = copy_resource_lock ("report_config", name, NULL, source_uuid, + "report_format_id", + 1, &new, &old); + if (ret) + { + sql_rollback (); + return ret; + } + + /* Copy report format parameters. */ + + sql ("INSERT INTO report_config_params " + " (report_config, name, value)" + " SELECT %llu, name, value" + " FROM report_format_params WHERE report_format = %llu;", + new, + old); + + sql_commit (); + + if (new_report_format) *new_report_format = new; + return 0; +} + +/** + * @brief Validate a parameter for a report config against the report format. + * + * @param[in] param The parameter to validate + * @param[in] report_format The report format the config param is based on + * @param[out] error_message Pointer for error message if validation fails + * + * @return 0 param is valid, 1 param is invalid + */ +static int +validate_report_config_param (report_config_param_data_t *param, + report_format_t report_format, + gchar **error_message) +{ + gchar *quoted_param_name = sql_quote (param->name); + report_format_param_t format_param; + + format_param = sql_int64_0 ("SELECT id FROM report_format_params" + " WHERE report_format = %llu" + " AND name = '%s'", + report_format, + quoted_param_name); + + if (format_param == 0) + { + if (error_message) + *error_message = g_strdup_printf ("report format has no parameter" + " named \"%s\"", + param->name); + g_free (quoted_param_name); + return 1; + } + + if (report_format_validate_param_value (report_format, format_param, + param->name, param->value, + error_message)) + { + g_free (quoted_param_name); + return 1; + } + + g_free (quoted_param_name); + return 0; +} + +/** + * @brief Add or replace a parameter to a new report config. + * + * @param[in] report_config The config the param is to be added to + * @param[in] param The parameter to add + */ +static void +insert_report_config_param (report_config_t report_config, + report_config_param_data_t *param) +{ + gchar *quoted_name, *quoted_value; + + quoted_name = sql_quote (param->name ?: ""); + quoted_value = sql_quote (param->value ?: ""); + + sql ("INSERT INTO report_config_params (report_config, name, value)" + " VALUES (%llu, '%s', '%s')" + " ON CONFLICT (report_config, name)" + " DO UPDATE SET value = EXCLUDED.value", + report_config, quoted_name, quoted_value); + + g_free (quoted_name); + g_free (quoted_value); +} + +/** + * @brief Create a report config. + * + * @param[in] name Name of report config. + * @param[in] comment Comment of report config. + * @param[in] report_format_id UUID of report format. + * @param[in] params Array of params. + * @param[out] report_config Created report config. + * @param[out] error_message Message for some errors like invalid params. + * + * @return 0 success, + * 1 report config with same name already exists, + * 2 report format not found, + * 3 report format not configurable, + * 4 param validation failed, + * 99 permission denied, + * -1 internal error. + */ +int +create_report_config (const char *name, const char *comment, + const char *report_format_id, + array_t *params, + report_config_t *report_config, + gchar **error_message) +{ + gchar *quoted_name, *quoted_comment, *quoted_report_format_id; + report_format_t report_format; + sql_begin_immediate (); + + if (acl_user_may ("create_report_config") == 0) + { + sql_rollback (); + return 99; + } + + quoted_name = sql_quote (name ? name : ""); + if (sql_int ("SELECT count(*) FROM report_configs WHERE name = '%s'", + quoted_name)) + { + g_free (quoted_name); + sql_rollback (); + return 1; + } + + report_format = 0; + if (find_report_format_with_permission (report_format_id, &report_format, + "get_report_formats")) + { + g_free (quoted_name); + sql_rollback (); + return -1; + } + + if (report_format == 0) + { + g_free (quoted_name); + sql_rollback (); + return 2; + } + + if (sql_int ("SELECT count(*) FROM report_format_params" + " WHERE report_format = %llu", report_format) == 0) + { + g_free (quoted_name); + sql_rollback (); + return 3; + } + + quoted_comment = sql_quote (comment ?: ""); + quoted_report_format_id = sql_quote (report_format_id ?: ""); + + *report_config = sql_int64_0 ("INSERT INTO report_configs" + " (uuid, name, comment, report_format_id," + " owner, creation_time, modification_time)" + " SELECT make_uuid(), '%s', '%s', '%s'," + " (SELECT id FROM users WHERE uuid='%s')," + " m_now(), m_now()" + " RETURNING id;", + quoted_name, + quoted_comment, + quoted_report_format_id, + current_credentials.uuid); + + g_free (quoted_name); + g_free (quoted_comment); + g_free (quoted_report_format_id); + + for (int i = 0; g_ptr_array_index (params, i); i++) + { + report_config_param_data_t *param; + param = g_ptr_array_index (params, i); + + // Skip params that use default value + if (param->use_default_value) + continue; + + if (validate_report_config_param (param, report_format, error_message)) + { + sql_rollback (); + return 4; + } + insert_report_config_param (*report_config, param); + } + sql_commit (); + return 0; +} + +/* MODIFY_REPORT_CONFIG */ + +/** + * @brief Modify a report config. + * + * @param[in] report_config_id UUID of report config to modify. + * @param[in] name Name of report config. + * @param[in] comment Comment of report config. + * @param[in] params Array of params. + * @param[out] report_config Created report config. + * @param[out] error_message Message for some errors like invalid params. + * + * @return 0 success, + * 1 report config not found, + * 2 report config with same name already exists, + * 3 cannot modify params of orphaned report config, + * 4 param validation failed, + * 99 permission denied, + * -1 internal error. + */ +int +modify_report_config (const char *report_config_id, + const char *new_name, + const char *new_comment, + array_t *params, + gchar **error_message) +{ + report_config_t report_config; + + sql_begin_immediate (); + + if (acl_user_may ("modify_report_config") == 0) + { + sql_rollback (); + return 99; + } + + report_config = 0; + if (find_report_config_with_permission (report_config_id, &report_config, + "modify_report_format")) + { + sql_rollback (); + return -1; + } + + if (report_config == 0) + { + sql_rollback (); + return 1; + } + + if (new_name) + { + gchar *quoted_name = sql_quote(new_name); + + if (sql_int ("SELECT count(*) FROM report_configs" + " WHERE name = '%s' AND id != %llu", + quoted_name, report_config)) + { + g_free (quoted_name); + sql_rollback (); + return 2; + } + + sql ("UPDATE report_configs SET name = '%s' WHERE id = %llu", + quoted_name, report_config); + g_free (quoted_name); + } + + if (new_comment) + { + gchar *quoted_comment = sql_quote(new_comment); + sql ("UPDATE report_configs SET comment = '%s' WHERE id = %llu", + quoted_comment, report_config); + g_free (quoted_comment); + } + + if (params->len) + { + report_format_t report_format; + report_format = sql_int64_0 ("SELECT id FROM report_formats" + " WHERE uuid = (SELECT report_format_id" + " FROM report_configs" + " WHERE id = %llu)", + report_config); + if (report_config == 0) + { + sql_rollback (); + return 3; + } + + for (int i = 0; g_ptr_array_index (params, i); i++) + { + report_config_param_data_t *param; + param = g_ptr_array_index (params, i); + + // Delete params meant to use default value + if (param->use_default_value) + { + gchar *quoted_param_name = sql_quote (param->name); + sql ("DELETE FROM report_config_params" + " WHERE report_config = %llu AND name = '%s'", + report_config, quoted_param_name); + continue; + } + else + { + if (validate_report_config_param (param, report_format, + error_message)) + { + sql_rollback (); + return 4; + } + insert_report_config_param (report_config, param); + } + } + } + + sql ("UPDATE report_configs" + " SET modification_time = m_now ()" + " WHERE id = %llu", + report_config); + + sql_commit (); + return 0; +} + + +/* DELETE_REPORT_CONFIG and RESTORE */ + +/** + * @brief Delete a report config. + * + * @param[in] report_config_id UUID of Report config. + * @param[in] ultimate Whether to remove entirely, or to trashcan. + * + * @return 0 success, 1 report config in use, 2 failed to find report config, + * 99 permission denied, -1 error. + */ +int +delete_report_config (const char *report_config_id, int ultimate) +{ + report_config_t report_config, trash_report_config; + + sql_begin_immediate (); + + if (acl_user_may ("delete_report_config") == 0) + { + sql_rollback (); + return 99; + } + + /* Look in the "real" table. */ + + if (find_report_config_with_permission (report_config_id, &report_config, + "delete_report_config")) + { + g_message("find failed"); + sql_rollback (); + return -1; + } + + if (report_config == 0) + { + /* Look in the trashcan. */ + + if (find_trash ("report_config", report_config_id, &report_config)) + { + g_message("find trash failed"); + sql_rollback (); + return -1; + } + if (report_config == 0) + { + sql_rollback (); + return 2; + } + if (ultimate == 0) + { + /* It's already in the trashcan. */ + sql_commit (); + return 0; + } + + /* Check if it's in use by a trash alert. */ + + if (trash_report_config_in_use (report_config)) + { + sql_rollback (); + return 1; + } + + /* Remove entirely. */ + + permissions_set_orphans ("report_config", report_config, LOCATION_TRASH); + tags_remove_resource ("report_config", report_config, LOCATION_TRASH); + + sql ("DELETE FROM report_config_params_trash WHERE report_config = %llu;", + report_config); + sql ("DELETE FROM report_configs_trash WHERE id = %llu;", + report_config); + + sql_commit (); + + return 0; + } + + if (ultimate) + { + permissions_set_orphans ("report_config", report_config, LOCATION_TABLE); + tags_remove_resource ("report_config", report_config, LOCATION_TABLE); + + /* Check if it's in use by a trash or regular alert. */ + + if (report_config_in_use (report_config)) + { + sql_rollback (); + return 1; + } + + /* Remove from "real" tables. */ + + sql ("DELETE FROM report_config_params WHERE report_config = %llu;", + report_config); + sql ("DELETE FROM report_configs WHERE id = %llu;", + report_config); + } + else + { + /* Check if it's in use by a regular alert. */ + + if (report_config_in_use (report_config)) + { + sql_rollback (); + return 1; + } + + /* Move to trash. */ + + sql ("INSERT INTO report_configs_trash" + " (uuid, owner, name, comment, creation_time, modification_time," + " report_format_id)" + " SELECT" + " uuid, owner, name, comment, creation_time, modification_time," + " report_format_id" + " FROM report_configs" + " WHERE id = %llu;", + report_config); + + trash_report_config = sql_last_insert_id (); + + sql ("INSERT INTO report_config_params_trash" + " (report_config, name, value)" + " SELECT %llu, name, value" + " FROM report_config_params" + " WHERE report_config = %llu;", + trash_report_config, report_config); + + permissions_set_locations ("report_config", report_config, + trash_report_config, LOCATION_TRASH); + tags_set_locations ("report_config", report_config, + trash_report_config, LOCATION_TRASH); + + /* Remove from "real" tables. */ + + sql ("DELETE FROM report_config_params WHERE report_config = %llu", + report_config); + sql ("DELETE FROM report_configs WHERE id = %llu", + report_config); + } + + sql_commit (); + + return 0; +} + +/** + * @brief Delete all report configs owned by a user. + * + * @param[in] user The user. + */ +void +delete_report_configs_user (user_t user) +{ + sql ("DELETE FROM report_config_params" + " WHERE report_config IN" + " (SELECT id FROM report_configs WHERE owner = %llu)", + user); + sql ("DELETE FROM report_configs WHERE owner = %llu;", user); + + sql ("DELETE FROM report_config_params_trash" + " WHERE report_config IN" + " (SELECT id FROM report_configs_trash WHERE owner = %llu)", + user); + sql ("DELETE report_configs_trash WHERE owner = %llu;", user); +} + +/** + * @brief Try restore a report config. + * + * If success, ends transaction for caller before exiting. + * + * @param[in] report_config_id UUID of resource. + * + * @return 0 success, 1 fail because resource is in use, 2 failed to find + * resource, 4 fail because resource with UUID exists, -1 error. + */ +int +restore_report_config (const char *report_config_id) +{ + report_config_t resource, report_config; + + if (find_trash ("report_config", report_config_id, &resource)) + { + sql_rollback (); + return -1; + } + + if (resource == 0) + return 2; + + if (sql_int ("SELECT count(*) FROM report_configs" + " WHERE name =" + " (SELECT name FROM report_configs_trash WHERE id = %llu)" + " AND " ACL_USER_OWNS () ";", + resource, + current_credentials.uuid)) + { + sql_rollback (); + return 3; + } + + if (sql_int ("SELECT count(*) FROM report_configs" + " WHERE uuid = (SELECT uuid" + " FROM report_configs_trash" + " WHERE id = %llu);", + resource)) + { + sql_rollback (); + return 4; + } + + /* Move to "real" tables. */ + + sql ("INSERT INTO report_configs" + " (uuid, owner, name, comment, creation_time, modification_time," + " report_format_id)" + " SELECT" + " uuid, owner, name, comment, creation_time, modification_time," + " report_format_id" + " FROM report_configs_trash" + " WHERE id = %llu;", + resource); + + report_config = sql_last_insert_id (); + + sql ("INSERT INTO report_config_params" + " (report_config, name, value)" + " SELECT %llu, name, value" + " FROM report_config_params_trash" + " WHERE report_config = %llu;", + report_config, + resource); + + permissions_set_locations ("report_config", resource, report_config, + LOCATION_TABLE); + tags_set_locations ("report_config", resource, report_config, + LOCATION_TABLE); + + /* Remove from trash tables. */ + + sql ("DELETE FROM report_config_params_trash WHERE report_config = %llu;", + resource); + sql ("DELETE FROM report_configs_trash WHERE id = %llu;", + resource); + + sql_commit (); + return 0; +} + + +/* GET_REPORT_FORMATS */ + +/** + * @brief Filter columns for Report Config iterator. + */ +#define REPORT_CONFIG_ITERATOR_FILTER_COLUMNS \ + { GET_ITERATOR_FILTER_COLUMNS, "report_format_id", "report_config", \ + NULL } + +/** + * @brief Report Config iterator columns. + */ +#define REPORT_CONFIG_ITERATOR_COLUMNS \ + { \ + { "id", NULL, KEYWORD_TYPE_INTEGER }, \ + { "uuid", NULL, KEYWORD_TYPE_STRING }, \ + { "name", NULL, KEYWORD_TYPE_STRING }, \ + { "comment", NULL, KEYWORD_TYPE_STRING }, \ + { "iso_time (creation_time)", NULL, KEYWORD_TYPE_STRING }, \ + { "iso_time (modification_time)", NULL, KEYWORD_TYPE_STRING }, \ + { "creation_time", "created", KEYWORD_TYPE_INTEGER }, \ + { "modification_time", "modified", KEYWORD_TYPE_INTEGER }, \ + { \ + "(SELECT name FROM users WHERE users.id = report_configs.owner)", \ + "_owner", \ + KEYWORD_TYPE_STRING \ + }, \ + { "owner", NULL, KEYWORD_TYPE_INTEGER }, \ + { "report_format_id", NULL, KEYWORD_TYPE_STRING }, \ + { \ + "(SELECT name FROM report_formats" \ + " WHERE report_formats.uuid = report_format_id)", \ + "report_format", \ + KEYWORD_TYPE_STRING, \ + }, \ + { \ + "(SELECT id FROM report_formats" \ + " WHERE report_formats.uuid = report_format_id)", \ + "report_format", \ + KEYWORD_TYPE_INTEGER, \ + }, \ + { NULL, NULL, KEYWORD_TYPE_UNKNOWN } \ + } + +/** + * @brief Report Config iterator columns for trash case. + */ +#define REPORT_CONFIG_ITERATOR_TRASH_COLUMNS \ + { \ + { "id", NULL, KEYWORD_TYPE_INTEGER }, \ + { "uuid", NULL, KEYWORD_TYPE_STRING }, \ + { "name", NULL, KEYWORD_TYPE_STRING }, \ + { "comment", NULL, KEYWORD_TYPE_STRING }, \ + { "iso_time (creation_time)", NULL, KEYWORD_TYPE_STRING }, \ + { "iso_time (modification_time)", NULL, KEYWORD_TYPE_STRING }, \ + { "creation_time", "created", KEYWORD_TYPE_INTEGER }, \ + { "modification_time", "modified", KEYWORD_TYPE_INTEGER }, \ + { \ + "(SELECT name FROM users WHERE users.id = report_configs_trash.owner)",\ + "_owner", \ + KEYWORD_TYPE_STRING \ + }, \ + { "owner", NULL, KEYWORD_TYPE_INTEGER }, \ + { "report_format_id", NULL, KEYWORD_TYPE_STRING }, \ + { \ + "(SELECT name FROM report_formats" \ + " WHERE report_formats.uuid = report_format_id)", \ + "report_format", \ + KEYWORD_TYPE_STRING, \ + }, \ + { \ + "(SELECT id FROM report_formats" \ + " WHERE report_formats.uuid = report_format_id)", \ + "report_format", \ + KEYWORD_TYPE_INTEGER, \ + }, \ + } + +/** + * @brief Count the number of Report Configs. + * + * @param[in] get GET params. + * + * @return Total number of Report Config filtered set. + */ +int +report_config_count (const get_data_t *get) +{ + static const char *filter_columns[] = REPORT_CONFIG_ITERATOR_FILTER_COLUMNS; + static column_t columns[] = REPORT_CONFIG_ITERATOR_COLUMNS; + static column_t trash_columns[] = REPORT_CONFIG_ITERATOR_TRASH_COLUMNS; + return count ("report_config", get, columns, trash_columns, filter_columns, + 0, 0, 0, TRUE); +} + +/** + * @brief Initialise a Report Config iterator, including observed Report + * Configs. + * + * @param[in] iterator Iterator. + * @param[in] get GET data. + * + * @return 0 success, 1 failed to find Report Config, 2 failed to find filter, + * -1 error. + */ +int +init_report_config_iterator (iterator_t* iterator, const get_data_t *get) +{ + static const char *filter_columns[] = REPORT_CONFIG_ITERATOR_FILTER_COLUMNS; + static column_t columns[] = REPORT_CONFIG_ITERATOR_COLUMNS; + static column_t trash_columns[] = REPORT_CONFIG_ITERATOR_TRASH_COLUMNS; + + return init_get_iterator (iterator, + "report_config", + get, + columns, + trash_columns, + filter_columns, + 0, + NULL, + NULL, + TRUE); +} + +/** + * @brief Get the report format id from a report config iterator. + * + * @param[in] iterator Iterator. + * + * @return Extension, or NULL if iteration is complete. Freed by + * cleanup_iterator. + */ +const char * +report_config_iterator_report_format_id (iterator_t *iterator) +{ + if (iterator->done) + return NULL; + return iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT); +} + +/** + * @brief Return the report format readable state from a report config iterator. + * + * @param[in] iterator Iterator. + * + * @return Whether report format is readable. + */ +int +report_config_iterator_report_format_readable (iterator_t* iterator) +{ + const char *report_format_id; + + if (iterator->done) return 0; + + report_format_id + = report_config_iterator_report_format_id (iterator); + + if (report_format_id) + { + int readable; + readable = acl_user_has_access_uuid + ("filter", report_format_id, "get_report_formats", 0); + return readable; + } + return 0; +} + +/** + * @brief Get the report format name from a report config iterator. + * + * @param[in] iterator Iterator. + * + * @return Report format name, or NULL if iteration is complete. Freed by + * cleanup_iterator. + */ +const char * +report_config_iterator_report_format_name (iterator_t *iterator) +{ + if (iterator->done) + return NULL; + return iterator_string (iterator, GET_ITERATOR_COLUMN_COUNT + 1); +} + +/** + * @brief Get the report format row id from a report config iterator. + * + * @param[in] iterator Iterator. + * + * @return Report format, or 0 if iteration is complete or report format + * does not exist. + */ +report_format_t +report_config_iterator_report_format (iterator_t *iterator) +{ + if (iterator->done) + return 0; + return iterator_int64 (iterator, GET_ITERATOR_COLUMN_COUNT + 2); +} + +/** + * @brief Initialise an interator of Report Config params. + * + * @param[in] iterator Iterator. + * @param[in] report_config The report config to get params of. + * @param[in] trash Whether to get report config from trash. + */ +void +init_report_config_param_iterator (iterator_t *iterator, + report_config_t report_config, + int trash) +{ + report_format_t report_format; + + report_format = report_config_report_format (report_config); + + init_iterator (iterator, + "SELECT rcp.id, rfp.name, rfp.type," + " coalesce (rcp.value, rfp.value, rfp.fallback)," + " coalesce (rfp.value, rfp.fallback)," + " rfp.type_min, rfp.type_max, rfp.id," + " (rcp.id IS NULL)" + " FROM report_format_params AS rfp" + " LEFT JOIN report_config_params%s AS rcp" + " ON rcp.name = rfp.name" + " AND rcp.report_config = %llu" + " WHERE rfp.report_format = %llu", + trash ? "_trash" : "", + report_config, report_format); +} + +/** + * @brief Get the parameter row id from a report config param iterator. + * + * @param[in] iterator Iterator. + * + * @return Param row id, or 0 if iteration is complete. + */ +report_config_param_t +report_config_param_iterator_rowid (iterator_t *iterator) +{ + if (iterator->done) + return 0; + return iterator_int64 (iterator, 0); +} + +/** + * @brief Get the parameter name from a report config param iterator. + * + * @param[in] iterator Iterator. + * + * @return Name, or NULL if iteration is complete. Freed by + * cleanup_iterator. + */ +const char* +report_config_param_iterator_name (iterator_t *iterator) +{ + if (iterator->done) + return NULL; + return iterator_string (iterator, 1); +} + +/** + * @brief Get the parameter type from a report config param iterator. + * + * @param[in] iterator Iterator. + * + * @return Param type, or REPORT_FORMAT_PARAM_TYPE_ERROR + * if iteration is complete. + */ +report_format_param_type_t +report_config_param_iterator_type (iterator_t *iterator) +{ + if (iterator->done) + return REPORT_FORMAT_PARAM_TYPE_ERROR; + return iterator_int (iterator, 2); +} + +/** + * @brief Get the parameter type name from a report config param iterator. + * + * @param[in] iterator Iterator. + * + * @return Param type name, or NULL if iteration is complete. + */ +const char* +report_config_param_iterator_type_name (iterator_t *iterator) +{ + if (iterator->done) + return NULL; + return report_format_param_type_name (iterator_int (iterator, 2)); +} + +/** + * @brief Get the parameter value from a report config param iterator. + * + * @param[in] iterator Iterator. + * + * @return Name, or NULL if iteration is complete. Freed by + * cleanup_iterator. + */ +const char* +report_config_param_iterator_value (iterator_t *iterator) +{ + if (iterator->done) + return NULL; + return iterator_string (iterator, 3); +} + +/** + * @brief Get the parameter fallback value from a report config param iterator. + * + * @param[in] iterator Iterator. + * + * @return Fallback value, or NULL if iteration is complete. Freed by + * cleanup_iterator. + */ +const char* +report_config_param_iterator_fallback_value (iterator_t *iterator) +{ + if (iterator->done) + return NULL; + return iterator_string (iterator, 4); +} + +/** + * @brief Get the minimum value or length from a report config param iterator. + * + * @param[in] iterator Iterator. + * + * @return Minimum value/length, or NULL if iteration is complete. Freed by + * cleanup_iterator. + */ +long long int +report_config_param_iterator_type_min (iterator_t *iterator) +{ + if (iterator->done) + return -1; + return iterator_int64 (iterator, 5); +} + +/** + * @brief Get the maximum value or length from a report config param iterator. + * + * @param[in] iterator Iterator. + * + * @return Maximum value/length, or NULL if iteration is complete. Freed by + * cleanup_iterator. + */ +long long int +report_config_param_iterator_type_max (iterator_t *iterator) +{ + if (iterator->done) + return -1; + return iterator_int64 (iterator, 6); +} + +/** + * @brief Get the report format parameter row id from a + * report config param iterator. + * + * @param[in] iterator Iterator. + * + * @return Report format param row id, or 0 if iteration is complete. + */ +report_format_param_t +report_config_param_iterator_format_param (iterator_t *iterator) +{ + if (iterator->done) + return 0; + return iterator_int64 (iterator, 7); +} + +/** + * @brief Get if a report format param is using the default fallback value. + * + * @param[in] iterator Iterator. + * + * @return 1 if using fallback, or 0 if not or iteration is complete. + */ +int +report_config_param_iterator_using_default (iterator_t *iterator) +{ + if (iterator->done) + return 0; + return iterator_int (iterator, 8); +} + +/* Misc. functions */ + +/** + * @brief Return the UUID of a config config. + * + * @param[in] report_config Report config. + * + * @return Newly allocated UUID. + */ +char * +report_config_uuid (report_config_t report_config) +{ + return sql_string ("SELECT uuid FROM report_configs WHERE id = %llu;", + report_config); +} + +/** + * @brief Return the report format of a report config. + * + * @param[in] report_config Report config. + * + * @return Newly allocated UUID. + */ +report_format_t +report_config_report_format (report_config_t report_config) +{ + return sql_int64_0 ("SELECT id FROM report_formats" + " WHERE uuid = (SELECT report_format_id" + " FROM report_configs WHERE id = %llu);", + report_config); +} + +/** + * @brief Return whether a report config is referenced by an alert. + * + * @param[in] report_config Report Config. + * + * @return 1 if in use, else 0. + */ +int +report_config_in_use (report_config_t report_config) +{ + return 0; +} + +/** + * @brief Return whether a report config in trash is referenced by an alert. + * + * @param[in] report_config Report Config. + * + * @return 1 if in use, else 0. + */ +int +trash_report_config_in_use (report_config_t report_config) +{ + return 0; +} + +/** + * @brief Get filter columns. + * + * @return Constant array of filter columns. + */ +const char** +report_config_filter_columns () +{ + static const char *columns[] = REPORT_CONFIG_ITERATOR_FILTER_COLUMNS; + return columns; +} + +/** + * @brief Get select columns. + * + * @return Constant array of select columns. + */ +column_t* +report_config_select_columns () +{ + static column_t columns[] = REPORT_CONFIG_ITERATOR_COLUMNS; + return columns; +} diff --git a/src/manage_sql_report_configs.h b/src/manage_sql_report_configs.h new file mode 100644 index 0000000000..a95d05ed7e --- /dev/null +++ b/src/manage_sql_report_configs.h @@ -0,0 +1,45 @@ +/* Copyright (C) 2024 Greenbone AG + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef _GVMD_MANAGE_SQL_REPORT_CONFIGS_H +#define _GVMD_MANAGE_SQL_REPORT_CONFIGS_H + +#include "manage.h" +#include "manage_sql.h" + +#include + + +const char** +report_config_filter_columns (); + +column_t* +report_config_select_columns (); + +int +restore_report_config (const char *); + +void +delete_report_configs_user (user_t); + +gboolean +inherit_report_configs (user_t, user_t); + + + +#endif /* not _GVMD_MANAGE_SQL_REPORT_CONFIGS_H */ diff --git a/src/manage_sql_report_formats.c b/src/manage_sql_report_formats.c index 89b23c4ca7..0a0d51c7a7 100644 --- a/src/manage_sql_report_formats.c +++ b/src/manage_sql_report_formats.c @@ -64,10 +64,6 @@ sync_report_formats_with_feed (gboolean); /* Static headers. */ -static int -validate_param_value (report_format_t, report_format_param_t param, const char *, - const char *); - static void set_report_format_name (report_format_t, const char *); @@ -808,12 +804,14 @@ add_report_format_params (report_format_t report_format, array_t *params, } } - if (validate_param_value (report_format, param_rowid, param->name, - param->value)) + if (report_format_validate_param_value (report_format, param_rowid, + param->name, param->value, + NULL)) return 3; - if (validate_param_value (report_format, param_rowid, param->name, - param->fallback)) + if (report_format_validate_param_value (report_format, param_rowid, + param->name, param->fallback, + NULL)) return 4; } @@ -2414,13 +2412,16 @@ report_format_param_type_min (report_format_t report_format, const char *name) * @param[in] param Param. * @param[in] name Name of param. * @param[in] value Potential value of param. + * @param[out] error_message Pointer for error message or NULL. * * @return 0 success, 1 fail. */ -static int -validate_param_value (report_format_t report_format, - report_format_param_t param, const char *name, - const char *value) +int +report_format_validate_param_value (report_format_t report_format, + report_format_param_t param, + const char *name, + const char *value, + gchar **error_message) { switch (report_format_param_type (report_format, name)) { @@ -2431,10 +2432,28 @@ validate_param_value (report_format_t report_format, /* Simply truncate out of range values. */ actual = strtoll (value, NULL, 0); if (actual < min) - return 1; + { + if (error_message) + { + *error_message + = g_strdup_printf ("value of param \"%s\"" + " is below minimum (%lld < %lld)", + name, actual, min); + } + return 1; + } max = report_format_param_type_max (report_format, name); if (actual > max) - return 1; + { + if (error_message) + { + *error_message + = g_strdup_printf ("value of param \"%s\"" + " is above maximum (%lld > %lld)", + name, actual, max); + } + return 1; + } } break; case REPORT_FORMAT_PARAM_TYPE_SELECTION: @@ -2454,6 +2473,13 @@ validate_param_value (report_format_t report_format, cleanup_iterator (&options); if (found) break; + if (error_message) + { + *error_message + = g_strdup_printf ("value of param \"%s\"" + " is not a valid selection option", + name); + } return 1; } case REPORT_FORMAT_PARAM_TYPE_STRING: @@ -2463,10 +2489,28 @@ validate_param_value (report_format_t report_format, min = report_format_param_type_min (report_format, name); actual = strlen (value); if (actual < min) - return 1; + { + if (error_message) + { + *error_message + = g_strdup_printf ("value of param \"%s\"" + " is too short (%lld < %lld)", + name, actual, min); + } + return 1; + } max = report_format_param_type_max (report_format, name); if (actual > max) - return 1; + { + if (error_message) + { + *error_message + = g_strdup_printf ("value of param \"%s\"" + " is too long (%lld > %lld)", + name, actual, min); + } + return 1; + } } break; case REPORT_FORMAT_PARAM_TYPE_REPORT_FORMAT_LIST: @@ -2474,7 +2518,16 @@ validate_param_value (report_format_t report_format, if (g_regex_match_simple ("^(?:[[:alnum:]\\-_]+)?(?:,(?:[[:alnum:]\\-_])+)*$", value, 0, 0) == FALSE) - return 1; + { + if (error_message) + { + *error_message + = g_strdup_printf ("value of param \"%s\"" + " is not a valid UUID list", + name); + } + return 1; + } else return 0; } @@ -2542,7 +2595,8 @@ set_report_format_param (report_format_t report_format, const char *name, /* Validate the value. */ - if (validate_param_value (report_format, param, name, value)) + if (report_format_validate_param_value (report_format, param, + name, value, NULL)) { sql_rollback (); g_free (quoted_name); @@ -2588,7 +2642,7 @@ report_format_trust (report_format_t report_format) #define REPORT_FORMAT_ITERATOR_FILTER_COLUMNS \ { ANON_GET_ITERATOR_FILTER_COLUMNS, "name", "extension", "content_type", \ "summary", "description", "trust", "trust_time", "active", "predefined", \ - NULL } + "configurable", NULL } /** * @brief Report Format iterator columns. @@ -2616,6 +2670,12 @@ report_format_trust (report_format_t report_format) { "signature", NULL, KEYWORD_TYPE_STRING }, \ { "trust", NULL, KEYWORD_TYPE_INTEGER }, \ { "trust_time", NULL, KEYWORD_TYPE_INTEGER }, \ + { \ + "(SELECT count(*) > 0 FROM report_format_params" \ + " WHERE report_format = report_formats.id)", \ + "configurable", \ + KEYWORD_TYPE_INTEGER \ + }, \ { "flags & 1", "active", KEYWORD_TYPE_INTEGER }, \ { "predefined", NULL, KEYWORD_TYPE_INTEGER }, \ { NULL, NULL, KEYWORD_TYPE_UNKNOWN } \ @@ -2648,6 +2708,12 @@ report_format_trust (report_format_t report_format) { "signature", NULL, KEYWORD_TYPE_STRING }, \ { "trust", NULL, KEYWORD_TYPE_INTEGER }, \ { "trust_time", NULL, KEYWORD_TYPE_INTEGER }, \ + { \ + "(SELECT count(*) > 0 FROM report_format_params_trash" \ + " WHERE report_format = report_formats_trash.id)", \ + "configurable", \ + KEYWORD_TYPE_INTEGER \ + }, \ { "flags & 1", "active", KEYWORD_TYPE_INTEGER }, \ { "predefined", NULL, KEYWORD_TYPE_INTEGER }, \ { NULL, NULL, KEYWORD_TYPE_UNKNOWN } \ @@ -2809,6 +2875,22 @@ report_format_iterator_trust_time (iterator_t* iterator) return ret; } +/** + * @brief Get whether a report format is configurable from an iterator. + * + * @param[in] iterator Iterator. + * + * @return Time report format was verified. + */ +int +report_format_iterator_configurable (iterator_t* iterator) +{ + int ret; + if (iterator->done) return -1; + ret = iterator_int (iterator, GET_ITERATOR_COLUMN_COUNT + 7); + return ret; +} + /** * @brief Get the active flag from a report format iterator. * @@ -2898,6 +2980,82 @@ report_format_alert_iterator_readable (iterator_t* iterator) return iterator_int (iterator, 2); } +/** + * @brief Initialise a Report Format alert iterator. + * + * Iterates over all alerts that use the Report Format. + * + * @param[in] iterator Iterator. + * @param[in] report_format Report Format. + */ +void +init_report_format_report_config_iterator (iterator_t* iterator, + const char *report_format_id) +{ + gchar *quoted_report_format_id; + gchar *available, *with_clause; + get_data_t get; + array_t *permissions; + + assert (report_format_id); + + get.trash = 0; + permissions = make_array (); + array_add (permissions, g_strdup ("get_report_configs")); + available = acl_where_owned ("report_config", &get, 1, "any", 0, permissions, + 0, &with_clause); + array_free (permissions); + + quoted_report_format_id = sql_quote (report_format_id); + init_iterator (iterator, + "%s" + " SELECT DISTINCT report_configs.name, report_configs.uuid, %s" + " FROM report_configs" + " WHERE report_configs.report_format_id = '%s'" + " ORDER BY report_configs.name ASC;", + with_clause ? with_clause : "", + available, + quoted_report_format_id); + + g_free (quoted_report_format_id); + g_free (with_clause); + g_free (available); +} + +/** + * @brief Get the name from a report_format_report_config iterator. + * + * @param[in] iterator Iterator. + * + * @return The name of the Report Config, or NULL if iteration is complete. + * Freed by cleanup_iterator. + */ +DEF_ACCESS (report_format_report_config_iterator_name, 0); + +/** + * @brief Get the UUID from a report_format_report_config iterator. + * + * @param[in] iterator Iterator. + * + * @return The UUID of the Report Config, or NULL if iteration is complete. + * Freed by cleanup_iterator. + */ +DEF_ACCESS (report_format_report_config_iterator_uuid, 1); + +/** + * @brief Get the read permission status from a GET iterator. + * + * @param[in] iterator Iterator. + * + * @return 1 if may read, else 0. + */ +int +report_format_report_config_iterator_readable (iterator_t* iterator) +{ + if (iterator->done) return 0; + return iterator_int (iterator, 2); +} + /** * @brief Initialise a report format iterator. * diff --git a/src/manage_utils.c b/src/manage_utils.c index 70bb933e62..674eb0008e 100644 --- a/src/manage_utils.c +++ b/src/manage_utils.c @@ -315,6 +315,7 @@ valid_db_resource_type (const char* type) || (strcasecmp (type, "port_list") == 0) || (strcasecmp (type, "permission") == 0) || (strcasecmp (type, "report") == 0) + || (strcasecmp (type, "report_config") == 0) || (strcasecmp (type, "report_format") == 0) || (strcasecmp (type, "result") == 0) || (strcasecmp (type, "role") == 0) diff --git a/src/schema_formats/XML/GMP.xml.in b/src/schema_formats/XML/GMP.xml.in index 1137994ba1..38d4a0d1c2 100644 --- a/src/schema_formats/XML/GMP.xml.in +++ b/src/schema_formats/XML/GMP.xml.in @@ -4800,6 +4800,121 @@ along with this program. If not, see . + + create_report_config + Create a report config + +

+ The client uses the create_report_config command to create a new report + config. +

+
+ + name + comment + copy + report_format + param + + + name + A name for the report config + name + + + comment + A comment on the report config + + text + + + + copy + The UUID of an existing report config + + uuid + + + + report_format + + The report format the config applies to. Must be configurable + + + + id + uuid + 1 + + + + + param + A parameter to pass to the report format + + name + value + + + name + Name of the parameter + text + + + value + Value of the parameter + + text + + use_default + boolean + + Whether to use the default instead of the given value + + + + + + + + + status + status + 1 + + + status_text + text + 1 + + + id + uuid + 1 + + + + + Create a report config + + + Test config + + + Node Distance + 10 + + Test comment + + + + + + + +
create_report_format Create a report format @@ -6651,6 +6766,58 @@ END:VCALENDAR + + delete_report_config + Delete a report config + +

+ The client uses the delete_report_config command to delete an existing + report config. +

+

+ Since this is a destructive command, the client is advised to ask + for confirmation from the user before sending this command to the + Manager. +

+
+ + + report_config_id + uuid + 1 + + + ultimate + Whether to remove entirely, or to the trashcan + boolean + 1 + + + + + + status + status + 1 + + + status_text + text + 1 + + + + + Delete a report config + + + + + + + + +
delete_report_format Delete a report format @@ -15476,18 +15643,18 @@ END:VCALENDAR - get_report_formats - Get one or many report formats + get_report_configs + Get one or many report configs

- The client uses the get_report_formats command to get report format + The client uses the get_report_configs command to get report config information.

- report_format_id - ID of single report format to get + report_config_id + ID of single report config to get uuid @@ -15558,46 +15725,6 @@ END:VCALENDAR name Name of the owner - - extension - text - File extension of the report format - - - content_type - text - Content type of the report format - - - summary - text - Short summary of the report format - - - description - text - Description of the report format - - - trust - boolean - Whether the report format is trusted - - - trust_time - iso_time - Time the report format was last verified - - - active - boolean - Whether the report format is active - - - predefined - boolean - Whether the report format was created from the feed - @@ -15607,22 +15734,17 @@ END:VCALENDAR trash - Whether to get the trashcan report formats instead + Whether to get the trashcan report configs instead boolean alerts - Whether to include alerts that use the report format - boolean - - - params - Whether to include report format parameters + Whether to include alerts that use the report config boolean details - Include report format file, signature and parameters + Include report config details boolean @@ -15638,14 +15760,14 @@ END:VCALENDAR text 1 - report_format + report_config filters sort - report_formats - report_format_count + report_configs + report_config_count - report_format + report_config id @@ -15654,32 +15776,21 @@ END:VCALENDAR owner name + comment creation_time modification_time writable in_use permissions user_tags - extension - content_type - summary - description + report_format + orphan alerts - - - file - signature - - - trust - active - predefined - deprecated param owner - Owner of the report format + Owner of the report config name @@ -15691,9 +15802,14 @@ END:VCALENDAR name - The name of the report format + The name of the report config name + + comment + The comment of the report config + text + creation_time iso_time @@ -15704,18 +15820,18 @@ END:VCALENDAR writable - Whether the report format is global or in use + Whether the report config is global or in use boolean in_use - Whether any alerts are using the report format + Whether any alerts are using the report config boolean permissions - Permissions that the current user has on the report format + Permissions that the current user has on the report config permission @@ -15734,7 +15850,7 @@ END:VCALENDAR user_tags - Info on tags attached to the report format + Info on tags attached to the report config count tag @@ -15779,24 +15895,39 @@ END:VCALENDAR - summary - text - - - description - text - - - extension - text + report_format + Report format the config will provide params for + + + id + uuid + UUID of the report format + 1 + + name + permissions + + + name + Name of the report format if it exists + name + + + permissions + Permissions the user has on the report format + + - content_type - text + orphan + Whether the report format of the config is missing + + boolean + alerts - Alerts using the report format + Alerts using the report config alert @@ -15819,7 +15950,7 @@ END:VCALENDAR permissions - Permissions the user has on the permission + Permissions the user has on the alert @@ -15921,11 +16052,625 @@ END:VCALENDAR The report format signature text - - trust - Whether signature verification succeeded - - + + + filters + + + id + UUID of filter if any, else 0 + uuid + 1 + + term + name + keywords + + + term + Filter term + text + + + name + Filter name, if applicable + text + + + keywords + Filter broken down into keywords + keyword + + keyword + + column + relation + value + + + column + Column prefix + text + + + relation + Relation operator + + + = + : + ~ + > + < + + + + + value + The filter text + text + + + + + + sort + + text + field + + + field + + order + + + order + + + ascending + descending + + + + + + + report_configs + + + start + First report config + integer + 1 + + + max + Maximum number of report configs + integer + 1 + + + + + report_config_count + + filtered + page + + + filtered + Number of report configs after filtering + integer + + + page + Number of report configs on current page + integer + + + + + Get information about a report config + + + + + + + + + admin + + Test config + Test comment + 2024-01-23T09:43:03Z + 2024-01-26T14:11:54Z + 1 + 0 + + + Everything + + + + Topology SVG + + + Graph Type + selection + dot + twopi + + + + + + + + Node Distance + integer120 + 8 + 8 + + + ... + + + +
+ + get_report_formats + Get one or many report formats + +

+ The client uses the get_report_formats command to get report format + information. +

+
+ + + report_format_id + ID of single report format to get + uuid + + + filter + Filter term to use to filter query + text + + + + + + + tag + text + + Name and optional "=" separted value of an attached tag + (e.g. "mytag" or "mytag=myvalue") + + + + tag_id + UUID + + UUID of an attached tag + + + + uuid + uuid + Unique ID + + + name + name + Name + + + created + iso_time + Creation time + + + modified + iso_time + Modification time + + + owner + name + Name of the owner + + + extension + text + File extension of the report format + + + content_type + text + Content type of the report format + + + summary + text + Short summary of the report format + + + description + text + Description of the report format + + + trust + boolean + Whether the report format is trusted + + + trust_time + iso_time + Time the report format was last verified + + + active + boolean + Whether the report format is active + + + predefined + boolean + Whether the report format was created from the feed + + + + + filt_id + ID of filter to use to filter query + uuid + + + trash + Whether to get the trashcan report formats instead + boolean + + + alerts + Whether to include alerts that use the report format + boolean + + + params + Whether to include report format parameters + boolean + + + details + Include report format file, signature and parameters + boolean + + + + + + status + status + 1 + + + status_text + text + 1 + + report_format + filters + sort + report_formats + report_format_count + + + report_format + + + id + uuid + 1 + + owner + name + creation_time + modification_time + writable + in_use + permissions + user_tags + extension + content_type + summary + description + alerts + + + file + signature + + + trust + active + predefined + configurable + deprecated + param + + + owner + Owner of the report format + + name + + + name + The name of the owner + name + + + + name + The name of the report format + name + + + creation_time + iso_time + + + modification_time + iso_time + + + writable + Whether the report format is global or in use + boolean + + + in_use + Whether any alerts are using the report format + boolean + + + permissions + + Permissions that the current user has on the report format + + + permission + + + permission + + name + + + name + The name of the permission + name + + + + + user_tags + Info on tags attached to the report format + + count + tag + + + count + Number of attached tags + integer + + + tag + + Short info on an individual tag + (only if details were requested) + + + + id + uuid + UUID of the tag + 1 + + name + value + comment + + + name + Name of the tag (usually namespace:predicate) + text + + + value + Value of the tag + text + + + comment + Comment for the tag + text + + + + + summary + text + + + description + text + + + extension + text + + + content_type + text + + + alerts + Alerts using the report format + + alert + + + alert + + + id + uuid + UUID of the alert + 1 + + name + permissions + + + name + Name of the alert + name + + + permissions + Permissions the user has on the permission + + + + + + param + + name + type + value + default + + + name + The name of the param + name + + + type + The type of the param + + min + max + options + + boolean + integer + selection + string + text + report_format_list + + + + min + Minimum + text + + + max + Maximum + text + + + options + Selection options + option + + option + Option value + text + + + + + value + The value of the param + + report_format + + + report_format + Report format info if type is report_format_list + + + id + uuid + 1 + + name + + + name + Name of the report format if available + text + + + + + default + The fallback value of the param + text + + + + file + One of the files used to generate the report + + + name + text + 1 + + base64 + + + + signature + The report format signature + text + + + trust + Whether signature verification succeeded + + name text 1 @@ -15953,6 +16698,11 @@ END:VCALENDAR Whether the report format was predefined by the feed boolean + + configurable + Whether the report format can be used with a report config + boolean + deprecated Whether the report format is deprecated @@ -17045,8 +17795,8 @@ END:VCALENDAR Type must be one of ALERT, CERT_BUND_ADV, CONFIG, CPE, CREDENTIAL, CVE, DFN_CERT_ADV, FILTER, GROUP, HOST, NOTE, NVT, OS, OVERRIDE, PERMISSION, - PORT_LIST, REPORT_FORMAT, REPORT, RESULT, ROLE, SCANNER, SCHEDULE, TARGET, - TASK, TLS_CERTIFICATE or USER + PORT_LIST, REPORT_CONFIG, REPORT_FORMAT, REPORT, RESULT, ROLE, SCANNER, + SCHEDULE, TARGET, TASK, TLS_CERTIFICATE or USER text 1 @@ -25768,6 +26518,98 @@ END:VCALENDAR
+ + modify_report_config + Modify an existing report config + +

+ The client uses the create_report_config command to change an existing + report config. +

+
+ + name + comment + param + + + name + A name for the report config. Omit to keep current one + name + + + comment + A comment on the report config. Omit to keep current one + + text + + + + param + + A parameter to pass to the report format. + Omit params to keep current value + + + name + value + + + name + Name of the parameter + text + + + value + Value of the parameter + + text + + use_default + boolean + + Whether to use the default instead of the given value + + + + + + + + + status + status + 1 + + + status_text + text + 1 + + + id + uuid + 1 + + + + + Rename a report config and reset a param to default + + + Renamed config + + Node Distance + + + + + + + + + +
modify_report_format Update an existing report format