diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ca1ddf2d4..f1285310b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -168,12 +168,13 @@ add_executable (${BINARY_NAME} manage_acl.c manage_config_discovery.c manage_config_host_discovery.c manage_config_system_discovery.c manage_sql.c manage_sql_nvts.c manage_sql_secinfo.c - manage_sql_tickets.c + manage_sql_tickets.c manage_sql_tls_certificates.c manage_migrators.c scanner.c ${BACKEND_FILES} lsc_user.c lsc_crypt.c utils.c comm.c otp.c - gmp.c gmp_base.c gmp_delete.c gmp_get.c gmp_tickets.c) + gmp.c gmp_base.c gmp_delete.c gmp_get.c gmp_tickets.c + gmp_tls_certificates.c) if (BACKEND STREQUAL SQLITE3) target_link_libraries (${BINARY_NAME} m @@ -368,6 +369,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_tickets.c" + "${CMAKE_CURRENT_SOURCE_DIR}/gmp_tls_certificates.c" "${CMAKE_CURRENT_SOURCE_DIR}/otp.c" "${CMAKE_CURRENT_SOURCE_DIR}/manage.c" "${CMAKE_CURRENT_SOURCE_DIR}/manage_utils.c" @@ -385,6 +387,7 @@ set (C_FILES "${CMAKE_CURRENT_SOURCE_DIR}/gvmd.c" "${CMAKE_CURRENT_SOURCE_DIR}/manage_sql_nvts.c" "${CMAKE_CURRENT_SOURCE_DIR}/manage_sql_secinfo.c" "${CMAKE_CURRENT_SOURCE_DIR}/manage_sql_tickets.c" + "${CMAKE_CURRENT_SOURCE_DIR}/manage_sql_tls_certificates.c" "${CMAKE_CURRENT_SOURCE_DIR}/manage_sqlite3.c" "${CMAKE_CURRENT_SOURCE_DIR}/manage_migrators.c" "${CMAKE_CURRENT_SOURCE_DIR}/comm.c" diff --git a/src/gmp.c b/src/gmp.c index 4514fcd68..fad12779e 100644 --- a/src/gmp.c +++ b/src/gmp.c @@ -89,6 +89,7 @@ #include "gmp_delete.h" #include "gmp_get.h" #include "gmp_tickets.h" +#include "gmp_tls_certificates.h" #include "manage.h" #include "manage_acl.h" #include "utils.h" @@ -5199,6 +5200,7 @@ typedef enum CLIENT_CREATE_TASK_SCHEDULE_PERIODS, CLIENT_CREATE_TASK_TARGET, CLIENT_CREATE_TICKET, + CLIENT_CREATE_TLS_CERTIFICATE, CLIENT_CREATE_USER, CLIENT_CREATE_USER_COMMENT, CLIENT_CREATE_USER_COPY, @@ -5232,6 +5234,7 @@ typedef enum CLIENT_DELETE_TARGET, CLIENT_DELETE_TASK, CLIENT_DELETE_TICKET, + CLIENT_DELETE_TLS_CERTIFICATE, CLIENT_DELETE_USER, CLIENT_DESCRIBE_AUTH, CLIENT_EMPTY_TRASHCAN, @@ -5267,6 +5270,7 @@ typedef enum CLIENT_GET_TARGETS, CLIENT_GET_TASKS, CLIENT_GET_TICKETS, + CLIENT_GET_TLS_CERTIFICATES, CLIENT_GET_USERS, CLIENT_GET_VERSION, CLIENT_GET_VERSION_AUTHENTIC, @@ -5456,6 +5460,7 @@ typedef enum CLIENT_MODIFY_TASK_HOSTS_ORDERING, CLIENT_MODIFY_TASK_SCANNER, CLIENT_MODIFY_TICKET, + CLIENT_MODIFY_TLS_CERTIFICATE, CLIENT_MODIFY_USER, CLIENT_MODIFY_USER_COMMENT, CLIENT_MODIFY_USER_GROUPS, @@ -5810,6 +5815,12 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, attribute_values); set_client_state (CLIENT_CREATE_TICKET); } + else if (strcasecmp ("CREATE_TLS_CERTIFICATE", element_name) == 0) + { + create_tls_certificate_start (gmp_parser, attribute_names, + attribute_values); + set_client_state (CLIENT_CREATE_TLS_CERTIFICATE); + } else if (strcasecmp ("CREATE_USER", element_name) == 0) { set_client_state (CLIENT_CREATE_USER); @@ -6053,6 +6064,12 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, attribute_names, attribute_values); set_client_state (CLIENT_DELETE_TICKET); } + else if (strcasecmp ("DELETE_TLS_CERTIFICATE", element_name) == 0) + { + delete_start ("tls_certificate", "TLS Certificate", + attribute_names, attribute_values); + set_client_state (CLIENT_DELETE_TLS_CERTIFICATE); + } else if (strcasecmp ("DELETE_USER", element_name) == 0) { const gchar* attribute; @@ -6704,6 +6721,7 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, set_client_state (CLIENT_GET_TASKS); } ELSE_GET_START (tickets, TICKETS) + ELSE_GET_START (tls_certificates, TLS_CERTIFICATES) else if (strcasecmp ("GET_USERS", element_name) == 0) { get_data_parse_attributes (&get_users_data->get, "user", @@ -6894,6 +6912,12 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, attribute_values); set_client_state (CLIENT_MODIFY_TICKET); } + else if (strcasecmp ("MODIFY_TLS_CERTIFICATE", element_name) == 0) + { + modify_tls_certificate_start (gmp_parser, attribute_names, + attribute_values); + set_client_state (CLIENT_MODIFY_TLS_CERTIFICATE); + } else if (strcasecmp ("MODIFY_USER", element_name) == 0) { append_attribute (attribute_names, attribute_values, "user_id", @@ -7853,6 +7877,12 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, attribute_values); break; + case CLIENT_MODIFY_TLS_CERTIFICATE: + modify_tls_certificate_element_start (gmp_parser, element_name, + attribute_names, + attribute_values); + break; + case CLIENT_MODIFY_USER: if (strcasecmp ("COMMENT", element_name) == 0) set_client_state (CLIENT_MODIFY_USER_COMMENT); @@ -9248,6 +9278,12 @@ gmp_xml_handle_start_element (/* unused */ GMarkupParseContext* context, attribute_values); break; + case CLIENT_CREATE_TLS_CERTIFICATE: + create_tls_certificate_element_start (gmp_parser, element_name, + attribute_names, + attribute_values); + break; + case CLIENT_CREATE_USER: if (strcasecmp ("COMMENT", element_name) == 0) set_client_state (CLIENT_CREATE_USER_COMMENT); @@ -13690,9 +13726,9 @@ handle_get_credentials (gmp_parser_t *gmp_parser, GError **error) time_t activation_time, expiration_time; gchar *activation_time_str, *expiration_time_str; gchar *fingerprint, *issuer; - get_certificate_info (cert, + get_certificate_info (cert, -1, &activation_time, &expiration_time, - &fingerprint, &issuer); + &fingerprint, NULL, &issuer, NULL); activation_time_str = certificate_iso_time (activation_time); expiration_time_str = certificate_iso_time (expiration_time); SENDF_TO_CLIENT_OR_FAIL @@ -17051,9 +17087,9 @@ handle_get_scanners (gmp_parser_t *gmp_parser, GError **error) { /* CA Certificate */ gchar *fingerprint, *issuer; - get_certificate_info (scanner_iterator_ca_pub (&scanners), + get_certificate_info (scanner_iterator_ca_pub (&scanners), -1, &activation_time, &expiration_time, - &fingerprint, &issuer); + &fingerprint, NULL, &issuer, NULL); activation_time_str = certificate_iso_time (activation_time); expiration_time_str = certificate_iso_time (expiration_time); SENDF_TO_CLIENT_OR_FAIL @@ -17096,9 +17132,9 @@ handle_get_scanners (gmp_parser_t *gmp_parser, GError **error) { /* Certificate */ gchar *fingerprint, *issuer; - get_certificate_info (scanner_iterator_key_pub (&scanners), + get_certificate_info (scanner_iterator_key_pub (&scanners), -1, &activation_time, &expiration_time, - &fingerprint, &issuer); + &fingerprint, NULL, &issuer, NULL); activation_time_str = certificate_iso_time (activation_time); expiration_time_str = certificate_iso_time (expiration_time); SENDF_TO_CLIENT_OR_FAIL @@ -17974,10 +18010,10 @@ handle_get_settings (gmp_parser_t *gmp_parser, GError **error) gchar *activation_time_str, *expiration_time_str, *fingerprint; gchar *issuer; - get_certificate_info (setting_iterator_value (&settings), + get_certificate_info (setting_iterator_value (&settings), -1, &activation_time, &expiration_time, &fingerprint, - &issuer); + NULL, &issuer, NULL); activation_time_str = certificate_iso_time (activation_time); expiration_time_str = certificate_iso_time (expiration_time); SENDF_TO_CLIENT_OR_FAIL @@ -20559,6 +20595,7 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, break; case CLIENT_DELETE_TICKET: + case CLIENT_DELETE_TLS_CERTIFICATE: delete_run (gmp_parser, error); set_client_state (CLIENT_AUTHENTIC); break; @@ -20726,9 +20763,9 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, "%s", ldap_cacert); - get_certificate_info (ldap_cacert, &activation_time, + get_certificate_info (ldap_cacert, -1, &activation_time, &expiration_time, &fingerprint, - &issuer); + NULL, &issuer, NULL); activation_time_str = certificate_iso_time (activation_time); expiration_time_str = certificate_iso_time (expiration_time); SENDF_TO_CLIENT_OR_FAIL @@ -20907,6 +20944,8 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, CASE_GET_END (TICKETS, tickets); + CASE_GET_END (TLS_CERTIFICATES, tls_certificates); + case CLIENT_GET_USERS: handle_get_users (gmp_parser, error); break; @@ -25107,6 +25146,12 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, set_client_state (CLIENT_AUTHENTIC); break; + case CLIENT_CREATE_TLS_CERTIFICATE: + if (create_tls_certificate_element_end (gmp_parser, error, + element_name)) + set_client_state (CLIENT_AUTHENTIC); + break; + case CLIENT_CREATE_USER: { gchar *errdesc; @@ -27839,6 +27884,13 @@ gmp_xml_handle_end_element (/* unused */ GMarkupParseContext* context, set_client_state (CLIENT_AUTHENTIC); break; + case CLIENT_MODIFY_TLS_CERTIFICATE: + if (modify_tls_certificate_element_end (gmp_parser, + error, + element_name)) + set_client_state (CLIENT_AUTHENTIC); + break; + case CLIENT_MODIFY_USER: { if ((modify_user_data->name == NULL @@ -29752,6 +29804,10 @@ gmp_xml_handle_text (/* unused */ GMarkupParseContext* context, create_ticket_element_text (text, text_len); break; + case CLIENT_CREATE_TLS_CERTIFICATE: + create_tls_certificate_element_text (text, text_len); + break; + APPEND (CLIENT_CREATE_USER_COMMENT, &create_user_data->comment); @@ -30059,6 +30115,9 @@ gmp_xml_handle_text (/* unused */ GMarkupParseContext* context, modify_ticket_element_text (text, text_len); break; + case CLIENT_MODIFY_TLS_CERTIFICATE: + modify_tls_certificate_element_text (text, text_len); + break; APPEND (CLIENT_RUN_WIZARD_MODE, &run_wizard_data->mode); diff --git a/src/gmp_tls_certificates.c b/src/gmp_tls_certificates.c new file mode 100644 index 000000000..875104f23 --- /dev/null +++ b/src/gmp_tls_certificates.c @@ -0,0 +1,730 @@ +/* Copyright (C) 2019 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_tls_certificates.c + * @brief GVM GMP layer: TLS certificates + * + * This includes function and variable definitions for GMP handling + * of TLS certificates. + */ + +#include "gmp_tls_certificates.h" +#include "gmp_base.h" +#include "gmp_get.h" +#include "manage_tls_certificates.h" + +#include +#include +#include + +#include + +#undef G_LOG_DOMAIN +/** + * @brief GLib log domain. + */ +#define G_LOG_DOMAIN "md gmp" + + + +/* GET_TLS_CERTIFICATES. */ + +/** + * @brief The get_tls_certificates command. + */ +typedef struct +{ + get_data_t get; ///< Get args. +} get_tls_certificates_t; + +/** + * @brief Parser callback data. + * + * This is initially 0 because it's a global variable. + */ +static get_tls_certificates_t get_tls_certificates_data; + +/** + * @brief Reset command data. + */ +static void +get_tls_certificates_reset () +{ + get_data_reset (&get_tls_certificates_data.get); + memset (&get_tls_certificates_data, 0, sizeof (get_tls_certificates_t)); +} + +/** + * @brief Handle command start element. + * + * @param[in] attribute_names All attribute names. + * @param[in] attribute_values All attribute values. + */ +void +get_tls_certificates_start (const gchar **attribute_names, + const gchar **attribute_values) +{ + get_data_parse_attributes (&get_tls_certificates_data.get, "tls_certificate", + attribute_names, + attribute_values); +} + +/** + * @brief Handle end element. + * + * @param[in] gmp_parser GMP parser. + * @param[in] error Error parameter. + */ +void +get_tls_certificates_run (gmp_parser_t *gmp_parser, GError **error) +{ + iterator_t tls_certificates; + int count, filtered, ret, first; + + count = 0; + + ret = init_get ("get_tls_certificates", + &get_tls_certificates_data.get, + "TLS Certificates", + &first); + if (ret) + { + switch (ret) + { + case 99: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("get_tls_certificates", + "Permission denied")); + break; + default: + internal_error_send_to_client (error); + get_tls_certificates_reset (); + return; + } + get_tls_certificates_reset (); + return; + } + + /* Setup the iterator. */ + + ret = init_tls_certificate_iterator (&tls_certificates, + &get_tls_certificates_data.get); + if (ret) + { + switch (ret) + { + case 1: + if (send_find_error_to_client ("get_tls_certificates", + "tls_certificate", + get_tls_certificates_data.get.id, + gmp_parser)) + { + error_send_to_client (error); + get_tls_certificates_reset (); + return; + } + break; + case 2: + if (send_find_error_to_client + ("get_tls_certificates", "filter", + get_tls_certificates_data.get.filt_id, gmp_parser)) + { + error_send_to_client (error); + get_tls_certificates_reset (); + return; + } + break; + case -1: + SEND_TO_CLIENT_OR_FAIL + (XML_INTERNAL_ERROR ("get_tls_certificates")); + break; + } + get_tls_certificates_reset (); + return; + } + + /* Loop through tls_certificates, sending XML. */ + + SEND_GET_START ("tls_certificate"); + while (1) + { + ret = get_next (&tls_certificates, &get_tls_certificates_data.get, + &first, &count, init_tls_certificate_iterator); + if (ret == 1) + break; + if (ret == -1) + { + internal_error_send_to_client (error); + get_tls_certificates_reset (); + return; + } + + /* Send generic GET command elements. */ + + SEND_GET_COMMON (tls_certificate, &get_tls_certificates_data.get, + &tls_certificates); + + /* Send tls_certificate info. */ + SENDF_TO_CLIENT_OR_FAIL + ("%s" + "%s" + "%d" + "%d" + "%s" + "%s" + "%s" + "%s" + "", + tls_certificate_iterator_certificate_format (&tls_certificates) + ? tls_certificate_iterator_certificate_format (&tls_certificates) + : "unknown", + get_tls_certificates_data.get.details + ? tls_certificate_iterator_certificate (&tls_certificates) + : "", + tls_certificate_iterator_md5_fingerprint (&tls_certificates), + tls_certificate_iterator_trust (&tls_certificates), + tls_certificate_iterator_valid (&tls_certificates), + tls_certificate_iterator_activation_time (&tls_certificates), + tls_certificate_iterator_expiration_time (&tls_certificates), + tls_certificate_iterator_subject_dn (&tls_certificates), + tls_certificate_iterator_issuer_dn (&tls_certificates)); + count++; + } + cleanup_iterator (&tls_certificates); + filtered = get_tls_certificates_data.get.id + ? 1 + : tls_certificate_count (&get_tls_certificates_data.get); + SEND_GET_END ("tls_certificate", + &get_tls_certificates_data.get, + count, + filtered); + + get_tls_certificates_reset (); +} + + +/* CREATE_TLS_CERTIFICATE. */ + +/** + * @brief The create_tls_certificate command. + */ +typedef struct +{ + context_data_t *context; ///< XML parser context. +} create_tls_certificate_t; + +/** + * @brief Parser callback data. + * + * This is initially 0 because it's a global variable. + */ +static create_tls_certificate_t create_tls_certificate_data; + +/** + * @brief Reset command data. + */ +static void +create_tls_certificate_reset () +{ + if (create_tls_certificate_data.context->first) + { + free_entity (create_tls_certificate_data.context->first->data); + g_slist_free_1 (create_tls_certificate_data.context->first); + } + g_free (create_tls_certificate_data.context); + memset (&create_tls_certificate_data, 0, sizeof (create_tls_certificate_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_tls_certificate_start (gmp_parser_t *gmp_parser, + const gchar **attribute_names, + const gchar **attribute_values) +{ + memset (&create_tls_certificate_data, 0, sizeof (create_tls_certificate_t)); + create_tls_certificate_data.context = g_malloc0 (sizeof (context_data_t)); + create_tls_certificate_element_start (gmp_parser, "create_tls_certificate", + 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_tls_certificate_element_start (gmp_parser_t *gmp_parser, + const gchar *name, + const gchar **attribute_names, + const gchar **attribute_values) +{ + xml_handle_start_element (create_tls_certificate_data.context, name, + attribute_names, attribute_values); +} + +/** + * @brief Execute command. + * + * @param[in] gmp_parser GMP parser. + * @param[in] error Error parameter. + */ +void +create_tls_certificate_run (gmp_parser_t *gmp_parser, GError **error) +{ + entity_t entity, copy, comment, name, certificate, trust; + int trust_int; + tls_certificate_t new_tls_certificate; + + entity = (entity_t) create_tls_certificate_data.context->first->data; + + copy = entity_child (entity, "copy"); + + if (copy) + { + /* Copy from an existing tls_certificate and exit. */ + + name = entity_child (entity, "name"); + comment = entity_child (entity, "comment"); + switch (copy_tls_certificate (name ? entity_text (name) : NULL, + comment ? entity_text (comment) : NULL, + entity_text (copy), &new_tls_certificate)) + { + case 0: + { + char *uuid; + uuid = tls_certificate_uuid (new_tls_certificate); + SENDF_TO_CLIENT_OR_FAIL (XML_OK_CREATED_ID + ("create_tls_certificate"), + uuid); + log_event ("tls_certificate", "TLS Certificate", uuid, "created"); + free (uuid); + break; + } + case 1: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_tls_certificate", + "TLS Certificate exists already")); + log_event_fail ("tls_certificate", "TLS Certificate", NULL, + "created"); + break; + case 2: + if (send_find_error_to_client ("create_tls_certificate", + "tls_certificate", + entity_text (copy), + gmp_parser)) + { + error_send_to_client (error); + return; + } + log_event_fail ("tls_certificate", + "TLS Certificate", + NULL, + "created"); + break; + case 99: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_tls_certificate", + "Permission denied")); + log_event_fail ("tls_certificate", + "TLS Certificate", + NULL, + "created"); + break; + case -1: + default: + SEND_TO_CLIENT_OR_FAIL + (XML_INTERNAL_ERROR ("create_tls_certificate")); + log_event_fail ("tls_certificate", + "TLS Certificate", + NULL, + "created"); + break; + } + create_tls_certificate_reset (); + return; + } + + /* Check given info. */ + + name = entity_child (entity, "name"); + comment = entity_child (entity, "comment"); + certificate = entity_child (entity, "certificate"); + trust = entity_child (entity, "trust"); + + if (certificate == NULL + || strcmp (entity_text (certificate), "") == 0) + { + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_tls_certificate", + "CERTIFICATE is required and must not be empty.")); + log_event_fail ("tls_certificate", + "TLS Certificate", + NULL, + "created"); + return; + } + + trust_int = 0; + if (trust) + { + if (strcmp (entity_text (trust), "") + && strcmp (entity_text (trust), "0")) + trust_int = 1; + } + + switch (create_tls_certificate + (name ? entity_text (name) : NULL, + comment ? entity_text (comment) : "", + certificate ? entity_text (certificate) : NULL, + trust_int, + &new_tls_certificate)) + { + case 0: + { + char *uuid = tls_certificate_uuid (new_tls_certificate); + SENDF_TO_CLIENT_OR_FAIL (XML_OK_CREATED_ID ("create_tls_certificate"), + uuid); + log_event ("tls_certificate", "TLS Certificate", uuid, "created"); + free (uuid); + break; + } + case 1: + { + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_tls_certificate", + "Invalid certificate content")); + log_event_fail ("tls_certificate", + "TLS Certificate", + NULL, + "created"); + break; + } + case 2: + { + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_tls_certificate", + "CERTIFICATE is not valid Base64.")); + log_event_fail ("tls_certificate", + "TLS Certificate", + NULL, + "created"); + return; + } + case 99: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("create_tls_certificate", + "Permission denied")); + log_event_fail ("tls_certificate", "TLS Certificate", NULL, "created"); + break; + case -1: + default: + SEND_TO_CLIENT_OR_FAIL (XML_INTERNAL_ERROR ("create_tls_certificate")); + log_event_fail ("tls_certificate", "TLS Certificate", NULL, "created"); + break; + } + + create_tls_certificate_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_tls_certificate_element_end (gmp_parser_t *gmp_parser, GError **error, + const gchar *name) +{ + xml_handle_end_element (create_tls_certificate_data.context, name); + if (create_tls_certificate_data.context->done) + { + create_tls_certificate_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_tls_certificate_element_text (const gchar *text, gsize text_len) +{ + xml_handle_text (create_tls_certificate_data.context, text, text_len); +} + + +/* MODIFY_TLS_CERTIFICATE. */ + +/** + * @brief The modify_tls_certificate command. + */ +typedef struct +{ + context_data_t *context; ///< XML parser context. +} modify_tls_certificate_t; + +/** + * @brief Parser callback data. + * + * This is initially 0 because it's a global variable. + */ +static modify_tls_certificate_t modify_tls_certificate_data; + +/** + * @brief Reset command data. + */ +static void +modify_tls_certificate_reset () +{ + if (modify_tls_certificate_data.context->first) + { + free_entity (modify_tls_certificate_data.context->first->data); + g_slist_free_1 (modify_tls_certificate_data.context->first); + } + g_free (modify_tls_certificate_data.context); + memset (&modify_tls_certificate_data, 0, sizeof (modify_tls_certificate_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_tls_certificate_start (gmp_parser_t *gmp_parser, + const gchar **attribute_names, + const gchar **attribute_values) +{ + memset (&modify_tls_certificate_data, + 0, + sizeof (modify_tls_certificate_t)); + modify_tls_certificate_data.context = g_malloc0 (sizeof (context_data_t)); + modify_tls_certificate_element_start (gmp_parser, + "modify_tls_certificate", + 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_tls_certificate_element_start (gmp_parser_t *gmp_parser, + const gchar *name, + const gchar **attribute_names, + const gchar **attribute_values) +{ + xml_handle_start_element (modify_tls_certificate_data.context, + name, + attribute_names, + attribute_values); +} + +/** + * @brief Execute command. + * + * @param[in] gmp_parser GMP parser. + * @param[in] error Error parameter. + */ +void +modify_tls_certificate_run (gmp_parser_t *gmp_parser, GError **error) +{ + entity_t entity, comment, name, certificate, trust; + const char *tls_certificate_id; + int trust_int; + + entity = (entity_t) modify_tls_certificate_data.context->first->data; + + tls_certificate_id = entity_attribute (entity, "tls_certificate_id"); + + /* Check the given info. */ + + comment = entity_child (entity, "comment"); + name = entity_child (entity, "name"); + certificate = entity_child (entity, "certificate"); + trust = entity_child (entity, "trust"); + + if (certificate + && strcmp (entity_text (certificate), "") == 0) + { + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("modify_tls_certificate", + "New CERTIFICATE must not be empty if given.")); + log_event_fail ("tls_certificate", + "TLS Certificate", + NULL, + "modified"); + return; + } + + trust_int = -1; + if (trust) + { + if (strcmp (entity_text (trust), "") + && strcmp (entity_text (trust), "0")) + trust_int = 1; + else + trust_int = 0; + } + + /* Modify the tls_certificate. */ + + if (tls_certificate_id == NULL) + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("modify_tls_certificate", + "MODIFY_TLS_CERTIFICATE requires a tls_certificate_id" + " attribute")); + else switch (modify_tls_certificate + (tls_certificate_id, + comment ? entity_text (comment) : NULL, + name ? entity_text (name) : NULL, + certificate ? entity_text (certificate) : NULL, + trust_int)) + { + case 0: + SENDF_TO_CLIENT_OR_FAIL (XML_OK ("modify_tls_certificate")); + log_event ("tls_certificate", + "TLS Certificate", + tls_certificate_id, + "modified"); + break; + case 1: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("modify_tls_certificate", + "TLS Certificate exists already")); + log_event_fail ("tls_certificate", + "TLS certificate", + tls_certificate_id, + "modified"); + break; + case 2: + log_event_fail ("tls_certificate", + "TLS Certificate", + tls_certificate_id, + "modified"); + if (send_find_error_to_client ("modify_tls_certificate", + "TLS certificate", + tls_certificate_id, + gmp_parser)) + { + error_send_to_client (error); + return; + } + break; + case 3: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("modify_tls_certificate", + "Invalid certificate content")); + + log_event_fail ("tls_certificate", + "TLS Certificate", + tls_certificate_id, + "modified"); + break; + case 4: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("modify_tls_certificate", + "CERTIFICATE is not valid Base64.")); + log_event_fail ("tls_certificate", + "TLS Certificate", + NULL, + "modified"); + return; + case 99: + SEND_TO_CLIENT_OR_FAIL + (XML_ERROR_SYNTAX ("modify_tls_certificate", + "Permission denied")); + log_event_fail ("tls_certificate", + "TLS Certificate", + tls_certificate_id, + "modified"); + break; + case -1: + default: + SEND_TO_CLIENT_OR_FAIL + (XML_INTERNAL_ERROR ("modify_tls_certificate")); + log_event_fail ("tls_certificate", + "TLS Certificate", + tls_certificate_id, + "modified"); + break; + } + + modify_tls_certificate_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_tls_certificate_element_end (gmp_parser_t *gmp_parser, GError **error, + const gchar *name) +{ + xml_handle_end_element (modify_tls_certificate_data.context, name); + if (modify_tls_certificate_data.context->done) + { + modify_tls_certificate_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_tls_certificate_element_text (const gchar *text, gsize text_len) +{ + xml_handle_text (modify_tls_certificate_data.context, text, text_len); +} + diff --git a/src/gmp_tls_certificates.h b/src/gmp_tls_certificates.h new file mode 100644 index 000000000..91a860635 --- /dev/null +++ b/src/gmp_tls_certificates.h @@ -0,0 +1,67 @@ +/* Copyright (C) 2019 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_tls_certificates.h + * @brief GVM GMP layer: TLS Certificates headers + * + * Headers for GMP handling of TLS Certificates. + */ + +#ifndef _GVMD_GMP_TLS_CERTIFICATES_H +#define _GVMD_GMP_TLS_CERTIFICATES_H + +#include "gmp_base.h" +#include "manage.h" + +void +get_tls_certificates_start (const gchar **, const gchar **); + +void +get_tls_certificates_run (gmp_parser_t *, GError **); + +void +create_tls_certificate_start (gmp_parser_t *, const gchar **, const gchar **); + +void +create_tls_certificate_element_start (gmp_parser_t *, const gchar *, + const gchar **, const gchar **); + +int +create_tls_certificate_element_end (gmp_parser_t *, GError **error, + const gchar *); + +void +create_tls_certificate_element_text (const gchar *, gsize); + +void +modify_tls_certificate_start (gmp_parser_t *, const gchar **, const gchar **); + +void +modify_tls_certificate_element_start (gmp_parser_t *, const gchar *, + const gchar **, const gchar **); + +int +modify_tls_certificate_element_end (gmp_parser_t *, GError **error, + const gchar *); + +void +modify_tls_certificate_element_text (const gchar *, gsize); + +#endif /* not _GVMD_GMP_TLS_CERTIFICATES_H */ diff --git a/src/manage.c b/src/manage.c index b630f0184..0d79fa891 100644 --- a/src/manage.c +++ b/src/manage.c @@ -51,6 +51,7 @@ #include "manage_sql_secinfo.h" #include "manage_sql_nvts.h" #include "manage_sql_tickets.h" +#include "manage_sql_tls_certificates.h" #include "comm.h" #include "utils.h" @@ -299,20 +300,25 @@ truncate_private_key (const gchar* private_key) /** * @brief Gathers info from a certificate. * - * @param[in] certificate The certificate to get data from. - * @param[out] activation_time Pointer to write activation time to. - * @param[out] expiration_time Pointer to write expiration time to. - * @param[out] fingerprint Pointer for newly allocated fingerprint. - * @param[out] issuer Pointer for newly allocated issuer DN. + * @param[in] certificate The certificate to get data from. + * @param[in] certificate_len Length of certificate, -1: null-terminated + * @param[out] activation_time Pointer to write activation time to. + * @param[out] expiration_time Pointer to write expiration time to. + * @param[out] fingerprint Pointer for newly allocated fingerprint. + * @param[out] subject Pointer for newly allocated subject DN. + * @param[out] issuer Pointer for newly allocated issuer DN. + * @param[out] certificate_format Pointer to certificate format. * * @return 0 success, -1 error. */ int -get_certificate_info (const gchar* certificate, +get_certificate_info (const gchar* certificate, gssize certificate_len, time_t* activation_time, time_t* expiration_time, - gchar** fingerprint, gchar** issuer) + gchar** fingerprint, gchar **subject, gchar** issuer, + gnutls_x509_crt_fmt_t *certificate_format) { gchar *cert_truncated; + gnutls_x509_crt_fmt_t certificate_format_internal; cert_truncated = NULL; if (activation_time) @@ -321,32 +327,61 @@ get_certificate_info (const gchar* certificate, *expiration_time = -1; if (fingerprint) *fingerprint = NULL; + if (subject) + *subject = NULL; if (issuer) *issuer = NULL; + if (certificate_format) + *certificate_format = 0; if (certificate) { int err; gnutls_datum_t cert_datum; gnutls_x509_crt_t gnutls_cert; + static const gchar* begin_str = "-----BEGIN "; - cert_truncated = truncate_certificate (certificate); - if (cert_truncated == NULL) + if (g_strstr_len (certificate, certificate_len, begin_str)) { - return -1; + cert_truncated = truncate_certificate (certificate); + if (cert_truncated == NULL) + { + return -1; + } + certificate_format_internal = GNUTLS_X509_FMT_PEM; + } + else + { + if (certificate_len < 0) + { + g_warning ("%s: PEM encoded certificate expected if" + " certificate_length is negative", + __FUNCTION__); + return -1; + } + + cert_truncated = g_memdup (certificate, certificate_len); + certificate_format_internal = GNUTLS_X509_FMT_DER; } + cert_datum.data = (unsigned char*) cert_truncated; - cert_datum.size = strlen (cert_truncated); + if (certificate_len < 0) + cert_datum.size = strlen (cert_truncated); + else + cert_datum.size = certificate_len; gnutls_x509_crt_init (&gnutls_cert); err = gnutls_x509_crt_import (gnutls_cert, &cert_datum, - GNUTLS_X509_FMT_PEM); + certificate_format_internal); if (err) { g_free (cert_truncated); return -1; } + if (certificate_format) + *certificate_format = certificate_format_internal; + if (activation_time) { *activation_time @@ -384,6 +419,17 @@ get_certificate_info (const gchar* certificate, g_string_free (string, FALSE); } + if (subject) + { + size_t buffer_size; + gchar *buffer; + gnutls_x509_crt_get_dn (gnutls_cert, NULL, &buffer_size); + buffer = g_malloc (buffer_size); + gnutls_x509_crt_get_dn (gnutls_cert, buffer, &buffer_size); + + *subject = buffer; + } + if (issuer) { size_t buffer_size; @@ -9960,6 +10006,8 @@ delete_resource (const char *type, const char *resource_id, int ultimate) { if (strcasecmp (type, "ticket") == 0) return delete_ticket (resource_id, ultimate); + if (strcasecmp (type, "tls_certificate") == 0) + return delete_tls_certificate (resource_id, ultimate); assert (0); return -1; } diff --git a/src/manage.h b/src/manage.h index 759daed53..893796b38 100644 --- a/src/manage.h +++ b/src/manage.h @@ -158,7 +158,14 @@ gchar* truncate_private_key (const gchar*); int -get_certificate_info (const gchar*, time_t*, time_t*, gchar**, gchar**); +get_certificate_info (const gchar *, + gssize, + time_t *, + time_t *, + gchar **, + gchar **, + gchar **, + gnutls_x509_crt_fmt_t *); gchar * certificate_iso_time (time_t); @@ -331,6 +338,7 @@ typedef long long int tag_t; typedef long long int target_t; typedef long long int task_t; typedef long long int ticket_t; +typedef long long int tls_certificate_t; typedef long long int result_t; typedef long long int report_t; typedef long long int report_host_t; diff --git a/src/manage_pg.c b/src/manage_pg.c index 11531a177..6caa18e44 100644 --- a/src/manage_pg.c +++ b/src/manage_pg.c @@ -991,6 +991,17 @@ manage_create_sql_functions () " END;" "$$ LANGUAGE plpgsql;"); + sql ("CREATE OR REPLACE FUNCTION certificate_iso_time (integer)" + " RETURNS text AS $$" + " BEGIN" + " RETURN CASE" + " WHEN ($1 = 0) THEN 'unlimited'" + " WHEN ($1 = -1) THEN 'unknown'" + " ELSE iso_time($1)" + " END;" + " END;" + "$$ LANGUAGE plpgsql;"); + sql ("CREATE OR REPLACE FUNCTION days_from_now (seconds integer)" " RETURNS integer AS $$" " DECLARE" @@ -2505,6 +2516,40 @@ create_tables () " result_uuid text," " report integer);"); // REFERENCES reports_trash (id) ON DELETE RESTRICT + sql ("CREATE TABLE IF NOT EXISTS tls_certificates" + " (id SERIAL PRIMARY KEY," + " uuid text UNIQUE NOT NULL," + " owner integer REFERENCES users (id) ON DELETE RESTRICT," + " name text," + " comment text," + " creation_time integer," + " modification_time integer," + " certificate text," + " subject_dn text," + " issuer_dn text," + " activation_time integer," + " expiration_time integer," + " md5_fingerprint text," + " trust integer," + " certificate_format text);"); + + sql ("CREATE TABLE IF NOT EXISTS tls_certificates_trash" + " (id SERIAL PRIMARY KEY," + " uuid text UNIQUE NOT NULL," + " owner integer REFERENCES users (id) ON DELETE RESTRICT," + " name text," + " comment text," + " creation_time integer," + " modification_time integer," + " certificate text," + " subject_dn text," + " issuer_dn text," + " activation_time integer," + " expiration_time integer," + " md5_fingerprint text," + " trust integer," + " certificate_format text);"); + sql ("CREATE TABLE IF NOT EXISTS scanners" " (id SERIAL PRIMARY KEY," " uuid text UNIQUE NOT NULL," diff --git a/src/manage_sql.c b/src/manage_sql.c index bbbaf6c8d..40469b2c3 100644 --- a/src/manage_sql.c +++ b/src/manage_sql.c @@ -35,6 +35,7 @@ #include "manage_sql_nvts.h" #include "manage_tickets.h" #include "manage_sql_tickets.h" +#include "manage_sql_tls_certificates.h" #include "manage_acl.h" #include "lsc_user.h" #include "sql.h" @@ -586,6 +587,7 @@ command_t gmp_commands[] {"CREATE_TARGET", "Create a target."}, {"CREATE_TASK", "Create a task."}, {"CREATE_TICKET", "Create a ticket."}, + {"CREATE_TLS_CERTIFICATE", "Create a TLS certificate."}, {"CREATE_USER", "Create a new user."}, {"DELETE_AGENT", "Delete an agent."}, {"DELETE_ALERT", "Delete an alert."}, @@ -608,6 +610,7 @@ command_t gmp_commands[] {"DELETE_TARGET", "Delete a target."}, {"DELETE_TASK", "Delete a task."}, {"DELETE_TICKET", "Delete a ticket."}, + {"DELETE_TLS_CERTIFICATE", "Delete a TLS certificate."}, {"DELETE_USER", "Delete an existing user."}, {"DESCRIBE_AUTH", "Get details about the used authentication methods."}, {"EMPTY_TRASHCAN", "Empty the trashcan."}, @@ -640,6 +643,7 @@ command_t gmp_commands[] {"GET_TARGETS", "Get all targets."}, {"GET_TASKS", "Get all tasks."}, {"GET_TICKETS", "Get all tickets."}, + {"GET_TLS_CERTIFICATES", "Get all TLS certificates."}, {"GET_USERS", "Get all users."}, {"GET_VERSION", "Get the Greenbone Management Protocol version."}, {"GET_VULNS", "Get all vulnerabilities."}, @@ -666,6 +670,7 @@ command_t gmp_commands[] {"MODIFY_TARGET", "Modify an existing target."}, {"MODIFY_TASK", "Update an existing task."}, {"MODIFY_TICKET", "Modify an existing ticket."}, + {"MODIFY_TLS_CERTIFICATE", "Modify an existing TLS certificate."}, {"MODIFY_USER", "Modify a user."}, {"MOVE_TASK", "Assign task to another slave scanner, even while running."}, {"RESTORE", "Restore a resource."}, @@ -59966,10 +59971,16 @@ manage_restore (const char *id) return 99; } + /* Ticket. */ ret = restore_ticket (id); if (ret != 2) return ret; + /* TLS Certificate. */ + ret = restore_tls_certificate (id); + if (ret != 2) + return ret; + /* Agent. */ if (find_trash ("agent", id, &resource)) @@ -61171,6 +61182,7 @@ manage_empty_trashcan () current_credentials.uuid); sql ("DELETE FROM configs_trash" WHERE_OWNER); empty_trashcan_tickets (); + empty_trashcan_tls_certificates(); sql ("DELETE FROM permissions" " WHERE subject_type = 'group'" " AND subject IN (SELECT id from groups_trash" @@ -65765,6 +65777,7 @@ delete_user (const char *user_id_arg, const char *name_arg, int ultimate, inheritor, user); inherit_tickets (user, inheritor); + inherit_tls_certificates (user, inheritor); sql ("UPDATE groups SET owner = %llu WHERE owner = %llu;", inheritor, user); @@ -65832,6 +65845,7 @@ delete_user (const char *user_id_arg, const char *name_arg, int ultimate, user); sql ("DELETE FROM tags_trash WHERE owner = %llu;", user); delete_tickets_user (user); + delete_tls_certificates_user (user); /* Delete assets (not directly referenced). */ diff --git a/src/manage_sql_tls_certificates.c b/src/manage_sql_tls_certificates.c new file mode 100644 index 000000000..74ab63b21 --- /dev/null +++ b/src/manage_sql_tls_certificates.c @@ -0,0 +1,932 @@ +/* Copyright (C) 2019 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 manage_sql_tls_certificates.c + * @brief GVM management layer: TLS Certificates SQL + * + * The TLS Certificates SQL for the GVM management layer. + */ + +#include "manage_tls_certificates.h" +#include "manage_acl.h" +#include "manage_sql_tls_certificates.h" +#include "manage_sql.h" +#include "sql.h" + +#include +#include + +#undef G_LOG_DOMAIN +/** + * @brief GLib log domain. + */ +#define G_LOG_DOMAIN "md manage" + +/** + * @brief Filter columns for tls_certificate iterator. + */ +#define TLS_CERTIFICATE_ITERATOR_FILTER_COLUMNS \ + { GET_ITERATOR_FILTER_COLUMNS, "subject_dn", "issuer_dn", "md5_fingerprint", \ + "activates", "expires", "valid", "certificate_format", NULL } + +/** + * @brief TLS Certificate iterator columns. + */ +#define TLS_CERTIFICATE_ITERATOR_COLUMNS \ + { \ + GET_ITERATOR_COLUMNS (tls_certificates), \ + { \ + "certificate", \ + NULL, \ + KEYWORD_TYPE_STRING \ + }, \ + { \ + "subject_dn", \ + NULL, \ + KEYWORD_TYPE_STRING \ + }, \ + { \ + "issuer_dn", \ + NULL, \ + KEYWORD_TYPE_STRING \ + }, \ + { \ + "trust", \ + NULL, \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "md5_fingerprint", \ + NULL, \ + KEYWORD_TYPE_STRING \ + }, \ + { \ + "certificate_iso_time (activation_time)", \ + "activation_time", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "certificate_iso_time (expiration_time)", \ + "expiration_time", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "(CASE WHEN (expiration_time >= m_now() OR expiration_time = -1)" \ + " AND (activation_time <= m_now() OR activation_time = -1)" \ + " THEN 1 ELSE 0 END)", \ + "valid", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "certificate_format", \ + NULL, \ + KEYWORD_TYPE_STRING \ + }, \ + { \ + "activation_time", \ + "activates", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "expiration_time", \ + "expires", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { NULL, NULL, KEYWORD_TYPE_UNKNOWN } \ + } + +/** + * @brief TLS Certificate iterator columns for trash case. + */ +#define TLS_CERTIFICATE_ITERATOR_TRASH_COLUMNS \ + { \ + GET_ITERATOR_COLUMNS (tls_certificates_trash), \ + { \ + "certificate", \ + NULL, \ + KEYWORD_TYPE_STRING \ + }, \ + { \ + "subject_dn", \ + NULL, \ + KEYWORD_TYPE_STRING \ + }, \ + { \ + "issuer_dn", \ + NULL, \ + KEYWORD_TYPE_STRING \ + }, \ + { \ + "trust", \ + NULL, \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "md5_fingerprint", \ + NULL, \ + KEYWORD_TYPE_STRING \ + }, \ + { \ + "iso_time (activation_time)", \ + "activation_time", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "iso_time (expiration_time)", \ + "expiration_time", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "(CASE WHEN (expiration_time >= m_now() OR expiration_time = -1)" \ + " AND (activation_time <= m_now() OR activation_time = -1)" \ + " THEN 1 ELSE 0 END)", \ + "valid", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "certificate_format", \ + NULL, \ + KEYWORD_TYPE_STRING \ + }, \ + { \ + "activation_time", \ + "activates", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { \ + "expiration_time", \ + "expires", \ + KEYWORD_TYPE_INTEGER \ + }, \ + { NULL, NULL, KEYWORD_TYPE_UNKNOWN } \ + } + +/** + * @brief Count number of tls_certificates. + * + * @param[in] get GET params. + * + * @return Total number of tls_certificates in filtered set. + */ +int +tls_certificate_count (const get_data_t *get) +{ + static const char *extra_columns[] = TLS_CERTIFICATE_ITERATOR_FILTER_COLUMNS; + static column_t columns[] = TLS_CERTIFICATE_ITERATOR_COLUMNS; + static column_t trash_columns[] = TLS_CERTIFICATE_ITERATOR_TRASH_COLUMNS; + + return count ("tls_certificate", get, columns, trash_columns, extra_columns, + 0, 0, 0, TRUE); +} + +/** + * @brief Initialise a tls_certificate iterator. + * + * @param[in] iterator Iterator. + * @param[in] get GET data. + * + * @return 0 success, 1 failed to find tls_certificate, + * 2 failed to find filter, -1 error. + */ +int +init_tls_certificate_iterator (iterator_t *iterator, const get_data_t *get) +{ + static const char *filter_columns[] = TLS_CERTIFICATE_ITERATOR_FILTER_COLUMNS; + static column_t columns[] = TLS_CERTIFICATE_ITERATOR_COLUMNS; + static column_t trash_columns[] = TLS_CERTIFICATE_ITERATOR_TRASH_COLUMNS; + + return init_get_iterator (iterator, + "tls_certificate", + get, + columns, + trash_columns, + filter_columns, + 0, + NULL, + NULL, + TRUE); +} + +/** + * @brief Get a column value from a tls_certificate iterator. + * + * @param[in] iterator Iterator. + * + * @return Value of the column or NULL if iteration is complete. + */ +DEF_ACCESS (tls_certificate_iterator_certificate, GET_ITERATOR_COLUMN_COUNT); + +/** + * @brief Get a column value from a tls_certificate iterator. + * + * @param[in] iterator Iterator. + * + * @return Value of the column or NULL if iteration is complete. + */ +DEF_ACCESS (tls_certificate_iterator_subject_dn, + GET_ITERATOR_COLUMN_COUNT + 1); + +/** + * @brief Get a column value from a tls_certificate iterator. + * + * @param[in] iterator Iterator. + * + * @return Value of the column or NULL if iteration is complete. + */ +DEF_ACCESS (tls_certificate_iterator_issuer_dn, + GET_ITERATOR_COLUMN_COUNT + 2); + +/** + * @brief Get a column value from a tls_certificate iterator. + * + * @param[in] iterator Iterator. + * + * @return Value of the column or NULL if iteration is complete. + */ +int +tls_certificate_iterator_trust (iterator_t *iterator) +{ + if (iterator->done) + return 0; + + return iterator_int (iterator, GET_ITERATOR_COLUMN_COUNT + 3); +} + +/** + * @brief Get a column value from a tls_certificate iterator. + * + * @param[in] iterator Iterator. + * + * @return Value of the column or NULL if iteration is complete. + */ +DEF_ACCESS (tls_certificate_iterator_md5_fingerprint, + GET_ITERATOR_COLUMN_COUNT + 4); + +/** + * @brief Get a column value from a tls_certificate iterator. + * + * @param[in] iterator Iterator. + * + * @return Value of the column or NULL if iteration is complete. + */ +DEF_ACCESS (tls_certificate_iterator_activation_time, + GET_ITERATOR_COLUMN_COUNT + 5); + +/** + * @brief Get a column value from a tls_certificate iterator. + * + * @param[in] iterator Iterator. + * + * @return Value of the column or NULL if iteration is complete. + */ +DEF_ACCESS (tls_certificate_iterator_expiration_time, + GET_ITERATOR_COLUMN_COUNT + 6); + +/** + * @brief Get a column value from a tls_certificate iterator. + * + * @param[in] iterator Iterator. + * + * @return Value of the column or NULL if iteration is complete. + */ +int +tls_certificate_iterator_valid (iterator_t *iterator) +{ + if (iterator->done) + return 0; + + return iterator_int (iterator, GET_ITERATOR_COLUMN_COUNT + 7); +} + +/** + * @brief Get a column value from a tls_certificate iterator. + * + * @param[in] iterator Iterator. + * + * @return Value of the column or NULL if iteration is complete. + */ +DEF_ACCESS (tls_certificate_iterator_certificate_format, + GET_ITERATOR_COLUMN_COUNT + 8); + +/** + * @brief Return whether a tls_certificate is in use. + * + * @param[in] tls_certificate TLS Certificate. + * + * @return 1 if in use, else 0. + */ +int +tls_certificate_in_use (tls_certificate_t tls_certificate) +{ + return 0; +} + +/** + * @brief Return whether a trashcan tls_certificate is in use. + * + * @param[in] tls_certificate TLS Certificate. + * + * @return 1 if in use, else 0. + */ +int +trash_tls_certificate_in_use (tls_certificate_t tls_certificate) +{ + return 0; +} + +/** + * @brief Return whether a tls_certificate is writable. + * + * @param[in] tls_certificate TLS Certificate. + * + * @return 1 if writable, else 0. + */ +int +tls_certificate_writable (tls_certificate_t tls_certificate) +{ + return 1; +} + +/** + * @brief Return whether a trashcan tls_certificate is writable. + * + * @param[in] tls_certificate TLS Certificate. + * + * @return 1 if writable, else 0. + */ +int +trash_tls_certificate_writable (tls_certificate_t tls_certificate) +{ + return trash_tls_certificate_in_use (tls_certificate) == 0; +} + +/** + * @brief Get a string representation of a certificate format. + * + * @param[in] certificate_format The format as gnutls_x509_crt_fmt_t. + * + * @return A string representation of the format (e.g. "PEM" or "DER"). + */ +static const char* +tls_certificate_format_str (gnutls_x509_crt_fmt_t certificate_format) +{ + switch (certificate_format) + { + case GNUTLS_X509_FMT_DER: + return "DER"; + case GNUTLS_X509_FMT_PEM: + return "PEM"; + default: + return "unknown"; + } +} + +/** + * @brief Create a TLS certificate. + * + * @param[in] name Name of new TLS certificate. + * @param[in] comment Comment of TLS certificate. + * @param[in] certificate_b64 Base64 certificate file content. + * @param[in] trust Whether to trust the certificate. + * @param[out] tls_certificate Created TLS certificate. + * + * @return 0 success, 1 invalid certificate content, 2 certificate not Base64, + * 99 permission denied, -1 error. + */ +int +create_tls_certificate (const char *name, + const char *comment, + const char *certificate_b64, + int trust, + tls_certificate_t *tls_certificate) +{ + int ret; + gchar *certificate_decoded; + gsize certificate_len; + char *md5_fingerprint, *subject_dn, *issuer_dn; + time_t activation_time, expiration_time; + gnutls_x509_crt_fmt_t certificate_format; + + certificate_decoded + = (gchar*) g_base64_decode (certificate_b64, &certificate_len); + + if (certificate_decoded == NULL || certificate_len == 0) + return 2; + + ret = get_certificate_info (certificate_decoded, + certificate_len, + &activation_time, + &expiration_time, + &md5_fingerprint, + &subject_dn, + &issuer_dn, + &certificate_format); + + if (ret) + return 1; + + sql ("INSERT INTO tls_certificates" + " (uuid, owner, name, comment, creation_time, modification_time," + " certificate, subject_dn, issuer_dn, trust," + " activation_time, expiration_time, md5_fingerprint," + " certificate_format)" + " SELECT make_uuid(), (SELECT id FROM users WHERE users.uuid = '%s')," + " '%s', '%s', m_now(), m_now(), '%s', '%s', '%s', %d," + " %ld, %ld, '%s', '%s';", + current_credentials.uuid, + name ? name : md5_fingerprint, + comment ? comment : "", + certificate_b64 ? certificate_b64 : "", + subject_dn ? subject_dn : "", + issuer_dn ? issuer_dn : "", + trust, + activation_time, + expiration_time, + md5_fingerprint, + tls_certificate_format_str (certificate_format)); + + if (tls_certificate) + *tls_certificate = sql_last_insert_id (); + + return 0; +} + +/** + * @brief Create a TLS certificate from an existing TLS certificate. + * + * @param[in] name Name. NULL to copy from existing TLS certificate. + * @param[in] comment Comment. NULL to copy from existing TLS certificate. + * @param[in] tls_certificate_id UUID of existing TLS certificate. + * @param[out] new_tls_certificate New TLS certificate. + * + * @return 0 success, + * 1 TLS certificate exists already, + * 2 failed to find existing TLS certificate, + * 99 permission denied, + * -1 error. + */ +int +copy_tls_certificate (const char *name, + const char *comment, + const char *tls_certificate_id, + tls_certificate_t *new_tls_certificate) +{ + int ret; + tls_certificate_t old_tls_certificate; + + assert (new_tls_certificate); + + ret = copy_resource ("tls_certificate", name, comment, tls_certificate_id, + "certificate, subject_dn, issuer_dn, trust," + "activation_time, expiration_time, md5_fingerprint," + "certificate_format", + 0, new_tls_certificate, &old_tls_certificate); + if (ret) + return ret; + + return 0; +} + +/** + * @brief Delete a tls_certificate. + * + * @param[in] tls_certificate_id UUID of tls_certificate. + * @param[in] ultimate Whether to remove entirely, or to trashcan. + * + * @return 0 success, 1 fail because tls_certificate is in use, + * 2 failed to find tls_certificate, + * 3 predefined tls_certificate, 99 permission denied, -1 error. + */ +int +delete_tls_certificate (const char *tls_certificate_id, int ultimate) +{ + tls_certificate_t tls_certificate = 0; + + sql_begin_immediate (); + + if (acl_user_may ("delete_tls_certificate") == 0) + { + sql_rollback (); + return 99; + } + + /* Search in the regular table. */ + + if (find_resource_with_permission ("tls_certificate", + tls_certificate_id, + &tls_certificate, + "delete_tls_certificate", + 0)) + { + sql_rollback (); + return -1; + } + + if (tls_certificate == 0) + { + /* No such tls_certificate, check the trashcan. */ + + if (find_trash ("tls_certificate", + tls_certificate_id, + &tls_certificate)) + { + sql_rollback (); + return -1; + } + if (tls_certificate == 0) + { + sql_rollback (); + return 2; + } + if (ultimate == 0) + { + /* It's already in the trashcan. */ + sql_commit (); + return 0; + } + + sql ("DELETE FROM permissions" + " WHERE resource_type = 'tls_certificate'" + " AND resource_location = %i" + " AND resource = %llu;", + LOCATION_TRASH, + tls_certificate); + + tags_remove_resource ("tls_certificate", + tls_certificate, + LOCATION_TRASH); + + sql ("DELETE FROM tls_certificates_trash WHERE id = %llu;", + tls_certificate); + + sql_commit (); + return 0; + } + + /* TLS certificate was found in regular table. */ + + if (ultimate == 0) + { + tls_certificate_t trash_tls_certificate; + + /* Move to trash. */ + + sql ("INSERT INTO tls_certificates_trash" + " (uuid, owner, name, comment, creation_time, modification_time," + " certificate, subject_dn, issuer_dn, trust," + " activation_time, expiration_time, md5_fingerprint," + " certificate_format)" + " SELECT" + " uuid, owner, name, comment, creation_time, modification_time," + " certificate, subject_dn, issuer_dn, trust," + " activation_time, expiration_time, md5_fingerprint," + " certificate_format" + " FROM tls_certificates WHERE id = %llu;", + tls_certificate); + + trash_tls_certificate = sql_last_insert_id (); + + permissions_set_locations ("tls_certificate", + tls_certificate, + trash_tls_certificate, + LOCATION_TRASH); + tags_set_locations ("tls_certificate", + tls_certificate, + trash_tls_certificate, + LOCATION_TRASH); + } + else + { + /* Delete entirely. */ + + sql ("DELETE FROM permissions" + " WHERE resource_type = 'tls_certificate'" + " AND resource_location = %i" + " AND resource = %llu;", + LOCATION_TABLE, + tls_certificate); + + tags_remove_resource ("tls_certificate", + tls_certificate, + LOCATION_TABLE); + } + + sql ("DELETE FROM tls_certificates WHERE id = %llu;", + tls_certificate); + + sql_commit (); + return 0; +} + +/** + * @brief Try restore a tls_certificate. + * + * If success, ends transaction for caller before exiting. + * + * @param[in] tls_certificate_id UUID of resource. + * + * @return 0 success, 1 fail because tls_certificate is in use, + * 2 failed to find tls_certificate, -1 error. + */ +int +restore_tls_certificate (const char *tls_certificate_id) +{ + tls_certificate_t trash_tls_certificate, tls_certificate; + + if (find_trash ("tls_certificate", + tls_certificate_id, + &trash_tls_certificate)) + { + sql_rollback (); + return -1; + } + + if (trash_tls_certificate == 0) + return 2; + + /* Move the tls_certificate back to the regular table. */ + + sql ("INSERT INTO tls_certificates" + " (uuid, owner, name, comment, creation_time, modification_time," + " certificate, subject_dn, issuer_dn, trust," + " activation_time, expiration_time, md5_fingerprint," + " certificate_format)" + " SELECT" + " uuid, owner, name, comment, creation_time, modification_time," + " certificate, subject_dn, issuer_dn, trust," + " activation_time, expiration_time, md5_fingerprint," + " certificate_format" + " FROM tls_certificates_trash WHERE id = %llu;", + trash_tls_certificate); + + tls_certificate = sql_last_insert_id (); + + /* Adjust references to the tls_certificate. */ + + permissions_set_locations ("tls_certificate", + trash_tls_certificate, + tls_certificate, + LOCATION_TABLE); + tags_set_locations ("tls_certificate", + trash_tls_certificate, + tls_certificate, + LOCATION_TABLE); + + /* Clear out the trashcan tls_certificate. */ + + sql ("DELETE FROM tls_certificates_trash WHERE id = %llu;", + trash_tls_certificate); + + sql_commit (); + return 0; +} + +/** + * @brief Empty TLS certificate trashcans. + */ +void +empty_trashcan_tls_certificates () +{ + sql ("DELETE FROM permissions" + " WHERE resource_type = 'tls_certificate'" + " AND resource_location = %i" + " AND resource IN (SELECT id FROM tls_certificates_trash" + " WHERE owner = (SELECT id FROM users" + " WHERE uuid = '%s'));", + LOCATION_TRASH, + current_credentials.uuid); + + sql ("DELETE FROM tls_certifcates_trash" + " WHERE owner = (SELECT id FROM users WHERE uuid = '%s');", + current_credentials.uuid); +} + +/** + * @brief Delete all TLS certificate owned by a user. + * + * Also delete trash TLS certificates. + * + * @param[in] user The user. + */ +void +delete_tls_certificates_user (user_t user) +{ + /* Regular tls_certificate. */ + + sql ("DELETE FROM tls_certificate WHERE owner = %llu;", user); + + /* Trash tls_certificate. */ + + sql ("DELETE FROM tls_certificate_trash WHERE owner = %llu;", user); +} + +/** + * @brief Change ownership of tls_certificate, for user deletion. + * + * Also assign tls_certificate that are assigned to the user to the inheritor. + * + * @param[in] user Current owner. + * @param[in] inheritor New owner. + */ +void +inherit_tls_certificates (user_t user, user_t inheritor) +{ + /* Regular tls_certificate. */ + + sql ("UPDATE tls_certificate SET owner = %llu WHERE owner = %llu;", + inheritor, user); + + /* Trash TLS certificates. */ + + sql ("UPDATE tls_certificate_trash SET owner = %llu WHERE owner = %llu;", + inheritor, user); +} + +/** + * @brief Modify a TLS certificate. + * + * @param[in] tls_certificate_id UUID of TLS certificate. + * @param[in] comment New comment on TLS certificate. + * @param[in] name New name of TLS certificate. + * @param[in] certificate_b64 New Base64 certificate file content. + * @param[in] trust New trust value or -1 to keep old value. + * + * @return 0 success, 1 TLS certificate exists already, + * 2 failed to find TLS certificate, + * 3 invalid certificate content, 4 certificate is not valid Base64, + * 99 permission denied, -1 error. + */ +int +modify_tls_certificate (const gchar *tls_certificate_id, + const gchar *comment, + const gchar *name, + const gchar *certificate_b64, + int trust) +{ + tls_certificate_t tls_certificate; + + assert (tls_certificate_id); + assert (current_credentials.uuid); + + sql_begin_immediate (); + + /* Check permissions and get a handle on the TLS certificate. */ + + if (acl_user_may ("modify_tls_certificate") == 0) + { + sql_rollback (); + return 99; + } + + tls_certificate = 0; + if (find_resource_with_permission ("tls_certificate", + tls_certificate_id, + &tls_certificate, + "modify_tls_certificate", + 0)) + { + sql_rollback (); + return -1; + } + + if (tls_certificate == 0) + { + sql_rollback (); + return 2; + } + + /* Update certificate if requested. */ + + if (certificate_b64) + { + gchar *quoted_certificate; + int ret; + char *md5_fingerprint, *subject_dn, *issuer_dn; + time_t activation_time, expiration_time; + gnutls_x509_crt_fmt_t certificate_format; + + gchar *certificate_decoded; + gsize certificate_len; + + certificate_decoded + = (gchar*) g_base64_decode (certificate_b64, &certificate_len); + + if (certificate_decoded == NULL || certificate_len == 0) + { + sql_rollback (); + return 4; + } + + ret = get_certificate_info (certificate_decoded, + certificate_len, + &activation_time, + &expiration_time, + &md5_fingerprint, + &subject_dn, + &issuer_dn, + &certificate_format); + + if (ret) + return 3; + + quoted_certificate = sql_quote (certificate_b64); + sql ("UPDATE tls_certificates SET" + " certificate = '%s'," + " activation_time = %llu," + " expiration_time = %llu," + " md5_fingerprint = '%s'," + " subject_dn = '%s'," + " issuer_dn = '%s'," + " modification_time = m_now ()," + " certificate_format = '%s'" + " WHERE id = %llu;", + quoted_certificate, + activation_time, + expiration_time, + md5_fingerprint, + subject_dn, + issuer_dn, + tls_certificate_format_str (certificate_format), + tls_certificate); + g_free (quoted_certificate); + } + + /* Update comment if requested. */ + + if (comment) + { + gchar *quoted_comment; + + quoted_comment = sql_quote (comment); + sql ("UPDATE tls_certificates SET" + " comment = '%s'," + " modification_time = m_now ()" + " WHERE id = %llu;", + quoted_comment, + tls_certificate); + g_free (quoted_comment); + } + + /* Update name if requested. */ + + if (name) + { + gchar *quoted_name; + + quoted_name = sql_quote (name); + sql ("UPDATE tls_certificates SET" + " name = '%s'," + " modification_time = m_now ()" + " WHERE id = %llu;", + quoted_name, + tls_certificate); + g_free (quoted_name); + } + + /* Update trust if requested */ + + if (trust != -1) + { + sql ("UPDATE tls_certificates SET" + " trust = %d," + " modification_time = m_now ()" + " WHERE id = %llu;", + trust, + tls_certificate); + } + + sql_commit (); + + return 0; +} + +/** + * @brief Return the UUID of a TLS certificate. + * + * @param[in] tls_certificate TLS certificate. + * + * @return Newly allocated UUID if available, else NULL. + */ +char* +tls_certificate_uuid (tls_certificate_t tls_certificate) +{ + return sql_string ("SELECT uuid FROM tls_certificates WHERE id = %llu;", + tls_certificate); +} diff --git a/src/manage_sql_tls_certificates.h b/src/manage_sql_tls_certificates.h new file mode 100644 index 000000000..b51be75ed --- /dev/null +++ b/src/manage_sql_tls_certificates.h @@ -0,0 +1,45 @@ +/* Copyright (C) 2019 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 manage_sql_tls_certificates.h + * @brief GVM management layer: TLS Certificates SQL headers + * + * Headers for TLS Certificates SQL for the GVM management layer. + */ + +#ifndef _GVMD_MANAGE_SQL_TLS_CERTIFICATES_H +#define _GVMD_MANAGE_SQL_TLS_CERTIFICATES_H + +int +delete_tls_certificate (const char *, int); + +int +restore_tls_certificate (const char *); + +void +empty_trashcan_tls_certificates (); + +void +delete_tls_certificates_user (user_t); + +void +inherit_tls_certificates (user_t, user_t); + +#endif /* not _GVMD_MANAGE_SQL_TLS_CERTIFICATES_H */ diff --git a/src/manage_sqlite3.c b/src/manage_sqlite3.c index 849914572..07965b225 100644 --- a/src/manage_sqlite3.c +++ b/src/manage_sqlite3.c @@ -1205,6 +1205,34 @@ sql_iso_time (sqlite3_context *context, int argc, sqlite3_value** argv) } } +/** + * @brief Convert an epoch time like iso_time with certificate special cases. + * + * This is a callback for a scalar SQL function of one argument. + * + * @param[in] context SQL context. + * @param[in] argc Number of arguments. + * @param[in] argv Argument array. + */ +void +sql_certificate_iso_time (sqlite3_context *context, int argc, + sqlite3_value** argv) +{ + time_t epoch_time; + gchar *iso; + + assert (argc == 1); + + epoch_time = sqlite3_value_int64 (argv[0]); + + iso = certificate_iso_time (epoch_time); + if (iso) + sqlite3_result_text (context, iso, -1, SQLITE_TRANSIENT); + else + sqlite3_result_error (context, "Failed to format time", -1); + g_free (iso); +} + /** * @brief Calculate difference between now and epoch time in days * @@ -2929,6 +2957,20 @@ manage_create_sql_functions () return -1; } + if (sqlite3_create_function (gvmd_db, + "certificate_iso_time", + 1, /* Number of args. */ + SQLITE_UTF8, + NULL, /* Callback data. */ + sql_certificate_iso_time, + NULL, /* xStep. */ + NULL) /* xFinal. */ + != SQLITE_OK) + { + g_warning ("%s: failed to create certificate_iso_time", __FUNCTION__); + return -1; + } + if (sqlite3_create_function (gvmd_db, "days_from_now", 1, /* Number of args. */ @@ -3813,6 +3855,18 @@ create_tables () sql ("CREATE TABLE IF NOT EXISTS ticket_results_trash" " (id INTEGER PRIMARY KEY, ticket, result, result_location," " result_uuid, report);"); + sql ("CREATE TABLE IF NOT EXISTS tls_certificates" + " (id INTEGER PRIMARY KEY, uuid text UNIQUE, owner integer," + " name text, comment text, creation_time integer," + " modification_time integer, certificate text, subject_dn text," + " issuer_dn text, activation_time integer, expiration_time integer," + " md5_fingerprint text, trust integer, certificate_format text);"); + sql ("CREATE TABLE IF NOT EXISTS tls_certificates_trash" + " (id INTEGER PRIMARY KEY, uuid text UNIQUE, owner integer," + " name text, comment text, creation_time integer," + " modification_time integer, certificate text, subject_dn text," + " issuer_dn text, activation_time integer, expiration_time integer," + " md5_fingerprint text, trust integer, certificate_format text);"); sql ("CREATE TABLE IF NOT EXISTS scanners" " (id INTEGER PRIMARY KEY, uuid, owner INTEGER, name, comment," " host, port, type, ca_pub, credential INTEGER," diff --git a/src/manage_tls_certificates.h b/src/manage_tls_certificates.h new file mode 100644 index 000000000..5272431f5 --- /dev/null +++ b/src/manage_tls_certificates.h @@ -0,0 +1,93 @@ +/* Copyright (C) 2019 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 manage_sql_tls_certificates.h + * @brief GVM management layer: TLS Certificates SQL headers + * + * Headers for TLS Certificates SQL for the GVM management layer. + */ + +#ifndef _GVMD_MANAGE_TLS_CERTIFICATES_H +#define _GVMD_MANAGE_TLS_CERTIFICATES_H + +#include "manage.h" +#include "iterator.h" + +int +tls_certificate_count (const get_data_t *); + +int +init_tls_certificate_iterator (iterator_t *, const get_data_t *); + +const char* +tls_certificate_iterator_certificate (iterator_t*); + +const char* +tls_certificate_iterator_subject_dn (iterator_t*); + +const char* +tls_certificate_iterator_issuer_dn (iterator_t*); + +int +tls_certificate_iterator_trust (iterator_t *); + +const char* +tls_certificate_iterator_md5_fingerprint (iterator_t*); + +const char* +tls_certificate_iterator_activation_time (iterator_t*); + +const char* +tls_certificate_iterator_expiration_time (iterator_t*); + +int +tls_certificate_iterator_valid (iterator_t *); + +const char* +tls_certificate_iterator_certificate_format (iterator_t*); + +int +tls_certificate_in_use (tls_certificate_t); + +int +trash_tls_certificate_in_use (tls_certificate_t); + +int +tls_certificate_writable (tls_certificate_t); + +int +trash_tls_certificate_writable (tls_certificate_t); + +int +create_tls_certificate (const char *, const char *, const char *, int, + tls_certificate_t *); + +int +copy_tls_certificate (const char*, const char*, const char*, + tls_certificate_t*); + +int +modify_tls_certificate (const gchar *, const gchar *, const gchar *, + const gchar *, int); + +char* +tls_certificate_uuid (tls_certificate_t); + +#endif /* not _GVMD_MANAGE_TLS_CERTIFICATES_H */ diff --git a/src/manage_utils.c b/src/manage_utils.c index 374488e0c..7d8b61559 100644 --- a/src/manage_utils.c +++ b/src/manage_utils.c @@ -790,6 +790,7 @@ valid_db_resource_type (const char* type) || (strcasecmp (type, "target") == 0) || (strcasecmp (type, "task") == 0) || (strcasecmp (type, "ticket") == 0) + || (strcasecmp (type, "tls_certificate") == 0) || (strcasecmp (type, "user") == 0); } diff --git a/src/schema_formats/XML/GMP.xml.in b/src/schema_formats/XML/GMP.xml.in index f4e06eb89..5fc400ca4 100644 --- a/src/schema_formats/XML/GMP.xml.in +++ b/src/schema_formats/XML/GMP.xml.in @@ -3111,6 +3111,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. create_target create_task create_ticket + create_tls_certificate create_user delete_agent delete_alert @@ -3164,6 +3165,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. get_targets get_tasks get_tickets + get_tls_certificates get_users get_version get_vulns @@ -3190,6 +3192,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. modify_target modify_task modify_ticket + modify_tls_certificate modify_user restore resume_task @@ -3239,6 +3242,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. create_target create_task create_ticket + create_tls_certificate create_user delete_agent delete_alert @@ -3292,6 +3296,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. get_targets get_tasks get_tickets + get_tls_certificates get_users get_version get_vulns @@ -3317,6 +3322,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. modify_tag modify_target modify_ticket + modify_tls_certificate modify_task modify_user restore @@ -6082,6 +6088,94 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + + create_tls_certificate + Create a TLS certificate + +

+ The client uses the create_tls_certificate command to create a new + TLS certificate. +

+
+ + comment + copy + name + trust + certificate + + + comment + A comment on the TLS certificate + + text + + + + copy + The UUID of an existing TLS certificate + + uuid + + + + name + + The name of the certificate, defaulting to the MD5 fingerprint + + + text + + + + trust + Whether the certificate is trusted + + boolean + + + + certificate + The Base64 encoded certificate data (x.509 DER or PEM) + + text + + + + + + status + status + 1 + + + status_text + text + 1 + + + id + uuid + 1 + + + + + Create a TLS certificate + + + Example Certificate + MIIDNjCCAp+gAwIBAgIBATANBgkqhkiG9w0BAQQFADCBqTELM[...] + + + + + + + +
create_user Create a user @@ -22581,6 +22675,441 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + + get_tls_certificates + Get one or many TLS certificates + +

+ The client uses the "get_tls_certificates" command to retrieve one + or more TLS certificates. +

+
+ + + tls_certificate_id + ID of single TLS certificate to get + uuid + + + filter + Filter term to use to filter query + text + + + uuid + uuid + Unique ID + + + name + name + Name + + + comment + text + Comment text + + + created + iso_time + Creation time + + + modified + iso_time + Modification time + + + owner + name + Name of the owner + + + subject_dn + text + + Distinguished name (DN) of the certificate subject + + + + issuer_dn + text + + Distinguished name (DN) of the certificate issuer + + + + md5_fingerprint + text + + MD5 fingerprint of the certificate + + + + activates + iso_time + Time before which the certificate is not valid + + + expires + iso_time + Time after which the certificate is not valid + + + valid + boolean + Whether the certificate is currently valid + + + + + filt_id + ID of filter to use to filter query + uuid + + + + + + status + status + 1 + + + status_text + text + 1 + + tls_certificate + filters + sort + tls_certificates + tls_certificate_count + + + tls_certificate + + + id + ID of TLS certificate + uuid + 1 + + owner + name + comment + creation_time + modification_time + writable + in_use + permissions + certificate + md5_fingerprint + trust + activation_time + expiration_time + subject_dn + issuer_dn + + + owner + Owner of the TLS certificate + + name + + + name + The name of the owner + name + + + + name + The name of the TLS certificate + text + + + comment + The comment on the TLS certificate + text + + + creation_time + Creation time of the TLS certificate + iso_time + + + modification_time + Last time the TLS certificate was modified + iso_time + + + writable + Whether the TLS certificate is writable + boolean + + + in_use + Whether this TLS certificate is currently in use + boolean + + + permissions + + Permissions that the current user has on the TLS certificate + + + permission + + + permission + + name + + + name + The name of the permission + name + + + + + certificate + The Base64 encoded certificate data if details are requested, empty otherwise + + + format + The format of the certificate + + + DER + PEM + unknown + + + 1 + + + + + md5_fingerprint + The MD5 fingerprint of the certificate + text + + + trust + Whether the certificate is trusted + boolean + + + valid + Whether the certificate is currently valid + boolean + + + activation_time + Time before which the certificate is not valid + iso_time + + + expiration_time + Time after which the certificate is not valid + iso_time + + + subject_dn + Distinguished name (DN) of the certificate subject + text + + + issuer_dn + Distinguished name (DN) of the certificate issuer + text + + + + 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 + + + + + + + + tls_certificates + + + start + First TLS certificate + integer + 1 + + + max + Maximum number of TLS certificates + integer + 1 + + + + + tls_certificate_count + + filtered + page + + + filtered + Number of TLS certificate after filtering + integer + + + page + Number of TLS certificate on current page + integer + + + + + Get the TLS certificates + + + + + + + + admin + + Example Certificate + + 2019-06-12T14:36:53Z + 2019-06-13T08:56:36Z + 1 + 0 + + + Everything + + + MIIDNjCCAp+gAwIBAgIBATANBgkqhkiG9w0BAQQFADCBqTELM[...] + ba:ec:16:30:27:ca:99:17:ff:df:a4:4c:bc:bf:1b:98 + 1 + 1 + 2019-02-26T14:24:15Z + 2021-02-25T14:24:15Z + CN=localhost,O=GVM Users,L=Osnabrueck,C=DE + OU=Certificate Authority for localhost,O=GVM Users,L=Osnabrueck,C=DE + + + first=1 rows=10 sort=name + + + first + = + 1 + + + rows + = + 1000 + + + sort + = + name + + + + + nameascending + + + 1 + 1 + 1 + + + + +
get_version Get the Greenbone Management Protocol version @@ -25562,6 +26091,96 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + + modify_tls_certificate + Create a TLS certificate + +

+ The client uses the modify_tls_certificate command to modify an + existing TLS certificate. +

+
+ + + tls_certificate_id + uuid + 1 + + comment + copy + name + trust + certificate + + + comment + A comment on the TLS certificate + + text + + + + copy + The UUID of an existing TLS certificate + + uuid + + + + name + + The name of the certificate, defaulting to the MD5 fingerprint + + + text + + + + trust + Whether the certificate is trusted + + boolean + + + + certificate + The Base64 encoded certificate data (x.509 DER or PEM) + + text + + + + + + status + status + 1 + + + status_text + text + 1 + + + + + + Modify the name and certificate content of a TLS certificate + + + + Updated Example Certificate + LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVrVENDQ[...] + + + + + + + + +
modify_user Modify an existing user