From: russ Date: Wed, 17 Apr 2019 01:29:44 +0000 (-0400) Subject: Squashed commit of the following: X-Git-Tag: 3.0.0-253~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b31dba02c4249e8a0fbff51627bbf69c6c571bba;p=thirdparty%2Fsnort3.git Squashed commit of the following: commit a7e771a2fafea7cb9d184b9ab08d0d436de91819 Author: russ Date: Tue Apr 16 09:27:28 2019 -0400 build: fix lua_plugffi.h make error commit 561738d9ffc7b6491b618187affe51b379389681 Author: russ Date: Mon Apr 15 10:02:53 2019 -0400 Lua: remove dependency on SNORT_LUA_PATH commit 6e0cb4c41a389ef6f084ef82c0155acc888f1786 Author: russ Date: Wed Apr 10 15:54:43 2019 -0400 parser: update include file handling Unify Lua and rule include handling of relative paths to search in this order: relative to working directory, relative to the including file, and if that fails relative to the -c conf. The precedence allows overrides and supports processing non-local configurations. --- diff --git a/README.md b/README.md index 584302020..a0fb376b9 100644 --- a/README.md +++ b/README.md @@ -123,15 +123,9 @@ Follow these steps: # RUN SNORT -First set up the environment: +Here are some examples. -```shell -export SNORT_LUA_PATH=$my_path/etc/snort -``` - -Then give it a go: - -* Snort++ provides lots of help from the command line. Here are some examples: +* Snort++ provides lots of help from the command line, including: ```shell $my_path/bin/snort --help diff --git a/doc/appid.txt b/doc/appid.txt index 357a1320b..84b1eba78 100644 --- a/doc/appid.txt +++ b/doc/appid.txt @@ -69,21 +69,6 @@ will reduce performance. Below is a minimal Snort configuration that is sufficient to block flows based on a specific HTTP header: - dir = os.getenv('SNORT_LUA_PATH') - - if ( not dir ) then - dir = '.' - end - - dofile(dir .. '/snort_defaults.lua') - - - local_rules = - [[ - block http ( msg:"openAppId: test content match for app http"; - content:"X-Header: malicious"; sid:18760; rev:4; ) - ]] - stream = { } stream_tcp = { } @@ -107,6 +92,12 @@ based on a specific HTTP header: appid = { } + local_rules = + [[ + block http ( msg:"openAppId: test content match for app http"; + content:"X-Header: malicious"; sid:18760; rev:4; ) + ]] + ips = { rules = local_rules, diff --git a/doc/enviro.txt b/doc/enviro.txt index ba2b77fb6..d2bc68a7b 100644 --- a/doc/enviro.txt +++ b/doc/enviro.txt @@ -5,9 +5,6 @@ Lua conf. Unknown symbols not in SNORT_IGNORE will cause warnings with --warn-unknown or fatals with --warn-unknown --pedantic. -* *SNORT_LUA_PATH*: an optional path where Snort can find supplemental conf - files such as classification.lua. - * *SNORT_PROMPT*: the character sequence that is printed at startup, shutdown, and in the shell. The default is the mini-pig: o")~ . diff --git a/doc/overview.txt b/doc/overview.txt index 2f125a6d7..f7bff7d8c 100644 --- a/doc/overview.txt +++ b/doc/overview.txt @@ -138,13 +138,6 @@ done with Lua, so your old conf won't work as is. Rules are still text based but with syntax tweaks, so your 2.X rules must be fixed up. However, snort2lua will help you convert your conf and rules to the new format. -==== Environment - -SNORT_LUA_PATH must be set to load auxiliary configuration files if you use -the default snort.lua. For example: - - export SNORT_LUA_PATH=$install_prefix/etc/snort - ==== Command Line A simple command line might look like this: diff --git a/doc/tutorial.txt b/doc/tutorial.txt index 725b75f57..ebcf66714 100644 --- a/doc/tutorial.txt +++ b/doc/tutorial.txt @@ -111,11 +111,7 @@ c. Or use ccmake directly to configure and generate from an arbitrary build === Running -First set up the environment: - - export SNORT_LUA_PATH=$my_path/etc/snort/ - -Then give it a go: +Examples: * Get some help: diff --git a/doc/usage.txt b/doc/usage.txt index 7eb9ad73c..6b45957aa 100644 --- a/doc/usage.txt +++ b/doc/usage.txt @@ -3,13 +3,6 @@ Snort install directory. Additionally, it is assumed that "$my_path/bin" is in your PATH. -=== Environment - -SNORT_LUA_PATH is used by Snort to load supplemental configuration files. - - export SNORT_LUA_PATH=$my_path/etc/snort - - === Help Print the help summary: diff --git a/lua/CMakeLists.txt b/lua/CMakeLists.txt index 9f5884d4c..4f9fc0343 100644 --- a/lua/CMakeLists.txt +++ b/lua/CMakeLists.txt @@ -2,13 +2,11 @@ set (LUA_SCRIPTS file_magic.lua inline.lua + snort.lua snort_defaults.lua talos.lua ) -configure_file(snort.lua.in - snort.lua) - -install (FILES ${LUA_SCRIPTS} ${CMAKE_CURRENT_BINARY_DIR}/snort.lua +install (FILES ${LUA_SCRIPTS} DESTINATION "${CMAKE_INSTALL_SYSCONFDIR}/snort" ) diff --git a/lua/snort.lua.in b/lua/snort.lua similarity index 88% rename from lua/snort.lua.in rename to lua/snort.lua index 2e740b319..a41e61220 100644 --- a/lua/snort.lua.in +++ b/lua/snort.lua @@ -6,38 +6,17 @@ -- many can be used with defaults w/o any explicit configuration. -- use this conf as a template for your specific configuration. --- 1. configure environment --- 2. configure defaults --- 3. configure inspection --- 4. configure bindings --- 5. configure performance --- 6. configure detection --- 7. configure filters --- 8. configure outputs --- 9. configure tweaks +-- 1. configure defaults +-- 2. configure inspection +-- 3. configure bindings +-- 4. configure performance +-- 5. configure detection +-- 6. configure filters +-- 7. configure outputs +-- 8. configure tweaks --------------------------------------------------------------------------- --- 1. configure environment ---------------------------------------------------------------------------- - --- given: --- export DIR=/install/path --- configure --prefix=$DIR --- make install - --- then: --- export SNORT_LUA_PATH=$DIR/etc/snort - --- this depends on SNORT_LUA_PATH --- where to find other config files -conf_dir = os.getenv('SNORT_LUA_PATH') - -if ( not conf_dir ) then - conf_dir = '${CMAKE_INSTALL_FULL_SYSCONFDIR}/snort' -end - ---------------------------------------------------------------------------- --- 2. configure defaults +-- 1. configure defaults --------------------------------------------------------------------------- -- HOME_NET and EXTERNAL_NET must be set now @@ -48,11 +27,11 @@ HOME_NET = 'any' -- (leave as "any" in most situations) EXTERNAL_NET = 'any' -dofile(conf_dir .. '/snort_defaults.lua') -dofile(conf_dir .. '/file_magic.lua') +include 'snort_defaults.lua' +include 'file_magic.lua' --------------------------------------------------------------------------- --- 3. configure inspection +-- 2. configure inspection --------------------------------------------------------------------------- -- mod = { } uses internal defaults @@ -123,7 +102,7 @@ reputation = --]] --------------------------------------------------------------------------- --- 4. configure bindings +-- 3. configure bindings --------------------------------------------------------------------------- wizard = default_wizard @@ -165,7 +144,7 @@ binder = } --------------------------------------------------------------------------- --- 5. configure performance +-- 4. configure performance --------------------------------------------------------------------------- -- use latency to monitor / enforce packet and rule thresholds @@ -180,7 +159,7 @@ latency = --perf_monitor = { } --------------------------------------------------------------------------- --- 6. configure detection +-- 5. configure detection --------------------------------------------------------------------------- references = default_references @@ -202,7 +181,7 @@ ips = -- rewrite = { } --------------------------------------------------------------------------- --- 7. configure filters +-- 6. configure filters --------------------------------------------------------------------------- -- below are examples of filters @@ -242,7 +221,7 @@ rate_filter = --]] --------------------------------------------------------------------------- --- 8. configure outputs +-- 7. configure outputs --------------------------------------------------------------------------- -- event logging @@ -266,7 +245,7 @@ rate_filter = --file_log = { } --------------------------------------------------------------------------- --- 9. configure tweaks +-- 8. configure tweaks --------------------------------------------------------------------------- if ( tweaks ~= nil ) then diff --git a/src/log/messages.cc b/src/log/messages.cc index 515a17dcb..e1fda5baf 100644 --- a/src/log/messages.cc +++ b/src/log/messages.cc @@ -74,6 +74,10 @@ static void log_message(FILE* file, const char* type, const char* msg) if ( file_line ) snort::LogMessage(file, "%s: %s:%d %s\n", type, file_name, file_line, msg); + + else if ( file_name ) + snort::LogMessage(file, "%s: %s: %s\n", type, file_name, msg); + else snort::LogMessage(file, "%s: %s\n", type, msg); } diff --git a/src/main/policy.h b/src/main/policy.h index 8a6b59a40..a652613f4 100644 --- a/src/main/policy.h +++ b/src/main/policy.h @@ -152,6 +152,7 @@ public: std::string include; std::string rules; + std::string parse_from; uint32_t var_id; diff --git a/src/main/shell.cc b/src/main/shell.cc index 79bc16ad8..d553c30ad 100644 --- a/src/main/shell.cc +++ b/src/main/shell.cc @@ -34,6 +34,7 @@ #include "main/policy.h" #include "main/snort_config.h" #include "managers/module_manager.h" +#include "parser/parse_conf.h" #include "parser/parser.h" using namespace snort; @@ -78,10 +79,8 @@ static bool load_config(lua_State* L, const char* file, const char* tweaks, bool if (is_fatal) FatalError("can't load %s: %s\n", file, lua_tostring(L, -1)); else - { ParseError("can't load %s: %s\n", file, lua_tostring(L, -1)); - return false; - } + return false; } if ( tweaks and *tweaks ) { @@ -157,14 +156,12 @@ Shell::Shell(const char* s, bool load_defaults) lua_atpanic(lua, Shell::panic); luaL_openlibs(lua); - char pwd[PATH_MAX]; - parse_from = getcwd(pwd, sizeof(pwd)); - if ( s ) - set_file(s); + file = s; - loaded = false; + parse_from = get_parse_file(); + loaded = false; load_string(lua, ModuleManager::get_lua_bootstrap()); if ( load_defaults ) @@ -178,15 +175,7 @@ Shell::~Shell() void Shell::set_file(const char* s) { - assert(file.empty()); - - if ( s && s[0] != '/' && parsing_follows_files ) - { - file += parse_from; - file += '/'; - } - - file += s; + file = s; } void Shell::set_overrides(const char* s) @@ -216,15 +205,28 @@ bool Shell::configure(SnortConfig* sc, bool is_fatal) set_network_policy(pt->network); } - const char* base_name = push_relative_path(file.c_str()); - if(! config_lua(lua, base_name, overrides, sc->tweaks.c_str(), is_fatal)) + std::string path = parse_from; + const char* code = get_config_file(file.c_str(), path); + + if ( !code ) + { + if ( is_fatal ) + FatalError("can't find %s\n", file.c_str()); + else + ParseError("can't find %s\n", file.c_str()); + return false; + } + + push_parse_location(code, path.c_str(), file.c_str(), 0); + + if ( !config_lua(lua, path.c_str(), overrides, sc->tweaks.c_str(), is_fatal) ) return false; set_default_policy(sc); ModuleManager::set_config(nullptr); loaded = true; - pop_relative_path(); + pop_parse_location(); return true; } diff --git a/src/main/shell.h b/src/main/shell.h index 039d27257..64d5dbed4 100644 --- a/src/main/shell.h +++ b/src/main/shell.h @@ -48,6 +48,9 @@ public: const char* get_file() const { return file.c_str(); } + const char* get_from() const + { return parse_from.c_str(); } + bool get_loaded() const { return loaded; } diff --git a/src/main/snort_config.h b/src/main/snort_config.h index 86df3ef33..6aca555eb 100644 --- a/src/main/snort_config.h +++ b/src/main/snort_config.h @@ -38,7 +38,7 @@ enum RunFlag RUN_FLAG__READ = 0x00000001, RUN_FLAG__DAEMON = 0x00000002, RUN_FLAG__NO_PROMISCUOUS = 0x00000004, - /* UNUSED 0x00000008 */ + RUN_FLAG__NO_OVERRIDES = 0x00000008, RUN_FLAG__INLINE = 0x00000010, RUN_FLAG__STATIC_HASH = 0x00000020, @@ -55,7 +55,7 @@ enum RunFlag RUN_FLAG__INLINE_TEST = 0x00004000, RUN_FLAG__PCAP_SHOW = 0x00008000, - /* UNUSED 0x00010000 */ + RUN_FLAG__SHOW_FILE_CODES = 0x00010000, RUN_FLAG__PAUSE = 0x00020000, RUN_FLAG__NO_PCRE = 0x00040000, /* If stream is configured, the STATEFUL flag is set. This is @@ -474,6 +474,12 @@ public: static bool inline_test_mode() { return snort::get_ips_policy()->policy_mode == POLICY_MODE__INLINE_TEST; } + static bool show_file_codes() + { return get_conf()->run_flags & RUN_FLAG__SHOW_FILE_CODES; } + + static bool allow_overrides() + { return !(get_conf()->run_flags & RUN_FLAG__NO_OVERRIDES); } + static bool adaptor_inline_mode() { return get_conf()->run_flags & RUN_FLAG__INLINE; } diff --git a/src/main/snort_module.cc b/src/main/snort_module.cc index 617d062a6..f25bff1e7 100644 --- a/src/main/snort_module.cc +++ b/src/main/snort_module.cc @@ -315,6 +315,9 @@ static const Parameter s_params[] = { "--dirty-pig", Parameter::PT_IMPLIED, nullptr, nullptr, "don't flush packets on shutdown" }, + { "--disable-overrides", Parameter::PT_IMPLIED, nullptr, nullptr, + "do not first look for files relative to the working directory" }, + { "--dump-builtin-rules", Parameter::PT_STRING, "(optional)", nullptr, "[] output stub rules for selected modules" }, @@ -417,9 +420,6 @@ static const Parameter s_params[] = " pause after count packets", }, #endif - { "--parsing-follows-files", Parameter::PT_IMPLIED, nullptr, nullptr, - "parse relative paths from the perspective of the current configuration file" }, - { "--pcap-file", Parameter::PT_STRING, nullptr, nullptr, " file that contains a list of pcaps to read - read mode is implied" }, @@ -447,6 +447,11 @@ static const Parameter s_params[] = { "--pedantic", Parameter::PT_IMPLIED, nullptr, nullptr, "warnings are fatal" }, +#ifdef PIGLET + { "--piglet", Parameter::PT_IMPLIED, nullptr, nullptr, + "enable piglet test harness mode" }, +#endif + { "--plugin-path", Parameter::PT_STRING, nullptr, nullptr, " where to find plugins" }, @@ -477,10 +482,9 @@ static const Parameter s_params[] = "enable the interactive command line", }, #endif -#ifdef PIGLET - { "--piglet", Parameter::PT_IMPLIED, nullptr, nullptr, - "enable piglet test harness mode" }, -#endif + { "--show-file-codes", Parameter::PT_IMPLIED, nullptr, nullptr, + "indicate how files are located: A=absolute and W, F, C which are relative " + "to the working directory, including file, and config file respectively" }, { "--show-plugins", Parameter::PT_IMPLIED, nullptr, nullptr, "list module and plugin versions", }, @@ -799,6 +803,9 @@ bool SnortModule::set(const char*, Value& v, SnortConfig* sc) else if ( v.is("--enable-inline-test") ) sc->run_flags |= RUN_FLAG__INLINE_TEST; + else if ( v.is("--disable-overrides") ) + sc->run_flags |= RUN_FLAG__NO_OVERRIDES; + else if ( v.is("--gen-msg-map") ) dump_msg_map(sc, v.get_string()); @@ -879,9 +886,6 @@ bool SnortModule::set(const char*, Value& v, SnortConfig* sc) sc->pkt_pause_cnt = v.get_uint64(); #endif - else if ( v.is("--parsing-follows-files") ) - parsing_follows_files = true; - else if ( v.is("--pcap-file") ) { Trough::add_source(Trough::SOURCE_FILE_LIST, v.get_string()); @@ -907,6 +911,11 @@ bool SnortModule::set(const char*, Value& v, SnortConfig* sc) else if ( v.is("--pcap-show") ) sc->run_flags |= RUN_FLAG__PCAP_SHOW; +#ifdef PIGLET + else if ( v.is("--piglet") ) + sc->run_flags |= RUN_FLAG__PIGLET; +#endif + else if ( v.is("--plugin-path") ) sc->set_plugin_path(v.get_string()); @@ -936,10 +945,8 @@ bool SnortModule::set(const char*, Value& v, SnortConfig* sc) sc->run_flags |= RUN_FLAG__SHELL; #endif -#ifdef PIGLET - else if ( v.is("--piglet") ) - sc->run_flags |= RUN_FLAG__PIGLET; -#endif + else if ( v.is("--show-file-codes") ) + sc->run_flags |= RUN_FLAG__SHOW_FILE_CODES; else if ( v.is("--show-plugins") ) sc->logging_flags |= LOGGING_FLAG__SHOW_PLUGINS; diff --git a/src/managers/CMakeLists.txt b/src/managers/CMakeLists.txt index 358472e2b..4a208dec1 100644 --- a/src/managers/CMakeLists.txt +++ b/src/managers/CMakeLists.txt @@ -46,7 +46,6 @@ add_library( managers OBJECT add_custom_command ( OUTPUT lua_plugffi.h snort_plugin.lua COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/ffi_wrap.sh ${CMAKE_CURRENT_SOURCE_DIR}/lua_plugin_defs.h > plugffi.lua - COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/lua_wrap.sh ${CMAKE_CURRENT_SOURCE_DIR} plugffi > lua_plugffi.h COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/plugffi.lua ${CMAKE_CURRENT_BINARY_DIR}/snort_plugin.lua ) diff --git a/src/managers/module_manager.cc b/src/managers/module_manager.cc index f6becc88f..890e2169c 100644 --- a/src/managers/module_manager.cc +++ b/src/managers/module_manager.cc @@ -30,7 +30,6 @@ #include #include #include -#include #include #include "framework/base_api.h" @@ -93,6 +92,9 @@ extern "C" bool set_number(const char* fqn, double val); bool set_string(const char* fqn, const char* val); bool set_alias(const char* from, const char* to); + + const char* push_relative_path(const char* file); + void pop_relative_path(); } //------------------------------------------------------------------------- @@ -816,59 +818,24 @@ SO_PUBLIC bool set_string(const char* fqn, const char* s) return set_value(fqn, v); } -struct DirStackItem -{ - string previous_dir; - string base_name; -}; - -static std::stack dir_stack; - SO_PUBLIC const char* push_relative_path(const char* file) { - if ( !parsing_follows_files ) - return file; - - dir_stack.push(DirStackItem()); - DirStackItem& dsi = dir_stack.top(); - - char pwd[PATH_MAX]; - - if ( getcwd(pwd, sizeof(pwd)) == nullptr ) - FatalError("Unable to determine process running directory\n"); - - dsi.previous_dir = pwd; - - char* base_name_buf = snort_strdup(file); - dsi.base_name = basename(base_name_buf); - snort_free(base_name_buf); - - char* dir_name_buf = snort_strdup(file); - char* dir_name = dirname(dir_name_buf); - - if ( chdir(dir_name) != 0 ) - FatalError("Unable to access %s\n", dir_name); - - snort_free(dir_name_buf); - - return dsi.base_name.c_str(); + static std::string path; + path = ""; + const char* code = get_config_file(file, path); + push_parse_location(code, path.c_str(), file); + return path.c_str(); } SO_PUBLIC void pop_relative_path() { - if ( !parsing_follows_files ) - return; - - assert( !dir_stack.empty() ); - - // We came from this directory, so it should still exist - const char* prev_dir = dir_stack.top().previous_dir.c_str(); - if ( chdir(prev_dir) != 0 ) - FatalError("Unable to access %s\n", prev_dir); - - dir_stack.pop(); + pop_parse_location(); } +//------------------------------------------------------------------------- +// private methods +//------------------------------------------------------------------------- + static bool comp_mods(const ModHook* l, const ModHook* r) { const Module* lm = l->mod; @@ -1355,7 +1322,6 @@ static void make_rule(ostream& os, const Module* m, const RuleMap* r) void ModuleManager::load_rules(SnortConfig* sc) { s_modules.sort(comp_gids); - push_parse_location("builtin"); for ( auto p : s_modules ) { @@ -1379,7 +1345,6 @@ void ModuleManager::load_rules(SnortConfig* sc) r++; } } - pop_parse_location(); } void ModuleManager::dump_rules(const char* pfx) diff --git a/src/managers/module_manager.h b/src/managers/module_manager.h index 0ab619822..0a4455d24 100644 --- a/src/managers/module_manager.h +++ b/src/managers/module_manager.h @@ -90,12 +90,5 @@ public: }; } -extern "C" -{ - // returns the correct path component to use for referencing the file - const char* push_relative_path(const char*); - void pop_relative_path(); -} - #endif diff --git a/src/parser/parse_conf.cc b/src/parser/parse_conf.cc index ee22c7905..500b9e974 100644 --- a/src/parser/parse_conf.cc +++ b/src/parser/parse_conf.cc @@ -25,7 +25,9 @@ #include "parse_conf.h" +#include #include +#include #include #include @@ -33,6 +35,7 @@ #include "log/messages.h" #include "main/snort_config.h" #include "managers/action_manager.h" +#include "managers/module_manager.h" #include "sfip/sf_vartable.h" #include "target_based/snort_protocols.h" #include "utils/util.h" @@ -46,15 +49,30 @@ using namespace snort; struct Location { + const char* code; + std::string path; std::string file; unsigned line; - Location(const char* s, unsigned u) - { file = s; line = u; } + Location(const char* c, const char* p, const char* f, unsigned u) + { code = c; path = p; file = f; line = u; } }; static std::stack files; +const char* get_parse_file() +{ + if ( !files.empty() ) + return files.top().path.c_str(); + + static char dir[PATH_MAX]; + + if ( !getcwd(dir, sizeof(dir)) ) + return ""; + + return dir; +} + void get_parse_location(const char*& file, unsigned& line) { if ( files.empty() ) @@ -68,14 +86,27 @@ void get_parse_location(const char*& file, unsigned& line) line = loc.line; } -void push_parse_location(const char* file, unsigned line) +static void print_parse_file(const char* msg, Location& loc) { - if ( !file ) + if ( SnortConfig::show_file_codes() ) + LogMessage("%s %s:%s:\n", msg, (loc.code ? loc.code : "?"), loc.file.c_str()); + + else + LogMessage("%s %s:\n", msg, loc.file.c_str()); +} + +void push_parse_location( + const char* code, const char* path, const char* file, unsigned line) +{ + if ( !path ) return; - Location loc(file, line); + if ( !file ) + file = path; + + Location loc(code, path, file, line); files.push(loc); - LogMessage("Loading %s:\n", file); + print_parse_file("Loading", loc); } void pop_parse_location() @@ -83,40 +114,95 @@ void pop_parse_location() if ( !files.empty() ) { Location& loc = files.top(); - LogMessage("Finished %s.\n", loc.file.c_str()); + print_parse_file("Finished", loc); files.pop(); } } void inc_parse_position() { + if ( files.empty() ) + return; Location& loc = files.top(); ++loc.line; } -void parse_include(SnortConfig* sc, const char* arg) +static bool valid_file(const char* file, std::string& path) { - struct stat file_stat; /* for include path testing */ - arg = ExpandVars(sc, arg); - char* fname = snort_strdup(arg); + path += '/'; + path += file; - /* Stat the file. If that fails, make it relative to the directory - * that the top level snort configuration file was in */ - if ( stat(fname, &file_stat) == -1 && fname[0] != '/' ) - { - const char* snort_conf_dir = get_snort_conf_dir(); + struct stat s; + return stat(path.c_str(), &s) == 0; +} + +static bool relative_to_parse_dir(const char* file, std::string& path) +{ + if ( !path.length() ) + path = get_parse_file(); + size_t idx = path.rfind('/'); + if ( idx == std::string::npos ) + idx = 0; + path.erase(idx); + return valid_file(file, path); +} - int path_len = strlen(snort_conf_dir) + strlen(arg) + 1; - snort_free(fname); +static bool relative_to_config_dir(const char* file, std::string& path) +{ + path = get_snort_conf_dir(); + return valid_file(file, path); +} + +static bool relative_to_working_dir(const char* file, std::string& path) +{ + char dir[PATH_MAX]; + if ( !getcwd(dir, sizeof(dir)) ) + return false; + path = dir; + return valid_file(file, path); +} + +const char* get_config_file(const char* arg, std::string& file) +{ + bool absolute = (arg[0] == '/'); - fname = (char*)snort_calloc(path_len); - snprintf(fname, path_len, "%s%s", snort_conf_dir, arg); + if ( absolute ) + { + file = arg; + return "A"; } + std::string hint = file; + + if ( SnortConfig::allow_overrides() and relative_to_working_dir(arg, file) ) + return "W"; + + file = hint; + + if ( relative_to_parse_dir(arg, file) ) + return "F"; + + if ( relative_to_config_dir(arg, file) ) + return "C"; - push_parse_location(fname); - ParseConfigFile(sc, fname); + return nullptr; +} + +void parse_include(SnortConfig* sc, const char* arg) +{ + assert(arg); + arg = ExpandVars(sc, arg); + std::string file; + + const char* code = get_config_file(arg, file); + + if ( !code ) + { + ParseError("can't open %s\n", arg); + return; + } + push_parse_location(code, file.c_str(), arg); + ParseConfigFile(sc, file.c_str()); pop_parse_location(); - snort_free((char*)fname); } void ParseIpVar(SnortConfig* sc, const char* var, const char* val) diff --git a/src/parser/parse_conf.h b/src/parser/parse_conf.h index e28e4f21a..8caa96987 100644 --- a/src/parser/parse_conf.h +++ b/src/parser/parse_conf.h @@ -20,6 +20,7 @@ #ifndef PARSE_CONF_H #define PARSE_CONF_H +#include #include "detection/rules.h" void parse_conf_init(); @@ -31,6 +32,12 @@ namespace snort struct SnortConfig; } +const char* get_parse_file(); + +// returns code or nullptr if not found, file holds abs path +// file may hold original parse path on entry +const char* get_config_file(const char* arg, std::string& file); + void ParseConfigFile(snort::SnortConfig*, const char* fname); void ParseConfigString(snort::SnortConfig*, const char* str); diff --git a/src/parser/parser.cc b/src/parser/parser.cc index dae7d837c..53031ea47 100644 --- a/src/parser/parser.cc +++ b/src/parser/parser.cc @@ -59,8 +59,6 @@ using namespace snort; -bool parsing_follows_files = false; - static struct rule_index_map_t* ruleIndexMap = nullptr; static std::string s_aux_rules; @@ -244,9 +242,7 @@ static bool parse_file(SnortConfig* sc, Shell* sh, bool is_fatal) if ( !fname || !*fname ) return false; - push_parse_location(fname, 0); bool success = sh->configure(sc, is_fatal); - pop_parse_location(); return success; } @@ -377,11 +373,13 @@ void ParseRules(SnortConfig* sc) ModuleManager::load_rules(sc); const char* fname = p->include.c_str(); + std::string file = p->parse_from; if ( fname && *fname ) { - push_parse_location(fname); - ParseConfigFile(sc, fname); + const char* code = get_config_file(fname, file); + push_parse_location(code, file.c_str(), fname); + ParseConfigFile(sc, file.c_str()); pop_parse_location(); } @@ -390,14 +388,14 @@ void ParseRules(SnortConfig* sc) if ( !p->rules.empty() ) { - push_parse_location("rules"); + push_parse_location("C", file.c_str(), "rules"); ParseConfigString(sc, p->rules.c_str()); pop_parse_location(); } if ( !idx && sc->stdin_rules ) { LogMessage("Reading rules until EOF or a line starting with END\n"); - push_parse_location("stdin"); + push_parse_location("C", get_snort_conf_dir(), "stdin"); parse_stream(std::cin, sc); pop_parse_location(); } diff --git a/src/parser/parser.h b/src/parser/parser.h index cf6bb3fcf..f4dcba363 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -36,7 +36,8 @@ void parser_term(snort::SnortConfig*); void get_parse_location(const char*& name, unsigned& line); // use line = 0 for lua to suppress line numbers for errors or warnings -void push_parse_location(const char* name, unsigned line = 1); +void push_parse_location( + const char* code, const char* path, const char* name = nullptr, unsigned line = 1); void pop_parse_location(); void inc_parse_position(); @@ -100,6 +101,5 @@ struct RuleTreeNodeKey PolicyId policyId; }; -extern bool parsing_follows_files; #endif