From 65cd0218517cbafd8456851c72e03131ccf555a3 Mon Sep 17 00:00:00 2001 From: Timo Pollmeier Date: Wed, 10 Apr 2024 10:50:54 +0200 Subject: [PATCH] Add: New multi_selection report format param type A new parameter type for report formats and report configs is added that allows selecting multiple predefined options. This can later be used to add new customization options to report formats like a column selection for CSV. --- INSTALL.md | 1 + src/CMakeLists.txt | 13 +-- src/gmp.c | 12 ++- src/manage_report_formats.c | 4 + src/manage_report_formats.h | 1 + src/manage_sql_report_formats.c | 134 +++++++++++++++++++++++++----- src/schema_formats/XML/GMP.xml.in | 2 + 7 files changed, 136 insertions(+), 31 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index ac327bc57..ff9f1b144 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -9,6 +9,7 @@ necessary to install dependent development packages. Prerequisites: * GCC (Debian package: gcc) * cmake >= 3.0 (Debian package: cmake) +* cJSON >= 1.7.14 (Debian package: libcjson-dev) * glib-2.0 >= 2.42 (Debian package: libglib2.0-dev) * gnutls >= 3.2.15 (Debian package: libgnutls28-dev) * libgvm_base, libgvm_util, libgvm_osp, libgvm_gmp >= 20.08.0 ([gvm-libs](https://github.com/greenbone/gvm-libs/tree/gvm-libs-20.08) component) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c2f3aebb0..993824040 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,6 +26,7 @@ find_package (Threads) ## list and throw an error, otherwise long install-cmake-install-cmake cycles ## might occur. +pkg_check_modules (CJSON REQUIRED libcjson>=1.7.14) pkg_check_modules (LIBGVM_BASE REQUIRED libgvm_base>=22.9) pkg_check_modules (LIBGVM_UTIL REQUIRED libgvm_util>=22.9) pkg_check_modules (LIBGVM_OSP REQUIRED libgvm_osp>=22.9) @@ -290,32 +291,32 @@ add_executable (gvmd target_link_libraries (gvmd m ${GNUTLS_LDFLAGS} ${GPGME_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT} ${LINKER_HARDENING_FLAGS} ${LINKER_DEBUG_FLAGS} - ${PostgreSQL_LIBRARIES} ${LIBBSD_LDFLAGS} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} + ${PostgreSQL_LIBRARIES} ${LIBBSD_LDFLAGS} ${CJSON_LDFLAGS} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} ${LIBGVM_GMP_LDFLAGS} ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) target_link_libraries (manage-test cgreen m ${GNUTLS_LDFLAGS} ${GPGME_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT} ${LINKER_HARDENING_FLAGS} ${LINKER_DEBUG_FLAGS} - ${PostgreSQL_LIBRARIES} ${LIBBSD_LDFLAGS} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} + ${PostgreSQL_LIBRARIES} ${LIBBSD_LDFLAGS} ${CJSON_LDFLAGS} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} ${LIBGVM_GMP_LDFLAGS} ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) target_link_libraries (manage-sql-test cgreen m ${GNUTLS_LDFLAGS} ${GPGME_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT} ${LINKER_HARDENING_FLAGS} ${LINKER_DEBUG_FLAGS} - ${PostgreSQL_LIBRARIES} ${LIBBSD_LDFLAGS} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} + ${PostgreSQL_LIBRARIES} ${LIBBSD_LDFLAGS} ${CJSON_LDFLAGS} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} ${LIBGVM_GMP_LDFLAGS} ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) target_link_libraries (manage-utils-test cgreen m ${GNUTLS_LDFLAGS} ${GPGME_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT} ${LINKER_HARDENING_FLAGS} ${LINKER_DEBUG_FLAGS} - ${PostgreSQL_LIBRARIES} ${LIBBSD_LDFLAGS} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} + ${PostgreSQL_LIBRARIES} ${LIBBSD_LDFLAGS} ${CJSON_LDFLAGS} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} ${LIBGVM_GMP_LDFLAGS} ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) target_link_libraries (gmp-tickets-test cgreen m ${GNUTLS_LDFLAGS} ${GPGME_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT} ${LINKER_HARDENING_FLAGS} ${LINKER_DEBUG_FLAGS} - ${PostgreSQL_LIBRARIES} ${LIBBSD_LDFLAGS} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} + ${PostgreSQL_LIBRARIES} ${LIBBSD_LDFLAGS} ${CJSON_LDFLAGS} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} ${LIBGVM_GMP_LDFLAGS} ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) target_link_libraries (utils-test cgreen m ${GNUTLS_LDFLAGS} ${GPGME_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT} ${LINKER_HARDENING_FLAGS} ${LINKER_DEBUG_FLAGS} - ${PostgreSQL_LIBRARIES} ${LIBBSD_LDFLAGS} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} + ${PostgreSQL_LIBRARIES} ${LIBBSD_LDFLAGS} ${CJSON_LDFLAGS} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} ${LIBGVM_GMP_LDFLAGS} ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) target_link_libraries (gvm-pg-server ${LIBBSD_LDFLAGS} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS}) diff --git a/src/gmp.c b/src/gmp.c index 932382bb2..417a12e65 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -15201,8 +15201,10 @@ print_report_config_params (gmp_parser_t *gmp_parser, GError **error, report_config_param_iterator_fallback_value (¶ms)); } - if (report_config_param_iterator_type (¶ms) - == REPORT_FORMAT_PARAM_TYPE_SELECTION) + report_format_param_type_t param_type; + param_type = report_config_param_iterator_type (¶ms); + if (param_type == REPORT_FORMAT_PARAM_TYPE_SELECTION + || param_type == REPORT_FORMAT_PARAM_TYPE_MULTI_SELECTION) { SEND_TO_CLIENT_OR_FAIL (""); init_param_option_iterator @@ -15624,8 +15626,10 @@ handle_get_report_formats (gmp_parser_t *gmp_parser, GError **error) report_format_param_iterator_fallback (¶ms)); } - if (report_format_param_iterator_type (¶ms) - == REPORT_FORMAT_PARAM_TYPE_SELECTION) + report_format_param_type_t param_type; + param_type = report_format_param_iterator_type (¶ms); + if (param_type == REPORT_FORMAT_PARAM_TYPE_SELECTION + || param_type == REPORT_FORMAT_PARAM_TYPE_MULTI_SELECTION) { SEND_TO_CLIENT_OR_FAIL (""); init_param_option_iterator diff --git a/src/manage_report_formats.c b/src/manage_report_formats.c index 340321189..efc471633 100644 --- a/src/manage_report_formats.c +++ b/src/manage_report_formats.c @@ -114,6 +114,8 @@ report_format_param_type_name (report_format_param_type_t type) return "text"; case REPORT_FORMAT_PARAM_TYPE_REPORT_FORMAT_LIST: return "report_format_list"; + case REPORT_FORMAT_PARAM_TYPE_MULTI_SELECTION: + return "multi_selection"; default: assert (0); case REPORT_FORMAT_PARAM_TYPE_ERROR: @@ -143,6 +145,8 @@ report_format_param_type_from_name (const char *name) return REPORT_FORMAT_PARAM_TYPE_TEXT; if (strcmp (name, "report_format_list") == 0) return REPORT_FORMAT_PARAM_TYPE_REPORT_FORMAT_LIST; + if (strcmp (name, "multi_selection") == 0) + return REPORT_FORMAT_PARAM_TYPE_MULTI_SELECTION; return REPORT_FORMAT_PARAM_TYPE_ERROR; } diff --git a/src/manage_report_formats.h b/src/manage_report_formats.h index 9d593a1cd..990f9436f 100644 --- a/src/manage_report_formats.h +++ b/src/manage_report_formats.h @@ -203,6 +203,7 @@ typedef enum REPORT_FORMAT_PARAM_TYPE_STRING = 3, REPORT_FORMAT_PARAM_TYPE_TEXT = 4, REPORT_FORMAT_PARAM_TYPE_REPORT_FORMAT_LIST = 5, + REPORT_FORMAT_PARAM_TYPE_MULTI_SELECTION = 6, REPORT_FORMAT_PARAM_TYPE_ERROR = 100 } report_format_param_type_t; diff --git a/src/manage_sql_report_formats.c b/src/manage_sql_report_formats.c index 34ee86b3a..b3f1593ac 100644 --- a/src/manage_sql_report_formats.c +++ b/src/manage_sql_report_formats.c @@ -31,6 +31,7 @@ #include "sql.h" #include "utils.h" +#include #include #include #include @@ -2406,6 +2407,28 @@ report_format_param_type_min (report_format_t report_format, const char *name) return min; } +static int +report_format_param_value_in_options (report_format_param_t param, + const char *value) +{ + iterator_t options; + int found = 0; + + init_param_option_iterator (&options, param, 1, NULL); + while (next (&options)) + { + if (param_option_iterator_value (&options) + && (strcmp (param_option_iterator_value (&options), value) + == 0)) + { + found = 1; + break; + } + } + cleanup_iterator (&options); + return found; +} + /** * @brief Validate a value for a report format param. * @@ -2459,29 +2482,18 @@ report_format_validate_param_value (report_format_t report_format, break; case REPORT_FORMAT_PARAM_TYPE_SELECTION: { - iterator_t options; - int found = 0; - - init_param_option_iterator (&options, param, 1, NULL); - while (next (&options)) - if (param_option_iterator_value (&options) - && (strcmp (param_option_iterator_value (&options), value) - == 0)) - { - found = 1; - break; - } - cleanup_iterator (&options); - if (found) - break; - if (error_message) + if (! report_format_param_value_in_options (param, value)) { - *error_message - = g_strdup_printf ("value of param \"%s\"" - " is not a valid selection option", - name); + if (error_message) + { + *error_message + = g_strdup_printf ("value of param \"%s\"" + " is not a valid selection option", + name); + } + return 1; } - return 1; + break; } case REPORT_FORMAT_PARAM_TYPE_STRING: case REPORT_FORMAT_PARAM_TYPE_TEXT: @@ -2533,6 +2545,86 @@ report_format_validate_param_value (report_format_t report_format, return 0; } break; + case REPORT_FORMAT_PARAM_TYPE_MULTI_SELECTION: + { + long long int min, max, actual; + min = report_format_param_type_min (report_format, name); + max = report_format_param_type_max (report_format, name); + actual = 0LL; + cJSON *json = cJSON_Parse (value); + cJSON *array_item = NULL; + + if (!cJSON_IsArray (json)) + { + if (error_message) + { + *error_message + = g_strdup_printf ("value of param \"%s\"" + " is not a valid JSON array", + name); + } + cJSON_Delete (json); + return 1; + } + + cJSON_ArrayForEach (array_item, json) + { + char *string; + if (!cJSON_IsString (array_item)) + { + if (error_message) + { + *error_message + = g_strdup_printf ("value of param \"%s\"" + " contains a non-string value", + name); + } + cJSON_Delete (json); + return 1; + } + string = cJSON_GetStringValue (array_item); + if (! report_format_param_value_in_options (param, string)) + { + if (error_message) + { + *error_message + = g_strdup_printf ("\"%s\" in value of param \"%s\"" + " is not a valid selection option", + string, name); + } + cJSON_Delete (json); + return 1; + } + actual ++; + } + + cJSON_Delete (json); + if (actual < min) + { + if (error_message) + { + *error_message + = g_strdup_printf ("value of param \"%s\"" + " must contain at least %lld option(s)," + " got %lld", + name, min, actual); + } + return 1; + } + if (actual > max) + { + if (error_message) + { + *error_message + = g_strdup_printf ("value of param \"%s\"" + " must contain a maximum of %lld" + " option(s), got %lld", + name, max, actual); + } + return 1; + } + break; + } default: break; } diff --git a/src/schema_formats/XML/GMP.xml.in b/src/schema_formats/XML/GMP.xml.in index 9f6e3732f..99cdb1050 100644 --- a/src/schema_formats/XML/GMP.xml.in +++ b/src/schema_formats/XML/GMP.xml.in @@ -16016,6 +16016,7 @@ END:VCALENDAR boolean integer + multi_selection selection string text @@ -16678,6 +16679,7 @@ END:VCALENDAR boolean integer + multi_selection selection string text