From dc8f9fc405243d583dd3ba5c44e197540cbf6748 Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Mon, 13 Sep 2021 06:19:19 -0500 Subject: [PATCH 1/3] Fix plugins upload. When a plugin modification was done quite earlier than the time in which it is put in the feed, the mtime is older than the feed version and the plugin is no uploaded/updated in the redis cache. This produced that some metadata or preferences is outdated for vts in this situation. This patch fix this, and now the upload is always done for all vts to ensure that the cache is up-to-date. --- nasl/exec.c | 2 + nasl/nasl_global_ctxt.h | 5 ++- nasl/nasl_grammar.y | 17 ++++++-- src/nasl_plugins.c | 93 ++++++++++++++++++++++++++--------------- src/openvas.c | 21 ++++++++++ src/pluginload.c | 5 +++ src/pluginload.h | 2 + 7 files changed, 108 insertions(+), 37 deletions(-) diff --git a/nasl/exec.c b/nasl/exec.c index 5157cdf27..3f5190e2e 100644 --- a/nasl/exec.c +++ b/nasl/exec.c @@ -1657,6 +1657,8 @@ exec_nasl_script (struct script_infos *script_infos, int mode) bzero (&ctx, sizeof (ctx)); if (mode & NASL_ALWAYS_SIGNED) ctx.always_signed = 1; + if ((mode & NASL_EXEC_DESCR) != 0) + ctx.exec_descr = 1; if (nvticache_initialized ()) ctx.kb = nvticache_get_kb (); else diff --git a/nasl/nasl_global_ctxt.h b/nasl/nasl_global_ctxt.h index ed6e950c7..d158e5602 100644 --- a/nasl/nasl_global_ctxt.h +++ b/nasl/nasl_global_ctxt.h @@ -26,7 +26,10 @@ typedef struct { int line_nb; - int always_signed; + int always_signed; /**< If set disable signature check during scans and feed + upload. */ + int exec_descr; /**< Tell grammar that is a feed upload process or a running a + scan process. */ int index; tree_cell *tree; char *buffer; diff --git a/nasl/nasl_grammar.y b/nasl/nasl_grammar.y index 4b3be046f..c476acba6 100644 --- a/nasl/nasl_grammar.y +++ b/nasl/nasl_grammar.y @@ -316,6 +316,7 @@ inc: INCLUDE '(' string ')' bzero (&subctx, sizeof (subctx)); subctx.always_signed = ((naslctxt*)parm)->always_signed; + subctx.exec_descr = ((naslctxt*)parm)->exec_descr; subctx.kb = ((naslctxt *) parm)->kb; subctx.tree = ((naslctxt*) parm)->tree; $$ = NULL; @@ -763,7 +764,12 @@ init_nasl_ctx(naslctxt* pc, const char* name) filename = full_name; snprintf (key_path, sizeof (key_path), "signaturecheck:%s", filename); timestamp = kb_item_get_int (pc->kb, key_path); - if (timestamp > 0) + + /* We never use the mtime of a .nasl/.inc file as integrity check during + * the script load up. A complete verification is done in this case. + * Once it has been uploaded in the nvticache it is enough to just check + * the mtime. */ + if (timestamp > 0 && pc->exec_descr == 0) { struct stat file_stat; @@ -796,14 +802,19 @@ init_nasl_ctx(naslctxt* pc, const char* name) int ret; char *check = file_checksum (full_name, checksum_algorithm); + snprintf (key_path, sizeof (key_path), "signaturecheck:%s", filename); ret = strcmp (check, checksum); if (ret) - g_warning ("checksum for %s not matching", full_name); + { + kb_del_items (pc->kb, key_path); + g_warning ("checksum for %s not matching", full_name); + } else { - snprintf (key_path, sizeof (key_path), "signaturecheck:%s", filename); + kb_del_items (pc->kb, key_path); kb_item_add_int (pc->kb, key_path, time (NULL)); } + g_free (full_name); g_free (checksum); g_free (check); diff --git a/src/nasl_plugins.c b/src/nasl_plugins.c index 5afed2036..ae105c45d 100644 --- a/src/nasl_plugins.c +++ b/src/nasl_plugins.c @@ -83,12 +83,45 @@ check_nvti (const char *filename, nvti_t *nvt) return 0; } +/** + * @brief Check a single .nasl/.inc file. + * + * @param folder Path to the plugin folder. + * @param filename File-name of the plugin + * + * @return 0 on success, -1 on error. + */ +int +nasl_file_check (const char *folder, const char *filename) +{ + char fullname[PATH_MAX + 1]; + int nasl_mode; + struct script_infos *args; + + snprintf (fullname, sizeof (fullname), "%s/%s", folder, filename); + nasl_mode = NASL_EXEC_DESCR; + if (prefs_get_bool ("nasl_no_signature_check")) + nasl_mode |= NASL_ALWAYS_SIGNED; + + args = g_malloc0 (sizeof (struct script_infos)); + args->key = nvticache_get_kb (); + args->nvti = NULL; + args->name = fullname; + if (exec_nasl_script (args, nasl_mode) < 0) + { + g_debug ("%s: Checksum check failed", fullname); + g_free (args); + return -1; + } + g_free (args); + + return 0; +} + /** * @brief Add *one* .nasl plugin to the plugin list. * - * The plugin is first attempted to be loaded from the cache. - * If that fails, it is parsed (via exec_nasl_script) and - * added to the cache. + * It is parsed (via exec_nasl_script) and added to the cache * * @param folder Path to the plugin folder. * @param filename File-name of the plugin @@ -100,44 +133,38 @@ nasl_plugin_add (char *folder, char *filename) { char fullname[PATH_MAX + 1]; int nasl_mode; - nasl_mode = NASL_EXEC_DESCR; + nvti_t *new_nvti; + struct script_infos *args; + time_t now; + struct utimbuf updated_timestamp; snprintf (fullname, sizeof (fullname), "%s/%s", folder, filename); - + nasl_mode = NASL_EXEC_DESCR; if (prefs_get_bool ("nasl_no_signature_check")) - { - nasl_mode |= NASL_ALWAYS_SIGNED; - } + nasl_mode |= NASL_ALWAYS_SIGNED; - if (!nvticache_check (filename)) + args = g_malloc0 (sizeof (struct script_infos)); + args->key = nvticache_get_kb (); + new_nvti = nvti_new (); + args->nvti = new_nvti; + args->name = fullname; + if (exec_nasl_script (args, nasl_mode) < 0) { - nvti_t *new_nvti; - struct script_infos *args; - time_t now; - struct utimbuf updated_timestamp; - - args = g_malloc0 (sizeof (struct script_infos)); - args->key = nvticache_get_kb (); - new_nvti = nvti_new (); - args->nvti = new_nvti; - args->name = fullname; - if (exec_nasl_script (args, nasl_mode) < 0) - { - g_debug ("%s: Could not be loaded", fullname); - g_free (args); - return -1; - } + g_debug ("%s: Could not be loaded", fullname); g_free (args); + return -1; + } + g_free (args); - now = time (NULL) - 1; - updated_timestamp.actime = now; - updated_timestamp.modtime = now; - utime (fullname, &updated_timestamp); + now = time (NULL) - 1; + updated_timestamp.actime = now; + updated_timestamp.modtime = now; + utime (fullname, &updated_timestamp); + + if (!check_nvti (filename, new_nvti)) + nvticache_add (new_nvti, filename); + nvti_free (new_nvti); - if (!check_nvti (filename, new_nvti)) - nvticache_add (new_nvti, filename); - nvti_free (new_nvti); - } return 0; } diff --git a/src/openvas.c b/src/openvas.c index 2bb876068..306062726 100644 --- a/src/openvas.c +++ b/src/openvas.c @@ -381,6 +381,25 @@ stop_single_task_scan (void) killpg (pid, SIGUSR1); } +/** + * @brief Send a failure message and set the scan as finished. + * + * @param msg Message to send to the client. + */ +void +send_message_to_client_and_finish_scan (const char *msg) +{ + char key[1024]; + kb_t kb; + + snprintf (key, sizeof (key), "internal/%s/scanprefs", global_scan_id); + kb = kb_find (prefs_get ("db_address"), key); + kb_item_push_str (kb, "internal/results", msg); + snprintf (key, sizeof (key), "internal/%s", global_scan_id); + kb_item_set_str (kb, key, "finished", 0); + kb_lnk_reset (kb); +} + /** * @brief Set up data needed for attack_network(). * @@ -401,6 +420,8 @@ attack_network_init (struct scan_globals *globals, const gchar *config_file) if (plugins_cache_init ()) { g_message ("Failed to initialize nvti cache."); + send_message_to_client_and_finish_scan ( + "ERRMSG||||||||||||NVTI cache initialization failed"); nvticache_reset (); exit (1); } diff --git a/src/pluginload.c b/src/pluginload.c index ccccfd21d..eb5e63b99 100644 --- a/src/pluginload.c +++ b/src/pluginload.c @@ -360,6 +360,7 @@ include_dirs (void) int plugins_cache_init (void) { + int ret; const char *plugins_folder = prefs_get ("plugins_folder"); if (nvticache_init (plugins_folder, prefs_get ("db_address"))) @@ -368,6 +369,10 @@ plugins_cache_init (void) return -1; } include_dirs (); + ret = nasl_file_check (plugins_folder, "plugin_feed_info.inc"); + if (ret) + return -1; + return 0; } diff --git a/src/pluginload.h b/src/pluginload.h index 4afd46019..5824bd24e 100644 --- a/src/pluginload.h +++ b/src/pluginload.h @@ -52,6 +52,8 @@ total_loading_plugins (void); /* From nasl_plugins.c */ int nasl_plugin_add (char *, char *); +int +nasl_file_check (const char *, const char *); int nasl_plugin_launch (struct scan_globals *, struct in6_addr *, GSList *, kb_t, From d238873e5e8bcb8dadb916aad66066310049ac31 Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Tue, 14 Sep 2021 09:19:24 -0500 Subject: [PATCH 2/3] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b1b42573..71b624c20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Fixed - Use fchmod to change file permission instead of on open to prevent race conditions [854](https://github.com/greenbone/openvas-scanner/pull/854) - Several minor potential security risks in different files, spotted by Code QL [854](https://github.com/greenbone/openvas-scanner/pull/854) +- Fix plugins upload. Backport #878 [#880](https://github.com/greenbone/openvas/pull/880) ### Removed - Remove handling of source_iface related preferences. [#730](https://github.com/greenbone/openvas/pull/730) From 3d14dba5a42ee3e28c07523eee2464d7d1fb8773 Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Tue, 14 Sep 2021 09:56:39 -0500 Subject: [PATCH 3/3] Fix format --- src/openvas.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openvas.c b/src/openvas.c index 306062726..f13d1c790 100644 --- a/src/openvas.c +++ b/src/openvas.c @@ -421,7 +421,7 @@ attack_network_init (struct scan_globals *globals, const gchar *config_file) { g_message ("Failed to initialize nvti cache."); send_message_to_client_and_finish_scan ( - "ERRMSG||||||||||||NVTI cache initialization failed"); + "ERRMSG||||||||||||NVTI cache initialization failed"); nvticache_reset (); exit (1); }