diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c1a86b2249..a9af94c954 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -83,6 +83,16 @@ else (NOT GPGME) OUTPUT_STRIP_TRAILING_WHITESPACE) endif (NOT GPGME) +find_package(Theia 1.0.0 QUIET) +if (Theia_DIR) + message (STATUS "Found libtheia ${Theia_VERSION} in ${Theia_DIR}") + add_definitions (-DHAS_LIBTHEIA="1") + set (OPT_THEIA_TGT Theia::Theia) +else (Theia_DIR) + message (STATUS "No compatible libtheia version found") + set (OPT_THEIA_TGT "") +endif (Theia_DIR) + include_directories (${LIBGVM_GMP_INCLUDE_DIRS} ${LIBGVM_BASE_INCLUDE_DIRS} ${LIBGVM_UTIL_INCLUDE_DIRS} ${LIBGVM_OSP_INCLUDE_DIRS} ${GLIB_INCLUDE_DIRS}) @@ -260,32 +270,32 @@ target_link_libraries (gvmd m ${GNUTLS_LDFLAGS} ${GPGME_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT} ${LINKER_HARDENING_FLAGS} ${LINKER_DEBUG_FLAGS} ${PostgreSQL_LIBRARIES} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} ${LIBGVM_GMP_LDFLAGS} - ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS}) + ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) target_link_libraries (manage-test cgreen m ${GNUTLS_LDFLAGS} ${GPGME_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT} ${LINKER_HARDENING_FLAGS} ${LINKER_DEBUG_FLAGS} ${PostgreSQL_LIBRARIES} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} ${LIBGVM_GMP_LDFLAGS} - ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS}) + ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) target_link_libraries (manage-sql-test cgreen m ${GNUTLS_LDFLAGS} ${GPGME_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT} ${LINKER_HARDENING_FLAGS} ${LINKER_DEBUG_FLAGS} ${PostgreSQL_LIBRARIES} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} ${LIBGVM_GMP_LDFLAGS} - ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS}) + ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) target_link_libraries (manage-utils-test cgreen m ${GNUTLS_LDFLAGS} ${GPGME_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT} ${LINKER_HARDENING_FLAGS} ${LINKER_DEBUG_FLAGS} ${PostgreSQL_LIBRARIES} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} ${LIBGVM_GMP_LDFLAGS} - ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS}) + ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) target_link_libraries (gmp-tickets-test cgreen m ${GNUTLS_LDFLAGS} ${GPGME_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT} ${LINKER_HARDENING_FLAGS} ${LINKER_DEBUG_FLAGS} ${PostgreSQL_LIBRARIES} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} ${LIBGVM_GMP_LDFLAGS} - ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS}) + ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) target_link_libraries (utils-test cgreen m ${GNUTLS_LDFLAGS} ${GPGME_LDFLAGS} ${CMAKE_THREAD_LIBS_INIT} ${LINKER_HARDENING_FLAGS} ${LINKER_DEBUG_FLAGS} ${PostgreSQL_LIBRARIES} ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBGVM_OSP_LDFLAGS} ${LIBGVM_GMP_LDFLAGS} - ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS}) + ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS} ${OPT_THEIA_TGT}) target_link_libraries (gvm-pg-server ${GLIB_LDFLAGS} ${GTHREAD_LDFLAGS} ${LIBGVM_BASE_LDFLAGS} ${LIBGVM_UTIL_LDFLAGS} ${LIBICAL_LDFLAGS} ${LINKER_HARDENING_FLAGS}) set_target_properties (gvmd PROPERTIES LINKER_LANGUAGE C) diff --git a/src/gmp_license.c b/src/gmp_license.c index 14c8fc1991..0c7cd180b6 100644 --- a/src/gmp_license.c +++ b/src/gmp_license.c @@ -102,47 +102,6 @@ get_license_element_start (gmp_parser_t *gmp_parser, attribute_names, attribute_values); } -/** - * @brief Writes XML for a license access key to a GString buffer. - * - * This is meant to be used to traverse a GTree with g_tree_foreach. - * - * @param[in] key The key from the tree, i.e. the access key name. - * @param[in] value The value from the tree, i.e. the key content. - * @param[in] buffer The GString to buffer the XML element. - * - * @return Always FALSE to continue traversing the GTree. - */ -static gboolean -buffer_license_key_xml (gchar *key, gchar *value, GString *buffer) -{ - xml_string_append (buffer, - "%s", - key, value); - return FALSE; -} - -/** - * @brief Writes XML for a license signature info item to a GString buffer. - * - * This is meant to be used to traverse a GTree with g_tree_foreach. - * - * @param[in] key The key from the tree, i.e. the info item name. - * @param[in] value The value from the tree, i.e. the info item content. - * @param[in] buffer The GString to buffer the XML element. - * - * @return Always FALSE to continue traversing the GTree. - */ -static gboolean -buffer_license_signature_xml (gchar *key, gchar *value, GString *buffer) -{ - xml_string_append (buffer, - "%s", - key, value); - return FALSE; -} - - /** * @brief Writes license data to a GString as XML * @@ -150,8 +109,15 @@ buffer_license_signature_xml (gchar *key, gchar *value, GString *buffer) * @param[in] license_data The license data struct to get the data from. */ static void -buffer_license_content_xml (GString *response, license_data_t *license_data) +buffer_license_content_xml (GString *response, theia_license_t *license_data) { +#ifdef HAS_LIBTHEIA + if (license_data == NULL) + { + xml_string_append (response, ""); + return; + } + xml_string_append (response, "" "" @@ -183,26 +149,22 @@ buffer_license_content_xml (GString *response, license_data_t *license_data) "%s" "%d" "" - "", + "" + "%s" + "" + "" + "%s" + "" + "", license_data->appliance->model, license_data->appliance->model_type, - license_data->appliance->sensor); - - g_tree_foreach (license_data->keys, - (GTraverseFunc) buffer_license_key_xml, - response); - - xml_string_append (response, - "" - ""); - - g_tree_foreach (license_data->signatures, - (GTraverseFunc) buffer_license_signature_xml, - response); + license_data->appliance->sensor, + license_data->keys->feed, + license_data->signatures->license); - xml_string_append (response, - "" - ""); +#else // HAS_LIBTHEIA + xml_string_append (response, ""); +#endif // HAS_LIBTHEIA } @@ -219,7 +181,7 @@ get_license_run (gmp_parser_t *gmp_parser, int ret; gchar *license_status; - license_data_t *license_data; + theia_license_t *license_data; license_status = NULL; license_data = NULL; @@ -262,6 +224,18 @@ get_license_run (gmp_parser_t *gmp_parser, " status_text=\"Licensing service unavailable.\"/>", STATUS_SERVICE_DOWN); break; + case 2: + SENDF_TO_CLIENT_OR_FAIL + ("", + STATUS_SERVICE_DOWN); + break; + case 3: + SENDF_TO_CLIENT_OR_FAIL + ("", + STATUS_SERVICE_DOWN); + break; case 99: SEND_TO_CLIENT_OR_FAIL (XML_ERROR_ACCESS ("get_license")); break; @@ -271,7 +245,10 @@ get_license_run (gmp_parser_t *gmp_parser, } g_free (license_status); - license_data_free (license_data); + +#ifdef HAS_LIBTHEIA + theia_license_free (license_data); +#endif get_license_reset (); } diff --git a/src/manage_license.c b/src/manage_license.c index d45fa8d8bd..14d4a52c2d 100644 --- a/src/manage_license.c +++ b/src/manage_license.c @@ -27,107 +27,11 @@ #include "manage_license.h" #include "utils.h" -/* Data types */ - -/** - * @brief Allocates a new license metadata struct - * - * @return Newly allocated license metadata. Free with license_meta_free. - */ -license_meta_t * -license_meta_new () -{ - return g_malloc0 (sizeof (license_meta_t)); -} - -/** - * @brief Frees a license metadata struct and its fields. - * - * @param[in] data The data struct to free. - */ -void -license_meta_free (license_meta_t *data) -{ - if (data == NULL) - return; - - free (data->id); - free (data->version); - free (data->title); - free (data->type); - free (data->customer_name); - - g_free (data); -} - -/** - * @brief Allocates a new license appliance data struct - * - * @return Newly allocated license appliance data. Free with license_meta_free. - */ -license_appliance_t * -license_appliance_new () -{ - return g_malloc0 (sizeof (license_appliance_t)); -} - -/** - * @brief Frees a license appliance data struct and its fields. - * - * @param[in] data The data struct to free. - */ -void -license_appliance_free (license_appliance_t *data) -{ - if (data == NULL) - return; - - free (data->model); - free (data->model_type); - - g_free (data); -} - -/** - * @brief Allocates a new license data struct - * - * @return Newly allocated license data. Free with license_meta_free. - */ -license_data_t * -license_data_new () -{ - license_data_t *data = g_malloc0 (sizeof (license_data_t)); - - data->meta = license_meta_new (); - data->appliance = license_appliance_new (); - - data->keys = g_tree_new_full ((GCompareDataFunc) g_ascii_strcasecmp, - NULL, g_free, g_free); - - data->signatures = g_tree_new_full ((GCompareDataFunc) g_ascii_strcasecmp, - NULL, g_free, g_free); - - return data; -} - +#undef G_LOG_DOMAIN /** - * @brief Frees a license data struct and its fields. - * - * @param[in] data The data struct to free. + * @brief GLib log domain. */ -void -license_data_free (license_data_t *data) -{ - if (data == NULL) - return; - - license_meta_free (data->meta); - license_appliance_free (data->appliance); - g_tree_destroy (data->keys); - g_tree_destroy (data->signatures); - - g_free (data); -} +#define G_LOG_DOMAIN "md manage" /* Actions */ @@ -156,46 +60,115 @@ manage_update_license_file (const char *new_license) * @param[out] status The validation status (e.g. "valid", "expired"). * @param[out] license_data The content of the license organized in a struct. * - * @return 0 success, 1 service unavailable, 99 permission denied. + * @return 0 success, 1 service unavailable, 2 error sending command, + * 3 error receiving response, 99 permission denied, -1 internal error. */ int manage_get_license (gchar **status, - license_data_t **license_data) + theia_license_t **license_data) { + if (status) + *status = NULL; + if (license_data) + *license_data = NULL; + if (! acl_user_may ("get_license")) return 99; +#ifdef HAS_LIBTHEIA + int ret; + char *broker_address; + theia_client_t *client; + theia_get_license_cmd_t *get_license_cmd; + theia_got_license_info_t *got_license_info; + + // TODO: Replace with command line option + broker_address = g_strdup ("localhost:9138"); + if (broker_address == NULL) + return 1; + + client = theia_client_new_mqtt (&client); + if (client == NULL) + { + g_warning ("%s: Failed to create MQTT client", __func__); + return -1; + } + + ret = theia_client_connect (client, broker_address); + if (ret) + { + g_warning ("%s: Failed to connect to MQTT broker (%s)", + __func__, broker_address); + return 1; + } + else + g_debug ("%s: Connected to %s\n", __func__, broker_address); + + ret = theia_new_get_license_cmd (&get_license_cmd); + if (ret) + { + g_warning ("%s: Error preparing get.license command", __func__); + theia_client_disconnect (client); + free (client); + return -1; + } + + ret = theia_client_send_cmd (client, THEIA_LICENSE_CMD_TOPIC, + (theia_cmd_t *) get_license_cmd); + if (ret) + { + fprintf (stderr, "Error publishing get.license message."); + theia_client_disconnect (client); + theia_get_license_cmd_free (get_license_cmd); + free (client); + return 2; + } + else + g_debug ("%s: Sent get.license command" + " (message_id: %s, group_id: %s)\n", + __func__, + get_license_cmd->message->id, + get_license_cmd->message->group_id); + + + ret = theia_client_get_info_response (client, THEIA_LICENSE_INFO_TOPIC, + "got.license", + get_license_cmd->message->group_id, + (theia_info_t **) &got_license_info); + if (ret) + { + g_debug ("%s: Failed to get got.license response", __func__); + theia_client_disconnect (client); + theia_get_license_cmd_free (get_license_cmd); + free (client); + return 3; + } + else + g_debug ("%s: Received got.license response", __func__); + + theia_client_disconnect (client); + if (status) - *status = g_strdup ("active"); + { + *status = got_license_info->status; + got_license_info->status = NULL; + } if (license_data) { - *license_data = license_data_new (); - license_meta_t *license_meta = (*license_data)->meta; - license_appliance_t *license_appliance = (*license_data)->appliance; - - // TODO : replace dummy data with data from license service - license_meta->id = g_strdup ("4711"); - license_meta->version = g_strdup_printf("1.0.0"); - license_meta->title = g_strdup ("Test License"); - license_meta->type = g_strdup ("trial"); - license_meta->customer_name = g_strdup ("Jane Doe"); - license_meta->created = time (NULL) - 3600; - license_meta->begins = time (NULL); - license_meta->expires = time (NULL) + 3600 * 24 * 8; - - license_appliance->model = g_strdup ("trial"); - license_appliance->model_type = g_strdup ("virtual"); - license_appliance->sensor = FALSE; - - g_tree_replace ((*license_data)->keys, - g_strdup ("feed"), - g_strdup ("*base64 GSF key*")); - - g_tree_replace ((*license_data)->signatures, - g_strdup ("license"), - g_strdup ("*base64 signature*")); + *license_data = got_license_info->license; + got_license_info->license = NULL; } + theia_got_license_info_free (got_license_info); + +#else // HAS_LIBTHEIA + if (status) + *status = NULL; + if (license_data) + *license_data = NULL; + return 1; +#endif // HAS_LIBTHEIA + return 0; } diff --git a/src/manage_license.h b/src/manage_license.h index ad3a0c9e76..72c22db449 100644 --- a/src/manage_license.h +++ b/src/manage_license.h @@ -25,59 +25,11 @@ #include -/* Data types */ - -/** - * @brief Defines the metadata of a license - */ -typedef struct { - char *id; ///< Unique Identifier of the license - char *version; ///< Version of the license file schema - char *title; ///< Short title summarizing the license - char *type; ///< Type of license, e.g. trial or commercial - char *customer_name; ///< Name of the customer - time_t created; ///< Time the license was created - time_t begins; ///< Time after which the license becomes valid - time_t expires; ///< Time the license expires -} license_meta_t; - -license_meta_t * -license_meta_new (); - -void -license_meta_free (license_meta_t *); - -/** - * @brief Defines the hardware and appliance information of a license - */ -typedef struct { - char *model; ///< Appliance model, e.g. "one", "ceno", "450", ... - char *model_type; ///< Appliance model type, e.g. "virtual" or "hardware" - gboolean sensor; ///< Whether the license is applied to a sensor or not -} license_appliance_t; - -license_appliance_t * -license_appliance_new (); - -void -license_appliance_free (license_appliance_t *); - -/** - * @brief Defines the information contained in a license - */ -typedef struct { - license_meta_t *meta; ///< License metadata - license_appliance_t *appliance; ///< Hardware and appliance information - GTree *keys; ///< Base64 encoded access keys, e.g. feed key - GTree *signatures; ///< Signature info of the license -} license_data_t; - -license_data_t * -license_data_new (); - -void -license_data_free (license_data_t *); - +#ifdef HAS_LIBTHEIA +#include +#else +#include "theia_dummy.h" +#endif /* Actions */ @@ -85,4 +37,4 @@ int manage_update_license_file (const char *); int -manage_get_license (char **, license_data_t **); +manage_get_license (char **, theia_license_t **); diff --git a/src/theia_dummy.h b/src/theia_dummy.h new file mode 100644 index 0000000000..4de53613a4 --- /dev/null +++ b/src/theia_dummy.h @@ -0,0 +1,24 @@ +/* Copyright (C) 2021 Greenbone Networks GmbH + * + * SPDX-License-Identifier: AGPL-3.0-or-later + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +/** + * @file theia_dummy.h + * @brief Dummy definitions and headers for libtheia. + */ + +typedef void theia_license_t; \ No newline at end of file