From dcfa6a6002062d61c8ed092dcd9234dc1d6158db Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Mon, 17 Oct 2022 15:10:48 -0600 Subject: [PATCH] suricata: allow additional include files on command line Add a new command line option, --include. This will merge additional configuration files into the configuration specified in the main suricata.yaml. It can be provided multiple times and the files will be included in the order they appear on the command line. Ticket: 3912 --- src/conf-yaml-loader.c | 3 +-- src/conf-yaml-loader.h | 3 +++ src/detect-engine.c | 9 +++++++++ src/suricata.c | 36 ++++++++++++++++++++++++++++++++++++ src/suricata.h | 1 + 5 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/conf-yaml-loader.c b/src/conf-yaml-loader.c index e7906b0a48..ca85f498d8 100644 --- a/src/conf-yaml-loader.c +++ b/src/conf-yaml-loader.c @@ -113,8 +113,7 @@ ConfYamlSetConfDirname(const char *filename) * * \retval 0 on success, -1 on failure. */ -static int -ConfYamlHandleInclude(ConfNode *parent, const char *filename) +int ConfYamlHandleInclude(ConfNode *parent, const char *filename) { yaml_parser_t parser; char include_filename[PATH_MAX]; diff --git a/src/conf-yaml-loader.h b/src/conf-yaml-loader.h index 6c599d0ac8..fcf73aaa8d 100644 --- a/src/conf-yaml-loader.h +++ b/src/conf-yaml-loader.h @@ -24,9 +24,12 @@ #ifndef __CONF_YAML_LOADER_H__ #define __CONF_YAML_LOADER_H__ +#include "conf.h" + int ConfYamlLoadFile(const char *); int ConfYamlLoadString(const char *, size_t); int ConfYamlLoadFileWithPrefix(const char *filename, const char *prefix); +int ConfYamlHandleInclude(ConfNode *parent, const char *filename); void ConfYamlRegisterTests(void); diff --git a/src/detect-engine.c b/src/detect-engine.c index f0d3b1bc7a..bb56c81c72 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -4441,6 +4441,7 @@ int DetectEngineReload(const SCInstance *suri) if (suri->conf_filename != NULL) { snprintf(prefix, sizeof(prefix), "detect-engine-reloads.%d", reloads++); + SCLogConfig("Reloading %s", suri->conf_filename); if (ConfYamlLoadFileWithPrefix(suri->conf_filename, prefix) != 0) { SCLogError("failed to load yaml %s", suri->conf_filename); return -1; @@ -4451,6 +4452,14 @@ int DetectEngineReload(const SCInstance *suri) SCLogError("failed to properly setup yaml %s", suri->conf_filename); return -1; } + + if (suri->additional_configs) { + for (int i = 0; suri->additional_configs[i] != NULL; i++) { + SCLogConfig("Reloading %s", suri->additional_configs[i]); + ConfYamlHandleInclude(node, suri->additional_configs[i]); + } + } + #if 0 ConfDump(); #endif diff --git a/src/suricata.c b/src/suricata.c index 49b81d5897..ad44e129aa 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -677,6 +677,7 @@ static void PrintUsage(const char *progname) #ifdef HAVE_LIBNET11 printf("\t--reject-dev : send reject packets from this interface\n"); #endif + printf("\t--include : additonal configuration file\n"); printf("\t--set name=value : set a configuration value\n"); printf("\n"); printf("\nTo run the engine with default configuration on " @@ -960,6 +961,13 @@ static TmEcode LoadYamlConfig(SCInstance *suri) SCReturnInt(TM_ECODE_FAILED); } + if (suri->additional_configs) { + for (int i = 0; suri->additional_configs[i] != NULL; i++) { + SCLogConfig("Loading additional configuration file %s", suri->additional_configs[i]); + ConfYamlHandleInclude(ConfGetRootNode(), suri->additional_configs[i]); + } + } + SCReturnInt(TM_ECODE_OK); } @@ -1390,6 +1398,7 @@ static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri) {"simulate-packet-tcp-ssn-memcap", required_argument, 0, 0}, {"simulate-packet-defrag-memcap", required_argument, 0, 0}, {"simulate-alert-queue-realloc-failure", 0, 0, 0}, + {"include", required_argument, 0, 0}, {NULL, 0, NULL, 0} }; @@ -1761,6 +1770,33 @@ static TmEcode ParseCommandLine(int argc, char** argv, SCInstance *suri) if (suri->strict_rule_parsing_string == NULL) { FatalError("failed to duplicate 'strict' string"); } + } else if (strcmp((long_opts[option_index]).name, "include") == 0) { + if (suri->additional_configs == NULL) { + suri->additional_configs = SCCalloc(2, sizeof(char **)); + if (suri->additional_configs == NULL) { + FatalError( + "Failed to allocate memory for additional configuration files: %s", + strerror(errno)); + } + suri->additional_configs[0] = optarg; + } else { + for (int i = 0;; i++) { + if (suri->additional_configs[i] == NULL) { + const char **additional_configs = + SCRealloc(suri->additional_configs, (i + 2) * sizeof(char **)); + if (additional_configs == NULL) { + FatalError("Failed to allocate memory for additional configuration " + "files: %s", + strerror(errno)); + } else { + suri->additional_configs = additional_configs; + } + suri->additional_configs[i] = optarg; + suri->additional_configs[i + 1] = NULL; + break; + } + } + } } else { int r = ExceptionSimulationCommandlineParser( (long_opts[option_index]).name, optarg); diff --git a/src/suricata.h b/src/suricata.h index 36e2e58670..20c31c8682 100644 --- a/src/suricata.h +++ b/src/suricata.h @@ -157,6 +157,7 @@ typedef struct SCInstance_ { const char *log_dir; const char *progname; /**< pointer to argv[0] */ const char *conf_filename; + const char **additional_configs; char *strict_rule_parsing_string; const char *capture_plugin_name;