From 1b8d1385b6dce1fe22b087b20cd41a498974c031 Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Tue, 21 Jan 2020 16:21:15 +0200 Subject: [PATCH 1/4] Move is_uuid to utils --- src/gmp.c | 15 --------------- src/utils.c | 18 ++++++++++++++++++ src/utils.h | 3 +++ 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/gmp.c b/src/gmp.c index a41962806..d60827e1d 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -98,7 +98,6 @@ #include #include -#include #include #include #include @@ -140,20 +139,6 @@ buffer_results_xml (GString *, iterator_t *, task_t, int, int, int, int, int, /* Helper functions. */ -/** - * @brief Check whether a string is a UUID. - * - * @param[in] uuid Potential UUID. - * - * @return 1 yes, 0 no. - */ -static int -is_uuid (const char *uuid) -{ - while (*uuid) if (isxdigit (*uuid) || (*uuid == '-')) uuid++; else return 0; - return 1; -} - /** * @brief Return time defined by broken down time strings. * diff --git a/src/utils.c b/src/utils.c index 2e6cf5ced..1188b1835 100644 --- a/src/utils.c +++ b/src/utils.c @@ -40,6 +40,7 @@ #include "utils.h" #include +#include #include #include #include @@ -528,3 +529,20 @@ lockfile_locked (const gchar *lockfile_basename) return -1; return ret; } + + +/* UUIDs. */ + +/** + * @brief Check whether a string is a UUID. + * + * @param[in] uuid Potential UUID. + * + * @return 1 yes, 0 no. + */ +int +is_uuid (const char *uuid) +{ + while (*uuid) if (isxdigit (*uuid) || (*uuid == '-')) uuid++; else return 0; + return 1; +} diff --git a/src/utils.h b/src/utils.h index 3b3008cad..574f4991d 100644 --- a/src/utils.h +++ b/src/utils.h @@ -76,4 +76,7 @@ lockfile_unlock (lockfile_t *); int lockfile_locked (const gchar *); +int +is_uuid (const char *); + #endif /* not _GVMD_UTILS_H */ From 8c12e7c500a08371f32f8121433b99447e2afd90 Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Tue, 21 Jan 2020 16:24:55 +0200 Subject: [PATCH 2/4] Use 'pick from parsed' style for port lists --- src/CMakeLists.txt | 9 +- src/gmp.c | 485 ++----------------------------------------- src/gmp_port_lists.c | 445 +++++++++++++++++++++++++++++++++++++++ src/gmp_port_lists.h | 42 ++++ 4 files changed, 506 insertions(+), 475 deletions(-) create mode 100644 src/gmp_port_lists.c create mode 100644 src/gmp_port_lists.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 77e780459..7979daa45 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -108,7 +108,7 @@ add_executable (manage-utils-test sql_pg.c manage_pg.c lsc_user.c lsc_crypt.c utils.c gmp.c gmp_base.c gmp_configs.c gmp_delete.c gmp_get.c - gmp_tickets.c gmp_tls_certificates.c) + gmp_port_lists.c gmp_tickets.c gmp_tls_certificates.c) add_test (manage-utils-test manage-utils-test) @@ -132,7 +132,7 @@ add_executable (manage-test sql_pg.c manage_pg.c lsc_user.c lsc_crypt.c utils.c gmp.c gmp_base.c gmp_configs.c gmp_delete.c gmp_get.c - gmp_tickets.c gmp_tls_certificates.c) + gmp_port_lists.c gmp_tickets.c gmp_tls_certificates.c) add_test (manage-test manage-test) @@ -156,7 +156,7 @@ add_executable (gmp-tickets-test sql_pg.c manage_pg.c lsc_user.c lsc_crypt.c utils.c gmp.c gmp_base.c gmp_configs.c gmp_delete.c gmp_get.c - gmp_tls_certificates.c) + gmp_port_lists.c gmp_tls_certificates.c) add_test (gmp-tickets-test gmp-tickets-test) @@ -187,7 +187,7 @@ add_executable (gvmd sql_pg.c manage_pg.c lsc_user.c lsc_crypt.c utils.c gmp.c gmp_base.c gmp_configs.c gmp_delete.c gmp_get.c - gmp_tickets.c gmp_tls_certificates.c) + gmp_port_lists.c gmp_tickets.c gmp_tls_certificates.c) target_link_libraries (gvmd m ${GNUTLS_LDFLAGS} ${GPGME_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT} ${LINKER_HARDENING_FLAGS} ${LINKER_DEBUG_FLAGS} @@ -367,6 +367,7 @@ set (C_FILES "${CMAKE_CURRENT_SOURCE_DIR}/gvmd.c" "${CMAKE_CURRENT_SOURCE_DIR}/gmp_delete.c" "${CMAKE_CURRENT_SOURCE_DIR}/gmp_get.c" "${CMAKE_CURRENT_SOURCE_DIR}/gmp_configs.c" + "${CMAKE_CURRENT_SOURCE_DIR}/gmp_port_lists.c" "${CMAKE_CURRENT_SOURCE_DIR}/gmp_tickets.c" "${CMAKE_CURRENT_SOURCE_DIR}/gmp_tls_certificates.c" "${CMAKE_CURRENT_SOURCE_DIR}/manage.c" diff --git a/src/gmp.c b/src/gmp.c index d60827e1d..714f24bfc 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -89,6 +89,7 @@ #include "gmp_delete.h" #include "gmp_get.h" #include "gmp_configs.h" +#include "gmp_port_lists.h" #include "gmp_tickets.h" #include "gmp_tls_certificates.h" #include "manage.h" @@ -862,76 +863,6 @@ create_permission_data_reset (create_permission_data_t *data) memset (data, 0, sizeof (create_permission_data_t)); } -/** - * @brief A port range. - */ -struct create_port_list_range -{ - char *comment; ///< Comment. - char *end; ///< End. - char *id; ///< UUID. - char *start; ///< Start. - char *type; ///< Type. -}; - -/** - * @brief Port range type. - */ -typedef struct create_port_list_range create_port_list_range_t; - -/** - * @brief Command data for the create_port_list command. - */ -typedef struct -{ - char *comment; ///< Comment. - char *id; ///< UUID. - char *copy; ///< UUID of Port List to copy. - int import; ///< Import flag. - char *name; ///< Name of new port list. - char *port_range; ///< Port range for new port list. - create_port_list_range_t *range; ///< Current port range for import. - array_t *ranges; ///< Port ranges for import. -} create_port_list_data_t; - -/** - * @brief Reset command data. - * - * @param[in] data Command data. - */ -static void -create_port_list_data_reset (create_port_list_data_t *data) -{ - free (data->comment); - free (data->copy); - free (data->name); - free (data->port_range); - - if (data->ranges) - { - guint index; - - index = data->ranges->len; - while (index--) - { - create_port_list_range_t *range; - range = (create_port_list_range_t*) g_ptr_array_index (data->ranges, - index); - if (range) - { - free (range->comment); - free (range->end); - free (range->id); - free (range->start); - free (range->type); - } - } - array_free (data->ranges); - } - - memset (data, 0, sizeof (create_port_list_data_t)); -} - /** * @brief Command data for the create_port_range command. */ @@ -3781,7 +3712,6 @@ typedef union create_note_data_t create_note; ///< create_note create_override_data_t create_override; ///< create_override create_permission_data_t create_permission; ///< create_permission - create_port_list_data_t create_port_list; ///< create_port_list create_port_range_data_t create_port_range; ///< create_port_range create_report_data_t create_report; ///< create_report create_report_format_data_t create_report_format; ///< create_report_format @@ -3939,12 +3869,6 @@ static create_override_data_t *create_override_data static create_permission_data_t *create_permission_data = (create_permission_data_t*) &(command_data.create_permission); -/** - * @brief Parser callback data for CREATE_PORT_LIST. - */ -static create_port_list_data_t *create_port_list_data - = (create_port_list_data_t*) &(command_data.create_port_list); - /** * @brief Parser callback data for CREATE_PORT_RANGE. */ @@ -4616,25 +4540,6 @@ typedef enum CLIENT_CREATE_PERMISSION_SUBJECT, CLIENT_CREATE_PERMISSION_SUBJECT_TYPE, CLIENT_CREATE_PORT_LIST, - CLIENT_CREATE_PORT_LIST_COMMENT, - CLIENT_CREATE_PORT_LIST_COPY, - CLIENT_CREATE_PORT_LIST_NAME, - CLIENT_CREATE_PORT_LIST_PORT_RANGE, - /* get_port_lists (GPL) is used for port lists export. CLIENT_CPL is - * for CLIENT_CREATE_PORT_LIST. */ - CLIENT_CPL_GPLR, - CLIENT_CPL_GPLR_PORT_LIST, - CLIENT_CPL_GPLR_PORT_LIST_COMMENT, - CLIENT_CPL_GPLR_PORT_LIST_IN_USE, - CLIENT_CPL_GPLR_PORT_LIST_NAME, - CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGE, - CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES, - CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES_PORT_RANGE, - CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES_PORT_RANGE_COMMENT, - CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES_PORT_RANGE_END, - CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES_PORT_RANGE_START, - CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES_PORT_RANGE_TYPE, - CLIENT_CPL_GPLR_PORT_LIST_TARGETS, CLIENT_CREATE_PORT_RANGE, CLIENT_CREATE_PORT_RANGE_COMMENT, CLIENT_CREATE_PORT_RANGE_END, @@ -5335,7 +5240,11 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, else if (strcasecmp ("CREATE_OVERRIDE", element_name) == 0) set_client_state (CLIENT_CREATE_OVERRIDE); else if (strcasecmp ("CREATE_PORT_LIST", element_name) == 0) - set_client_state (CLIENT_CREATE_PORT_LIST); + { + create_port_list_start (gmp_parser, attribute_names, + attribute_values); + set_client_state (CLIENT_CREATE_PORT_LIST); + } else if (strcasecmp ("CREATE_PORT_RANGE", element_name) == 0) set_client_state (CLIENT_CREATE_PORT_RANGE); else if (strcasecmp ("CREATE_PERMISSION", element_name) == 0) @@ -7730,83 +7639,10 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, ELSE_READ_OVER; case CLIENT_CREATE_PORT_LIST: - if (strcasecmp ("COMMENT", element_name) == 0) - set_client_state (CLIENT_CREATE_PORT_LIST_COMMENT); - else if (strcasecmp ("COPY", element_name) == 0) - set_client_state (CLIENT_CREATE_PORT_LIST_COPY); - else if (strcasecmp ("GET_PORT_LISTS_RESPONSE", element_name) == 0) - { - create_port_list_data->import = 1; - set_client_state (CLIENT_CPL_GPLR); - } - else if (strcasecmp ("PORT_RANGE", element_name) == 0) - { - gvm_append_string (&create_port_list_data->port_range, ""); - set_client_state (CLIENT_CREATE_PORT_LIST_PORT_RANGE); - } - else if (strcasecmp ("NAME", element_name) == 0) - set_client_state (CLIENT_CREATE_PORT_LIST_NAME); - ELSE_READ_OVER; - - case CLIENT_CPL_GPLR: - if (strcasecmp ("PORT_LIST", element_name) == 0) - { - append_attribute (attribute_names, attribute_values, "id", - &create_port_list_data->id); - set_client_state (CLIENT_CPL_GPLR_PORT_LIST); - } - ELSE_READ_OVER; - - case CLIENT_CPL_GPLR_PORT_LIST: - if (strcasecmp ("COMMENT", element_name) == 0) - set_client_state (CLIENT_CPL_GPLR_PORT_LIST_COMMENT); - else if (strcasecmp ("IN_USE", element_name) == 0) - set_client_state (CLIENT_CPL_GPLR_PORT_LIST_IN_USE); - else if (strcasecmp ("NAME", element_name) == 0) - set_client_state (CLIENT_CPL_GPLR_PORT_LIST_NAME); - else if (strcasecmp ("PORT_RANGE", element_name) == 0) - set_client_state (CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGE); - else if (strcasecmp ("PORT_RANGES", element_name) == 0) - { - create_port_list_data->ranges = make_array (); - set_client_state (CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES); - } - ELSE_READ_OVER; - - case CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES: - if (strcasecmp ("PORT_RANGE", element_name) == 0) - { - assert (create_port_list_data->range == NULL); - create_port_list_data->range - = g_malloc0 (sizeof (create_port_list_range_t)); - append_attribute (attribute_names, attribute_values, "id", - &(create_port_list_data->range->id)); - set_client_state (CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES_PORT_RANGE); - } - ELSE_READ_OVER; - - case CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES_PORT_RANGE: - if (strcasecmp ("COMMENT", element_name) == 0) - { - gvm_append_string (&create_port_list_data->range->comment, ""); - set_client_state (CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES_PORT_RANGE_COMMENT); - } - else if (strcasecmp ("END", element_name) == 0) - { - gvm_append_string (&create_port_list_data->range->end, ""); - set_client_state (CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES_PORT_RANGE_END); - } - else if (strcasecmp ("START", element_name) == 0) - { - gvm_append_string (&create_port_list_data->range->start, ""); - set_client_state (CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES_PORT_RANGE_START); - } - else if (strcasecmp ("TYPE", element_name) == 0) - { - gvm_append_string (&create_port_list_data->range->type, ""); - set_client_state (CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES_PORT_RANGE_TYPE); - } - ELSE_READ_OVER; + create_port_list_element_start (gmp_parser, element_name, + attribute_names, + attribute_values); + break; case CLIENT_CREATE_PORT_RANGE: if (strcasecmp ("COMMENT", element_name) == 0) @@ -11472,54 +11308,6 @@ buffer_aggregate_xml (GString *xml, iterator_t* aggregate, const gchar* type, }; } -/** - * @brief Convert ranges to manage ranges. - * - * @param[in] ranges Ranges buffered in CREATE_PORT_LIST. - * - * @return Array of manage ranges on success, else NULL. - */ -static array_t * -convert_to_manage_ranges (array_t *ranges) -{ - if (ranges) - { - guint index; - array_t *manage_ranges; - - manage_ranges = make_array (); - - index = ranges->len; - while (index--) - { - create_port_list_range_t *range; - range = (create_port_list_range_t*) g_ptr_array_index (ranges, - index); - if (range) - { - range_t *manage_range; - - manage_range = g_malloc0 (sizeof (range_t)); - manage_range->comment = range->comment; - manage_range->end = atoi (range->end); - manage_range->id = range->id; - manage_range->start = atoi (range->start); - if (strcasecmp (range->type, "TCP") == 0) - manage_range->type = PORT_PROTOCOL_TCP; - else if (strcasecmp (range->type, "UDP") == 0) - manage_range->type = PORT_PROTOCOL_UDP; - else - manage_range->type = PORT_PROTOCOL_OTHER; - manage_range->exclude = 0; - - array_add (manage_ranges, manage_range); - } - } - return manage_ranges; - } - return NULL; -} - /** * @brief Insert else clause for gmp_xml_handle_start_element. * @@ -21897,227 +21685,9 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, CLOSE (CLIENT_CREATE_PERMISSION_SUBJECT, TYPE); case CLIENT_CREATE_PORT_LIST: - { - port_list_t new_port_list; - array_t *manage_ranges; - - manage_ranges = NULL; - - /* The import element, GET_PORT_LISTS_RESPONSE, overrides any other - * elements. */ - - if (create_port_list_data->import) - { - array_terminate (create_port_list_data->ranges); - - if (create_port_list_data->name == NULL) - SEND_TO_CLIENT_OR_FAIL - (XML_ERROR_SYNTAX ("create_port_list", - "GET_PORT_LISTS_RESPONSE requires a" - " NAME element")); - else if (strlen (create_port_list_data->name) == 0) - SEND_TO_CLIENT_OR_FAIL - (XML_ERROR_SYNTAX ("create_port_list", - "GET_PORT_LISTS_RESPONSE NAME must be" - " at least one character long")); - else if (create_port_list_data->id == NULL) - SEND_TO_CLIENT_OR_FAIL - (XML_ERROR_SYNTAX ("create_port_list", - "GET_PORT_LISTS_RESPONSE must have an" - " ID attribute")); - else if (strlen (create_port_list_data->id) == 0) - SEND_TO_CLIENT_OR_FAIL - (XML_ERROR_SYNTAX ("create_port_list", - "GET_PORT_LISTS_RESPONSE ID must be" - " at least one character long")); - else if (!is_uuid (create_port_list_data->id)) - SEND_TO_CLIENT_OR_FAIL - (XML_ERROR_SYNTAX ("create_port_list", - "GET_PORT_LISTS_RESPONSE ID must be" - " a UUID")); - else if ((manage_ranges = convert_to_manage_ranges - (create_port_list_data->ranges)) - == NULL) - SEND_TO_CLIENT_OR_FAIL - (XML_ERROR_SYNTAX ("create_port_list", - "Error in GET_PORT_LISTS_RESPONSE ranges")); - else switch (create_port_list - (create_port_list_data->id, - create_port_list_data->name, - create_port_list_data->comment, - NULL, - manage_ranges, - &new_port_list)) - { - case 1: - SEND_TO_CLIENT_OR_FAIL - (XML_ERROR_SYNTAX ("create_port_list", - "Port list exists already")); - log_event_fail ("port_list", "Port List", NULL, "created"); - break; - case 2: - SEND_TO_CLIENT_OR_FAIL - (XML_ERROR_SYNTAX ("create_port_list", - "Port list exists already, in" - " trashcan")); - log_event_fail ("port_list", "Port List", NULL, "created"); - break; - case 99: - SEND_TO_CLIENT_OR_FAIL - (XML_ERROR_SYNTAX ("create_port_list", - "Permission denied")); - log_event_fail ("port_list", "Port List", NULL, "created"); - break; - case -1: - SEND_TO_CLIENT_OR_FAIL - (XML_INTERNAL_ERROR ("create_port_list")); - log_event_fail ("port_list", "Port List", NULL, "created"); - break; - default: - { - char *uuid = port_list_uuid (new_port_list); - SENDF_TO_CLIENT_OR_FAIL - (XML_OK_CREATED_ID ("create_port_list"), - uuid); - log_event ("port_list", "Port List", uuid, "created"); - free (uuid); - break; - } - } - /* Range fields are freed by the reset function below. */ - array_free (manage_ranges); - } - else if (create_port_list_data->copy) - switch (copy_port_list (create_port_list_data->name, - create_port_list_data->comment, - create_port_list_data->copy, - &new_port_list)) - { - case 0: - { - char *uuid; - uuid = port_list_uuid (new_port_list); - SENDF_TO_CLIENT_OR_FAIL (XML_OK_CREATED_ID - ("create_port_list"), - uuid); - log_event ("port_list", "Port List", uuid, "created"); - free (uuid); - break; - } - case 1: - SEND_TO_CLIENT_OR_FAIL - (XML_ERROR_SYNTAX ("create_port_list", - "Port List exists already")); - log_event_fail ("port_list", "Port List", NULL, "created"); - break; - case 2: - if (send_find_error_to_client ("create_port_list", - "port_list", - create_port_list_data->copy, - gmp_parser)) - { - error_send_to_client (error); - return; - } - log_event_fail ("port_list", "Port List", NULL, "created"); - break; - case 99: - SEND_TO_CLIENT_OR_FAIL - (XML_ERROR_SYNTAX ("create_port_list", - "Permission denied")); - log_event_fail ("port_list", "Port List", NULL, "created"); - break; - case -1: - default: - SEND_TO_CLIENT_OR_FAIL - (XML_INTERNAL_ERROR ("create_port_list")); - log_event_fail ("port_list", "Port List", NULL, "created"); - break; - } - else if (create_port_list_data->name == NULL) - SEND_TO_CLIENT_OR_FAIL - (XML_ERROR_SYNTAX ("create_port_list", - "A NAME is required")); - else if (strlen (create_port_list_data->name) == 0) - SEND_TO_CLIENT_OR_FAIL - (XML_ERROR_SYNTAX ("create_port_list", - "Name must be at" - " least one character long")); - else switch (create_port_list - (NULL, - create_port_list_data->name, - create_port_list_data->comment, - create_port_list_data->port_range, - NULL, - &new_port_list)) - { - case 1: - SEND_TO_CLIENT_OR_FAIL - (XML_ERROR_SYNTAX ("create_port_list", - "Port list exists already")); - log_event_fail ("port_list", "Port List", NULL, "created"); - break; - case 4: - SEND_TO_CLIENT_OR_FAIL - (XML_ERROR_SYNTAX ("create_port_list", - "Error in port range")); - log_event_fail ("port_list", "Port List", NULL, "created"); - break; - case 99: - SEND_TO_CLIENT_OR_FAIL - (XML_ERROR_SYNTAX ("create_port_list", - "Permission denied")); - log_event_fail ("port_list", "Port List", NULL, "created"); - break; - case -1: - SEND_TO_CLIENT_OR_FAIL - (XML_INTERNAL_ERROR ("create_port_list")); - log_event_fail ("port_list", "Port List", NULL, "created"); - break; - default: - { - char *uuid = port_list_uuid (new_port_list); - SENDF_TO_CLIENT_OR_FAIL - (XML_OK_CREATED_ID ("create_port_list"), uuid); - log_event ("port_list", "Port List", uuid, "created"); - free (uuid); - break; - } - } - - create_port_list_data_reset (create_port_list_data); + if (create_port_list_element_end (gmp_parser, error, element_name)) set_client_state (CLIENT_AUTHENTIC); - break; - } - CLOSE (CLIENT_CREATE_PORT_LIST, COMMENT); - CLOSE (CLIENT_CREATE_PORT_LIST, COPY); - case CLIENT_CPL_GPLR: - set_client_state (CLIENT_CREATE_PORT_LIST); break; - CLOSE (CLIENT_CREATE_PORT_LIST, NAME); - CLOSE (CLIENT_CREATE_PORT_LIST, PORT_RANGE); - - CLOSE (CLIENT_CPL_GPLR, PORT_LIST); - CLOSE (CLIENT_CPL_GPLR_PORT_LIST, COMMENT); - CLOSE (CLIENT_CPL_GPLR_PORT_LIST, IN_USE); - CLOSE (CLIENT_CPL_GPLR_PORT_LIST, NAME); - CLOSE (CLIENT_CPL_GPLR_PORT_LIST, PORT_RANGE); - CLOSE (CLIENT_CPL_GPLR_PORT_LIST, PORT_RANGES); - - case CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES_PORT_RANGE: - { - assert (create_port_list_data->ranges); - - array_add (create_port_list_data->ranges, - create_port_list_data->range); - create_port_list_data->range = NULL; - set_client_state (CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES); - break; - } - CLOSE (CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES_PORT_RANGE, COMMENT); - CLOSE (CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES_PORT_RANGE, END); - CLOSE (CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES_PORT_RANGE, START); - CLOSE (CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES_PORT_RANGE, TYPE); case CLIENT_CREATE_PORT_RANGE: { @@ -27879,36 +27449,9 @@ gmp_xml_handle_text (/* unused */ GMarkupParseContext* context, &create_permission_data->subject_type); - APPEND (CLIENT_CREATE_PORT_LIST_COMMENT, - &create_port_list_data->comment); - - APPEND (CLIENT_CREATE_PORT_LIST_COPY, - &create_port_list_data->copy); - - APPEND (CLIENT_CREATE_PORT_LIST_NAME, - &create_port_list_data->name); - - APPEND (CLIENT_CREATE_PORT_LIST_PORT_RANGE, - &create_port_list_data->port_range); - - - APPEND (CLIENT_CPL_GPLR_PORT_LIST_COMMENT, - &create_port_list_data->comment); - - APPEND (CLIENT_CPL_GPLR_PORT_LIST_NAME, - &create_port_list_data->name); - - APPEND (CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES_PORT_RANGE_COMMENT, - &create_port_list_data->range->comment); - - APPEND (CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES_PORT_RANGE_END, - &create_port_list_data->range->end); - - APPEND (CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES_PORT_RANGE_START, - &create_port_list_data->range->start); - - APPEND (CLIENT_CPL_GPLR_PORT_LIST_PORT_RANGES_PORT_RANGE_TYPE, - &create_port_list_data->range->type); + case CLIENT_CREATE_PORT_LIST: + create_port_list_element_text (text, text_len); + break; APPEND (CLIENT_CREATE_PORT_RANGE_COMMENT, diff --git a/src/gmp_port_lists.c b/src/gmp_port_lists.c new file mode 100644 index 000000000..701ebfc35 --- /dev/null +++ b/src/gmp_port_lists.c @@ -0,0 +1,445 @@ +/* Copyright (C) 2020 Greenbone Networks GmbH + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/** + * @file gmp_port_lists.c + * @brief GVM GMP layer: Port Lists + * + * GMP port lists. + */ + +#include "gmp_port_lists.h" +#include "gmp_base.h" +#include "gmp_get.h" +#include "manage_port_lists.h" +#include "utils.h" + + +/* CREATE_PORT_LIST. */ + +/** + * @brief The create_port_list command. + */ +typedef struct +{ + context_data_t *context; ///< XML parser context. +} create_port_list_t; + +/** + * @brief Parser callback data. + * + * This is initially 0 because it's a global variable. + */ +static create_port_list_t create_port_list_data; + +/** + * @brief Reset command data. + */ +static void +create_port_list_reset () +{ + if (create_port_list_data.context->first) + { + free_entity (create_port_list_data.context->first->data); + g_slist_free_1 (create_port_list_data.context->first); + } + g_free (create_port_list_data.context); + memset (&create_port_list_data, 0, sizeof (create_port_list_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_port_list_start (gmp_parser_t *gmp_parser, + const gchar **attribute_names, + const gchar **attribute_values) +{ + memset (&create_port_list_data, 0, sizeof (create_port_list_t)); + create_port_list_data.context = g_malloc0 (sizeof (context_data_t)); + create_port_list_element_start (gmp_parser, "create_port_list", 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_port_list_element_start (gmp_parser_t *gmp_parser, const gchar *name, + const gchar **attribute_names, + const gchar **attribute_values) +{ + xml_handle_start_element (create_port_list_data.context, name, attribute_names, + attribute_values); +} + +/** + * @brief Get creation data from a port_list entity. + * + * @param[in] port_list Port list entity. + * @param[out] port_list_id Address for port list ID if required, else NULL. + * @param[out] name Address for name. + * @param[out] comment Address for comment. + * @param[out] ranges Address for port ranges. + */ +void +parse_port_list_entity (entity_t port_list, const char **port_list_id, + char **name, char **comment, array_t **ranges) +{ + entity_t entity, port_ranges; + + *name = *comment = NULL; + + if (port_list_id) + *port_list_id = entity_attribute (port_list, "id"); + + entity = entity_child (port_list, "name"); + if (entity) + *name = entity_text (entity); + + entity = entity_child (port_list, "comment"); + if (entity) + *comment = entity_text (entity); + + /* Collect port ranges. */ + + *ranges = NULL; + port_ranges = entity_child (port_list, "port_ranges"); + if (port_ranges) + { + entity_t port_range; + entities_t children; + + *ranges = make_array (); + + children = port_ranges->entities; + while ((port_range = first_entity (children))) + { + range_t *range; + entity_t range_comment, end, start, type; + + range = g_malloc0 (sizeof (range_t)); + + range_comment = entity_child (port_range, "comment"); + range->comment = range_comment ? entity_text (range_comment) : NULL; + + end = entity_child (port_range, "end"); + range->end = end ? atoi (entity_text (end)) : 0; + + /* Nothing is going to modify ID. Casting is simpler than dealing + * with an allocation because create_port_list may remove ranges from + * the array. */ + range->id = (gchar *) entity_attribute (port_range, "id"); + + start = entity_child (port_range, "start"); + range->start = start ? atoi (entity_text (start)) : 0; + + type = entity_child (port_range, "type"); + if (type && strcasecmp (entity_text (type), "TCP") == 0) + range->type = PORT_PROTOCOL_TCP; + else if (type && strcasecmp (entity_text (type), "UDP") == 0) + range->type = PORT_PROTOCOL_UDP; + else + range->type = PORT_PROTOCOL_OTHER; + + range->exclude = 0; + + array_add (*ranges, range); + + children = next_entities (children); + } + + array_terminate (*ranges); + } +} + +/** + * @brief Execute command. + * + * @param[in] gmp_parser GMP parser. + * @param[in] error Error parameter. + */ +void +create_port_list_run (gmp_parser_t *gmp_parser, GError **error) +{ + port_list_t new_port_list; + entity_t entity, get_port_lists_response, port_list, name, copy; + + entity = (entity_t) create_port_list_data.context->first->data; + + /* The import element, GET_PORT_LISTS_RESPONSE, overrides + * any other elements. */ + + get_port_lists_response = entity_child (entity, "get_port_lists_response"); + if (get_port_lists_response + && (port_list = entity_child (get_port_lists_response, "port_list"))) + { + char *comment, *import_name; + const char *port_list_id; + array_t *ranges; + + /* Get the port_list data from the XML. */ + + parse_port_list_entity (port_list, &port_list_id, &import_name, + &comment, &ranges); + + /* Check data, then create port list. */ + + if (import_name == NULL) + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_port_list", + "GET_PORT_LISTS_RESPONSE requires a" + " NAME element")); + else if (strlen (import_name) == 0) + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_port_list", + "GET_PORT_LISTS_RESPONSE NAME must be" + " at least one character long")); + else if (port_list_id == NULL) + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_port_list", + "GET_PORT_LISTS_RESPONSE must have an" + " ID attribute")); + else if (strlen (port_list_id) == 0) + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_port_list", + "GET_PORT_LISTS_RESPONSE ID must be" + " at least one character long")); + else if (!is_uuid (port_list_id)) + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_port_list", + "GET_PORT_LISTS_RESPONSE ID must be" + " a UUID")); + else switch (create_port_list (port_list_id, + import_name, + comment, + NULL, /* Optional port range string. */ + ranges, + &new_port_list)) + { + case 0: + { + char *uuid = port_list_uuid (new_port_list); + SENDF_TO_CLIENT_OR_FAIL + (XML_OK_CREATED_ID ("create_port_list"), + uuid); + log_event ("port_list", "Port List", uuid, "created"); + free (uuid); + break; + } + case 1: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_port_list", + "Port list exists already")); + log_event_fail ("port_list", "Port List", NULL, "created"); + break; + case 2: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_port_list", + "Port list exists already, in" + " trashcan")); + log_event_fail ("port_list", "Port List", NULL, "created"); + break; + case 99: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_port_list", + "Permission denied")); + log_event_fail ("port_list", "Port List", NULL, "created"); + break; + default: + case -1: + SEND_TO_CLIENT_OR_FAIL + (XML_INTERNAL_ERROR ("create_port_list")); + log_event_fail ("port_list", "Port List", NULL, "created"); + break; + } + + /* Cleanup. */ + + array_free (ranges); + + create_port_list_reset (); + return; + } + + copy = entity_child (entity, "copy"); + if (copy) + { + entity_t comment; + + /* Copy from an existing port list. */ + + name = entity_child (entity, "name"); + comment = entity_child (entity, "comment"); + + switch (copy_port_list (name ? entity_text (name) : NULL, + comment ? entity_text (comment) : NULL, + entity_text (copy), + &new_port_list)) + { + case 0: + { + char *uuid; + uuid = port_list_uuid (new_port_list); + SENDF_TO_CLIENT_OR_FAIL (XML_OK_CREATED_ID + ("create_port_list"), + uuid); + log_event ("port_list", "Port List", uuid, "created"); + free (uuid); + break; + } + case 1: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_port_list", + "Port List exists already")); + log_event_fail ("port_list", "Port List", NULL, "created"); + break; + case 2: + if (send_find_error_to_client ("create_port_list", + "port_list", + entity_text (copy), + gmp_parser)) + { + error_send_to_client (error); + return; + } + log_event_fail ("port_list", "Port List", NULL, "created"); + break; + case 99: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_port_list", + "Permission denied")); + log_event_fail ("port_list", "Port List", NULL, "created"); + break; + case -1: + default: + SEND_TO_CLIENT_OR_FAIL + (XML_INTERNAL_ERROR ("create_port_list")); + log_event_fail ("port_list", "Port List", NULL, "created"); + break; + } + + create_port_list_reset (); + return; + } + + /* Manually create a port list. */ + + name = entity_child (entity, "name"); + if (name == NULL) + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_port_list", + "A NAME is required")); + else if (strlen (entity_text (name)) == 0) + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_port_list", + "Name must be at" + " least one character long")); + else switch (create_port_list (NULL, + entity_text (name), + entity_child (entity, "comment") + ? entity_text (entity_child (entity, + "comment")) + : NULL, + entity_child (entity, "port_range") + ? entity_text (entity_child (entity, + "port_range")) + : NULL, + NULL, /* Optional port ranges array. */ + &new_port_list)) + { + case 1: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_port_list", + "Port list exists already")); + log_event_fail ("port_list", "Port List", NULL, "created"); + break; + case 4: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_port_list", + "Error in port range")); + log_event_fail ("port_list", "Port List", NULL, "created"); + break; + case 99: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_port_list", + "Permission denied")); + log_event_fail ("port_list", "Port List", NULL, "created"); + break; + case -1: + SEND_TO_CLIENT_OR_FAIL + (XML_INTERNAL_ERROR ("create_port_list")); + log_event_fail ("port_list", "Port List", NULL, "created"); + break; + default: + { + char *uuid = port_list_uuid (new_port_list); + SENDF_TO_CLIENT_OR_FAIL + (XML_OK_CREATED_ID ("create_port_list"), uuid); + log_event ("port_list", "Port List", uuid, "created"); + free (uuid); + break; + } + } + + create_port_list_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_port_list_element_end (gmp_parser_t *gmp_parser, GError **error, + const gchar *name) +{ + xml_handle_end_element (create_port_list_data.context, name); + if (create_port_list_data.context->done) + { + create_port_list_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_port_list_element_text (const gchar *text, gsize text_len) +{ + xml_handle_text (create_port_list_data.context, text, text_len); +} diff --git a/src/gmp_port_lists.h b/src/gmp_port_lists.h new file mode 100644 index 000000000..8be85b4cc --- /dev/null +++ b/src/gmp_port_lists.h @@ -0,0 +1,42 @@ +/* Copyright (C) 2020 Greenbone Networks GmbH + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef _GVMD_GMP_PORT_LISTS_H +#define _GVMD_GMP_PORT_LISTS_H + +#include "gmp_base.h" +#include "manage.h" + +void +create_port_list_start (gmp_parser_t *, const gchar **, const gchar **); + +void +create_port_list_element_start (gmp_parser_t *, const gchar *, const gchar **, + const gchar **); + +int +create_port_list_element_end (gmp_parser_t *, GError **error, const gchar *); + +void +create_port_list_element_text (const gchar *, gsize); + +void +parse_port_list_entity (entity_t, const char **, char **, char **, array_t **); + +#endif /* not _GVMD_GMP_PORT_LISTS_H */ From 10860d44b864b3d030b4d0580006dc95cb795776 Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Tue, 21 Jan 2020 16:27:37 +0200 Subject: [PATCH 3/4] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index be9822f00..06c0240db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Add "Base" scan config [#862](https://github.com/greenbone/gvmd/pull/862) - Add setting "BPM Data" [#915](https://github.com/greenbone/gvmd/pull/915) - Automatically load predefined configs from the feed [#931](https://github.com/greenbone/gvmd/pull/931) [#933](https://github.com/greenbone/gvmd/pull/933) [#934](https://github.com/greenbone/gvmd/pull/934) +- Automatically load predefined port lists from the feed [#950](https://github.com/greenbone/gvmd/pull/950) ### Changed - Update SCAP and CERT feed info in sync scripts [#810](https://github.com/greenbone/gvmd/pull/810) From 75e2befe4e6ab4ed530e2da6922deb164432b065 Mon Sep 17 00:00:00 2001 From: Matt Mundell Date: Tue, 21 Jan 2020 16:33:44 +0200 Subject: [PATCH 4/4] Add missing includes --- src/gmp_port_lists.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/gmp_port_lists.c b/src/gmp_port_lists.c index 701ebfc35..16df1cdc0 100644 --- a/src/gmp_port_lists.c +++ b/src/gmp_port_lists.c @@ -30,6 +30,10 @@ #include "manage_port_lists.h" #include "utils.h" +#include +#include +#include + /* CREATE_PORT_LIST. */