]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Squashed commit of the following:
authorruss <rucombs@cisco.com>
Wed, 17 Apr 2019 01:29:44 +0000 (21:29 -0400)
committerruss <rucombs@cisco.com>
Wed, 17 Apr 2019 01:29:44 +0000 (21:29 -0400)
commit a7e771a2fafea7cb9d184b9ab08d0d436de91819
Author: russ <rucombs@cisco.com>
Date:   Tue Apr 16 09:27:28 2019 -0400

    build: fix lua_plugffi.h make error

commit 561738d9ffc7b6491b618187affe51b379389681
Author: russ <rucombs@cisco.com>
Date:   Mon Apr 15 10:02:53 2019 -0400

    Lua: remove dependency on SNORT_LUA_PATH

commit 6e0cb4c41a389ef6f084ef82c0155acc888f1786
Author: russ <rucombs@cisco.com>
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.

21 files changed:
README.md
doc/appid.txt
doc/enviro.txt
doc/overview.txt
doc/tutorial.txt
doc/usage.txt
lua/CMakeLists.txt
lua/snort.lua [moved from lua/snort.lua.in with 88% similarity]
src/log/messages.cc
src/main/policy.h
src/main/shell.cc
src/main/shell.h
src/main/snort_config.h
src/main/snort_module.cc
src/managers/CMakeLists.txt
src/managers/module_manager.cc
src/managers/module_manager.h
src/parser/parse_conf.cc
src/parser/parse_conf.h
src/parser/parser.cc
src/parser/parser.h

index 584302020aab273b845cf4ec01c88a1ee3de09ea..a0fb376b9b386a7ea910c9b6450b3fdc7fb62bdf 100644 (file)
--- 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
index 357a1320beff603455b3a44a94ecfc8a4cf6eda2..84b1eba783e9c81274d91fb2a8c8164ebe2406b8 100644 (file)
@@ -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,
index ba2b77fb6f38cd5d3110006ecc1cdba85a1f3099..d2bc68a7b01bb268db07854251096ff51af84c1c 100644 (file)
@@ -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")~ .
 
index 2f125a6d7b734a3ab541f4ea3eb1516f60b18bf4..f7bff7d8cc0fd7fcb4b59ee75de43bbb5585fdeb 100644 (file)
@@ -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:
index 725b75f57161e92b10d7d5592448fd1206ec8b09..ebcf66714c6ac30c761e8510b172655ae4b6ec62 100644 (file)
@@ -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:
 
index 7eb9ad73cb61c93959daa0d619ddcb2b4b0645a6..6b45957aa49614230704cba0a256c5decbc16a3a 100644 (file)
@@ -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:
index 9f5884d4ca02d4afec81fe9abb3a8a9c56c6805f..4f9fc0343b99957828612fee2e4fb86f3e12e301 100644 (file)
@@ -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"
 )
similarity index 88%
rename from lua/snort.lua.in
rename to lua/snort.lua
index 2e740b31961a3ebbcbea810564bfa0a4f5de905d..a41e61220255d6f6a37da532fc0f9633b968bf9f 100644 (file)
@@ -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
index 515a17dcb31cfad91e61296a386fee59f18c0700..e1fda5baf9ba9fc2547d6db5d5a1539669fbac0e 100644 (file)
@@ -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);
 }
index 8a6b59a40441d4f47c58664b528909a3ebbc6923..a652613f450d79f2a930f6d9b8e28de384c30ad6 100644 (file)
@@ -152,6 +152,7 @@ public:
 
     std::string include;
     std::string rules;
+    std::string parse_from;
 
     uint32_t var_id;
 
index 79bc16ad84fedcbb89a8b23690888cba44915843..d553c30adddfdf87aa7fbc46994ceba4dce13bae 100644 (file)
@@ -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;
 }
 
index 039d2725757ff4a02a5ccb10266786214461c840..64d5dbed45c3cbe14f583686f0b9ca911e67dbc4 100644 (file)
@@ -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; }
 
index 86df3ef33f6b221022a7bffddd2ca02ac4dd556f..6aca555eb4041c742857a7e2ac721610d96d94f3 100644 (file)
@@ -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; }
 
index 617d062a64a9e46bf05ae0dc16ea6eb2eacdcad0..f25bff1e7ca5fd41e7989b17f16eeb9d899a3aaf 100644 (file)
@@ -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,
       "[<module prefix>] output stub rules for selected modules" },
 
@@ -417,9 +420,6 @@ static const Parameter s_params[] =
       "<count> 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> 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,
       "<path> 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;
index 358472e2b5e0bcfd099d881584587386b4c8df01..4a208dec1226594dc24a8f172c6d0db85d76df18 100644 (file)
@@ -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
 )
 
index f6becc88f984e4e5bbe6efdf90df0187e5be69b7..890e2169c192d72bb32dc4e41cad0098f81f4346 100644 (file)
@@ -30,7 +30,6 @@
 #include <iostream>
 #include <mutex>
 #include <regex>
-#include <stack>
 #include <string>
 
 #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<DirStackItem> 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)
index 0ab6198227b0dc5110ff633d33fad2630ea9971b..0a4455d240b149a6b0692f5a5ffd5a2018edc659 100644 (file)
@@ -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
 
index ee22c790568d1f4ff7dc0f359a0fe40247f84bfc..500b9e974841cfa5c0790861cbfa99b2a864d7df 100644 (file)
@@ -25,7 +25,9 @@
 
 #include "parse_conf.h"
 
+#include <limits.h>
 #include <sys/stat.h>
+#include <unistd.h>
 
 #include <fstream>
 #include <stack>
@@ -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<Location> 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)
index e28e4f21a9edf7d6e3a49064fdede81840c809e3..8caa9698795396b42a46c68fe16f999e8a2ee591 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef PARSE_CONF_H
 #define PARSE_CONF_H
 
+#include <string>
 #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);
 
index dae7d837c1063f778c9dd830dcb8254588f491bd..53031ea4764d95dad1768351a3a828a11846ff61 100644 (file)
@@ -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();
         }
index cf6bb3fcfb55b2303b2435de8a0d6dca9e06c37d..f4dcba3634e0086e512fc50b9793eafa7d30e081 100644 (file)
@@ -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