From 477e217685c2f71bdae60fd8bb03d58ddd6d6e23 Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Wed, 14 Feb 2024 11:41:01 +0100 Subject: [PATCH] Add: Add new Report Config data type This adds GMP handlers for the new report config data type. The new data type will allow configuring parameters of predefined report formats when exporting reports or setting up alerts. --- src/gsad.c | 11 ++ src/gsad_gmp.c | 422 +++++++++++++++++++++++++++++++++++++++++++ src/gsad_gmp.h | 22 +++ src/gsad_validator.c | 21 ++- 4 files changed, 473 insertions(+), 3 deletions(-) diff --git a/src/gsad.c b/src/gsad.c index 4e7e76223..a0cb83268 100644 --- a/src/gsad.c +++ b/src/gsad.c @@ -348,6 +348,10 @@ params_append_mhd (params_t *params, const char *name, const char *filename, || (strncmp (name, "file:", strlen ("file:")) == 0) || (strncmp (name, "include_id_list:", strlen ("include_id_list:")) == 0) || (strncmp (name, "parameter:", strlen ("parameter:")) == 0) + || (strncmp (name, "param:", strlen ("param:")) == 0) + || (strncmp (name, + "param_using_default:", strlen ("param_using_default:")) + == 0) || (strncmp (name, "password:", strlen ("password:")) == 0) || (strncmp (name, "preference:", strlen ("preference:")) == 0) || (strncmp (name, "select:", strlen ("select:")) == 0) @@ -822,6 +826,7 @@ exec_gmp_post (http_connection_t *con, gsad_connection_info_t *con_info, ELSE (create_port_list) ELSE (create_port_range) ELSE (create_report) + ELSE (create_report_config) ELSE (create_scanner) ELSE (create_schedule) ELSE (create_task) @@ -844,6 +849,7 @@ exec_gmp_post (http_connection_t *con, gsad_connection_info_t *con_info, ELSE (delete_port_list) ELSE (delete_port_range) ELSE (delete_report) + ELSE (delete_report_config) ELSE (delete_report_format) ELSE (delete_role) ELSE (delete_scanner) @@ -884,6 +890,7 @@ exec_gmp_post (http_connection_t *con, gsad_connection_info_t *con_info, ELSE (save_override) ELSE (save_permission) ELSE (save_port_list) + ELSE (save_report_config) ELSE (save_report_format) ELSE (save_role) ELSE (save_scanner) @@ -1487,6 +1494,8 @@ exec_gmp_get (http_connection_t *con, gsad_connection_info_t *con_info, ELSE (export_port_list) ELSE (export_port_lists) ELSE (export_preference_file) + ELSE (export_report_config) + ELSE (export_report_configs) ELSE (export_report_format) ELSE (export_report_formats) ELSE (export_result) @@ -1569,6 +1578,8 @@ exec_gmp_get (http_connection_t *con, gsad_connection_info_t *con_info, ELSE (get_port_lists) ELSE (get_report) ELSE (get_reports) + ELSE (get_report_config) + ELSE (get_report_configs) ELSE (get_report_format) ELSE (get_report_formats) ELSE (get_resource_names) diff --git a/src/gsad_gmp.c b/src/gsad_gmp.c index 665ee0a65..750124df9 100644 --- a/src/gsad_gmp.c +++ b/src/gsad_gmp.c @@ -209,6 +209,10 @@ static char * get_target (gvm_connection_t *, credentials_t *, params_t *, const char *, cmd_response_data_t *); +static char * +get_report_config (gvm_connection_t *, credentials_t *, params_t *, + const char *, cmd_response_data_t *); + static char * get_report_format (gvm_connection_t *, credentials_t *, params_t *, const char *, cmd_response_data_t *); @@ -7741,6 +7745,46 @@ export_preference_file_gmp (gvm_connection_t *connection, g_string_free (xml, FALSE), response_data); } +/** + * @brief Export a report config. + * + * @param[in] connection Connection to manager. + * @param[in] credentials Username and password for authentication. + * @param[in] params Request parameters. + * @param[out] response_data Extra data return for the HTTP response. + * + * @return Report config XML on success. Enveloped XML + * on error. + */ +char * +export_report_config_gmp (gvm_connection_t *connection, + credentials_t *credentials, params_t *params, + cmd_response_data_t *response_data) +{ + return export_resource (connection, "report_config", credentials, params, + response_data); +} + +/** + * @brief Export a list of Report Configs. + * + * @param[in] connection Connection to manager. + * @param[in] credentials Username and password for authentication. + * @param[in] params Request parameters. + * @param[out] response_data Extra data return for the HTTP response. + * + * @return Report Formats XML on success. Enveloped XML + * on error. + */ +char * +export_report_configs_gmp (gvm_connection_t *connection, + credentials_t *credentials, params_t *params, + cmd_response_data_t *response_data) +{ + return export_many (connection, "report_config", credentials, params, + response_data); +} + /** * @brief Export a report format. * @@ -10276,6 +10320,380 @@ get_system_report_gmp_from_url (gvm_connection_t *connection, return NULL; } +/** + * @brief Get one report config, envelope the result. + * + * @param[in] connection Connection to manager. + * @param[in] credentials Username and password for authentication. + * @param[in] params Request parameters. + * @param[in] extra_xml Extra XML to insert inside page element. + * @param[out] response_data Extra data return for the HTTP response. + * + * @return Enveloped XML object. + */ +static char * +get_report_config (gvm_connection_t *connection, credentials_t *credentials, + params_t *params, const char *extra_xml, + cmd_response_data_t *response_data) +{ + gmp_arguments_t *arguments; + arguments = gmp_arguments_new (); + + gmp_arguments_add (arguments, "alerts", "1"); + + return get_one (connection, "report_config", credentials, params, extra_xml, + arguments, response_data); +} + +/** + * @brief Get one report config, envelope the result. + * + * @param[in] connection Connection to manager. + * @param[in] credentials Username and password for authentication. + * @param[in] params Request parameters. + * @param[out] response_data Extra data return for the HTTP response. + * + * @return Enveloped XML object. + */ +char * +get_report_config_gmp (gvm_connection_t *connection, credentials_t *credentials, + params_t *params, cmd_response_data_t *response_data) +{ + return get_report_config (connection, credentials, params, NULL, + response_data); +} + +/** + * @brief Get all Report Configs, envelope the result. + * + * @param[in] connection Connection to manager. + * @param[in] credentials Username and password for authentication. + * @param[in] params Request parameters. + * @param[out] response_data Extra data return for the HTTP response. + * + * @return Enveloped XML object. + */ +char * +get_report_configs_gmp (gvm_connection_t *connection, + credentials_t *credentials, params_t *params, + cmd_response_data_t *response_data) +{ + return get_many (connection, "report_configs", credentials, params, NULL, + response_data); +} + +/** + * @brief Collect the report config params. + * + * @param[in] params All request params. + * @param[out] config_params Collected config params with values set. + * @param[out] default_config_params Config params using default values. + */ +static void +collect_report_config_params (params_t *params, GHashTable **config_params, + GHashTable **default_config_params) +{ + params_t *default_params; + params_t *preference_params; + + *config_params = + g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); + + *default_config_params = + g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + + /* Collect params using default value */ + default_params = params_values (params, "param_using_default:"); + if (default_params) + { + param_t *param; + gchar *param_name; + params_iterator_t iter; + + params_iterator_init (&iter, default_params); + while (params_iterator_next (&iter, ¶m_name, ¶m)) + { + if (param->value == NULL) + continue; + + g_hash_table_insert (*default_config_params, g_strdup (param_name), + GINT_TO_POINTER (1)); + } + } + + /* Collect params with value */ + preference_params = params_values (params, "param:"); + if (preference_params) + { + param_t *param; + gchar *param_name; + params_iterator_t iter; + + params_iterator_init (&iter, preference_params); + while (params_iterator_next (&iter, ¶m_name, ¶m)) + { + if (param->value == NULL) + continue; + + if (g_hash_table_contains (*default_config_params, param_name)) + continue; + + g_hash_table_insert (*config_params, g_strdup (param_name), + g_strdup (param->value)); + } + } +} + +/** + * @brief Append XML for report config params to a string. + * + * @param[in] string String buffer to append XML to. + * @param[in] config_params Collected config params with values set. + * @param[in] default_config_params Config params using default values. + */ +static void +buffer_report_config_params (GString *string, GHashTable *config_params, + GHashTable *default_config_params) +{ + GHashTableIter iter; + const char *param_name, *param_value; + + g_hash_table_iter_init (&iter, config_params); + g_message ("%s: params size: %d", __func__, + g_hash_table_size (config_params)); + while (g_hash_table_iter_next (&iter, (void **) ¶m_name, + (void **) ¶m_value)) + { + g_message ("%s: param...", __func__); + g_message ("%s: param name %s", __func__, param_name); + g_message ("%s: param value %s", __func__, param_value); + + xml_string_append (string, + "" + "%s" + "%s" + "", + param_name, param_value); + } + + g_hash_table_iter_init (&iter, default_config_params); + while (g_hash_table_iter_next (&iter, (void **) ¶m_name, + (void **) ¶m_value)) + { + xml_string_append (string, + "" + "%s" + "" + "", + param_name); + } +} + +/** + * @brief Save report_config, get next page, envelope the result. + * + * @param[in] connection Connection to manager. + * @param[in] credentials Username and password for authentication. + * @param[in] request_params Request parameters. + * @param[out] response_data Extra data return for the HTTP response. + * + * @return Enveloped XML object. + */ +char * +create_report_config_gmp (gvm_connection_t *connection, + credentials_t *credentials, params_t *params, + cmd_response_data_t *response_data) +{ + int ret; + gchar *html, *response; + const char *name, *comment, *report_format_id; + entity_t entity; + GHashTable *config_params, *default_config_params; + GString *command; + + name = params_value (params, "name"); + comment = params_value (params, "comment"); + report_format_id = params_value (params, "report_format_id"); + + CHECK_VARIABLE_INVALID (name, "Save Report Config"); + CHECK_VARIABLE_INVALID (comment, "Save Report Config"); + CHECK_VARIABLE_INVALID (report_format_id, "Save Report Config"); + + collect_report_config_params (params, &config_params, &default_config_params); + + command = g_string_new (""); + xml_string_append (command, + "" + "%s" + "%s" + "", + name, comment, report_format_id); + + buffer_report_config_params (command, config_params, default_config_params); + + g_string_append (command, ""); + + response = NULL; + entity = NULL; + ret = gmpf (connection, credentials, &response, &entity, response_data, + command->str); + + g_string_free (command, TRUE); + + switch (ret) + { + case 0: + break; + case -1: + return response; + case 1: + cmd_response_data_set_status_code (response_data, + MHD_HTTP_INTERNAL_SERVER_ERROR); + return gsad_message ( + credentials, "Internal error", __func__, __LINE__, + "An internal error occurred while creating a Report Config. " + "The Report Config was not created. " + "Diagnostics: Failure to send command to manager daemon.", + response_data); + case 2: + cmd_response_data_set_status_code (response_data, + MHD_HTTP_INTERNAL_SERVER_ERROR); + return gsad_message ( + credentials, "Internal error", __func__, __LINE__, + "An internal error occurred while creating a Report Config. " + "It is unclear whether the Report Config has been created or not. " + "Diagnostics: Failure to receive response from manager daemon.", + response_data); + default: + cmd_response_data_set_status_code (response_data, + MHD_HTTP_INTERNAL_SERVER_ERROR); + return gsad_message ( + credentials, "Internal error", __func__, __LINE__, + "An internal error occurred while creating a Report Config. " + "It is unclear whether the Report Config has been created or not. " + "Diagnostics: Internal Error.", + response_data); + } + + html = response_from_entity (connection, credentials, params, entity, + "Create Report Config", response_data); + free_entity (entity); + g_free (response); + return html; +} + +/** + * @brief Delete report config, get report config, envelope the result. + * + * @param[in] connection Connection to manager. + * @param[in] credentials Username and password for authentication. + * @param[in] params Request parameters. + * @param[out] response_data Extra data return for the HTTP response. + * + * @return Enveloped XML object. + */ +char * +delete_report_config_gmp (gvm_connection_t *connection, + credentials_t *credentials, params_t *params, + cmd_response_data_t *response_data) +{ + return move_resource_to_trash (connection, "report_config", credentials, + params, response_data); +} + +/** + * @brief Save report_config, get next page, envelope the result. + * + * @param[in] connection Connection to manager. + * @param[in] credentials Username and password for authentication. + * @param[in] params Request parameters. + * @param[out] response_data Extra data return for the HTTP response. + * + * @return Enveloped XML object. + */ +char * +save_report_config_gmp (gvm_connection_t *connection, + credentials_t *credentials, params_t *params, + cmd_response_data_t *response_data) +{ + int ret; + gchar *html, *response; + const char *report_config_id, *name, *comment; + entity_t entity; + GHashTable *config_params, *default_config_params; + GString *command; + + report_config_id = params_value (params, "report_config_id"); + name = params_value (params, "name"); + comment = params_value (params, "comment"); + + CHECK_VARIABLE_INVALID (report_config_id, "Save Report Config"); + CHECK_VARIABLE_INVALID (name, "Save Report Config"); + CHECK_VARIABLE_INVALID (comment, "Save Report Config"); + + collect_report_config_params (params, &config_params, &default_config_params); + + command = g_string_new (""); + xml_string_append (command, + "" + "%s" + "%s", + report_config_id, name, comment); + + buffer_report_config_params (command, config_params, default_config_params); + + g_string_append (command, ""); + + response = NULL; + entity = NULL; + ret = gmpf (connection, credentials, &response, &entity, response_data, + command->str); + + g_string_free (command, TRUE); + + switch (ret) + { + case 0: + break; + case -1: + return response; + case 1: + cmd_response_data_set_status_code (response_data, + MHD_HTTP_INTERNAL_SERVER_ERROR); + return gsad_message ( + credentials, "Internal error", __func__, __LINE__, + "An internal error occurred while saving a Report Config. " + "The Report Config was not saved. " + "Diagnostics: Failure to send command to manager daemon.", + response_data); + case 2: + cmd_response_data_set_status_code (response_data, + MHD_HTTP_INTERNAL_SERVER_ERROR); + return gsad_message ( + credentials, "Internal error", __func__, __LINE__, + "An internal error occurred while saving a Report Config. " + "It is unclear whether the Report Config has been saved or not. " + "Diagnostics: Failure to receive response from manager daemon.", + response_data); + default: + cmd_response_data_set_status_code (response_data, + MHD_HTTP_INTERNAL_SERVER_ERROR); + return gsad_message ( + credentials, "Internal error", __func__, __LINE__, + "An internal error occurred while saving a Report Config. " + "It is unclear whether the Report Config has been saved or not. " + "Diagnostics: Internal Error.", + response_data); + } + + html = response_from_entity (connection, credentials, params, entity, + "Save Report Config", response_data); + free_entity (entity); + g_free (response); + return html; +} + /** * @brief Get one report format, envelope the result. * @@ -10297,6 +10715,7 @@ get_report_format (gvm_connection_t *connection, credentials_t *credentials, gmp_arguments_add (arguments, "alerts", "1"); gmp_arguments_add (arguments, "params", "1"); + gmp_arguments_add (arguments, "report_configs", "1"); return get_one (connection, "report_format", credentials, params, extra_xml, arguments, response_data); @@ -10924,6 +11343,9 @@ get_trash (gvm_connection_t *connection, credentials_t *credentials, GET_TRASH_RESOURCE ("GET_PORT_LISTS", "get_port_lists", "port lists"); + GET_TRASH_RESOURCE ("GET_REPORT_CONFIGS", "get_report_configs", + "report configs"); + GET_TRASH_RESOURCE ("GET_REPORT_FORMATS", "get_report_formats", "report formats"); diff --git a/src/gsad_gmp.h b/src/gsad_gmp.h index f416d43d4..12a0623ed 100644 --- a/src/gsad_gmp.h +++ b/src/gsad_gmp.h @@ -331,6 +331,12 @@ char * export_preference_file_gmp (gvm_connection_t *, credentials_t *, params_t *, cmd_response_data_t *); char * +export_report_config_gmp (gvm_connection_t *, credentials_t *, params_t *, + cmd_response_data_t *); +char * +export_report_configs_gmp (gvm_connection_t *, credentials_t *, params_t *, + cmd_response_data_t *); +char * export_report_format_gmp (gvm_connection_t *, credentials_t *, params_t *, cmd_response_data_t *); char * @@ -517,6 +523,22 @@ get_system_report_gmp_from_url (gvm_connection_t *, credentials_t *, const char *, params_t *, cmd_response_data_t *); +char * +get_report_config_gmp (gvm_connection_t *, credentials_t *, params_t *, + cmd_response_data_t *); +char * +get_report_configs_gmp (gvm_connection_t *, credentials_t *, params_t *, + cmd_response_data_t *); +char * +create_report_config_gmp (gvm_connection_t *, credentials_t *, params_t *, + cmd_response_data_t *); +char * +delete_report_config_gmp (gvm_connection_t *, credentials_t *, params_t *, + cmd_response_data_t *); +char * +save_report_config_gmp (gvm_connection_t *, credentials_t *, params_t *, + cmd_response_data_t *); + char * get_report_format_gmp (gvm_connection_t *, credentials_t *, params_t *, cmd_response_data_t *); diff --git a/src/gsad_validator.c b/src/gsad_validator.c index e5286573f..9127495fe 100644 --- a/src/gsad_validator.c +++ b/src/gsad_validator.c @@ -50,6 +50,7 @@ init_validator () "|(create_port_list)" "|(create_port_range)" "|(create_report)" + "|(create_report_config)" "|(create_role)" "|(create_scanner)" "|(create_schedule)" @@ -74,6 +75,7 @@ init_validator () "|(delete_port_list)" "|(delete_port_range)" "|(delete_report)" + "|(delete_report_config)" "|(delete_report_format)" "|(delete_role)" "|(delete_scanner)" @@ -115,6 +117,8 @@ init_validator () "|(export_port_list)" "|(export_port_lists)" "|(export_preference_file)" + "|(export_report_config)" + "|(export_report_configs)" "|(export_report_format)" "|(export_report_formats)" "|(export_result)" @@ -163,6 +167,8 @@ init_validator () "|(get_port_lists)" "|(get_report)" "|(get_reports)" + "|(get_report_config)" + "|(get_report_configs)" "|(get_report_format)" "|(get_report_formats)" "|(get_resource_names)" @@ -222,6 +228,7 @@ init_validator () "|(save_override)" "|(save_permission)" "|(save_port_list)" + "|(save_report_config)" "|(save_report_format)" "|(save_role)" "|(save_scanner)" @@ -250,7 +257,8 @@ init_validator () gvm_validator_add ( validator, "aggregate_type", "^(alert|config|credential|filter|group|host|nvt|note|os|override|" - "permission|port_list|report|report_format|result|role|scanner|schedule|" + "permission|port_list|report|report_config|report_format|result|role|" + "scanner|schedule|" "tag|target|task|user|cve|cpe|ovaldef|cert_bund_adv|dfn_cert_adv|" "vuln|tls_certificate)$"); gvm_validator_add ( @@ -425,6 +433,7 @@ init_validator () gvm_validator_add (validator, "related:value", "^.*$"); gvm_validator_add (validator, "report_fname", "^([[:alnum:]_-]|%[%CcDFMmNTtUu])+$"); + gvm_validator_add (validator, "report_config_id", "^[a-z0-9\\-]+$"); gvm_validator_add (validator, "report_format_id", "^[a-z0-9\\-]+$"); gvm_validator_add (validator, "report_section", "^(summary|results|hosts|ports" @@ -433,6 +442,10 @@ init_validator () gvm_validator_add (validator, "resource_type", "(?s)^.*$"); gvm_validator_add (validator, "result_id", "^[a-z0-9\\-]+$"); gvm_validator_add (validator, "role", "^[[:alnum:] ]+$"); + gvm_validator_add (validator, "param:name", "^(.*){0,400}$"); + gvm_validator_add (validator, "param:value", "(?s)^.*$"); + gvm_validator_add (validator, "param_using_default:name", "^(.*){0,400}$"); + gvm_validator_add (validator, "param_using_default:value", "(?s)^.*$"); gvm_validator_add (validator, "permission", "^([_a-z]+|Super)$"); gvm_validator_add (validator, "permission_type", "^(read|write)$"); gvm_validator_add (validator, "port_list_id", "^[a-z0-9\\-]+$"); @@ -441,7 +454,8 @@ init_validator () validator, "resource_type", "^(alert|asset|cert_bund_adv|config|cpe|credential|cve|dfn_cert_adv|" "filter|group|host|info|nvt|note|os|ovaldef|override|permission|port_list|" - "report|report_format|result|role|scanner|schedule|tag|target|task|ticket|" + "report|report_config|report_format|result|role|scanner|schedule|tag|" + "target|task|ticket|" "tls_certificate|user|vuln|)$"); gvm_validator_add (validator, "resource_id", "^[[:alnum:]\\-_.:\\/~]*$"); gvm_validator_add (validator, "resources_action", "^(|add|set|remove)$"); @@ -449,7 +463,8 @@ init_validator () validator, "optional_resource_type", "^(alert|asset|cert_bund_adv|config|cpe|credential|cve|dfn_cert_adv|" "filter|group|host|info|nvt|note|os|ovaldef|override|permission|port_list|" - "report|report_format|result|role|scanner|schedule|tag|target|task|ticket|" + "report|report_config|report_format|result|role|scanner|schedule|tag|" + "target|task|ticket|" "tls_certificate|user|vuln|)?$"); gvm_validator_add (validator, "select:value", "^.*$"); gvm_validator_add (validator, "ssl_cert", "^.*$");