]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1908 in SNORT/snort3 from ~BBANTWAL/snort3:lua_whitelist to master
authorMichael Altizer (mialtize) <mialtize@cisco.com>
Tue, 18 Feb 2020 15:38:18 +0000 (15:38 +0000)
committerMichael Altizer (mialtize) <mialtize@cisco.com>
Tue, 18 Feb 2020 15:38:18 +0000 (15:38 +0000)
Squashed commit of the following:

commit b3a7aed754ada79a9493d27b9eda4cac57db6810
Author: Bhagya Tholpady <bbantwal@cisco.com>
Date:   Tue Feb 11 20:54:48 2020 -0500

    doc: update documentation for lua whitelist

commit c91dc91110887f7348fe09f60b4fad2a95de4fe4
Author: Bhagya Tholpady <bbantwal@cisco.com>
Date:   Tue Feb 11 20:52:38 2020 -0500

    main: add verbose output and print whitelist during reload

commit 3c54fac801e3ea60854e34cd8d46dc0b8e27f64a
Author: Bhagya Tholpady <bbantwal@cisco.com>
Date:   Tue Feb 11 20:52:15 2020 -0500

    lua: update lua files to whitelist the tables defined.
    define default_whitelist and whitelist them in snort_defaults.lua
    file_magic.lua to add file_magic table to whitelist

commit a1867b791cd05bcf36e308f701423aee08ae8dd4
Author: Bhagya Tholpady <bbantwal@cisco.com>
Date:   Tue Feb 11 20:48:44 2020 -0500

    module_manager: add snort_whitelist_append and snort_whitelist_add_prefix ffis
    These ffis add table names and prefixes to the lua whitelist used to print warnings when modules for the table names are not found in snort.
    split bootstrap into two lua files( bootstrap and finalize )
    load aliases before called snort_traversal in finalize.lua
    main: move config_lua to Shell::configure
    snort: add new warn flag warn-conf-strict that will throw out warning when table is not found

14 files changed:
doc/overview.txt
lua/file_magic.lua
lua/snort_defaults.lua
src/log/messages.h
src/main/shell.cc
src/main/shell.h
src/main/snort.cc
src/main/snort_module.cc
src/managers/CMakeLists.txt
src/managers/bootstrap.lua
src/managers/dev_notes.txt
src/managers/finalize.lua [new file with mode: 0644]
src/managers/module_manager.cc
src/managers/module_manager.h

index d96c7b36ce78203b637acd47854eb2e17bb975d0..e1f323eb88493e0dc096027fc1be60beb34107cb 100644 (file)
@@ -234,6 +234,27 @@ If we also wanted to limit retries to at least 5 seconds, we could do:
 
     active = { max_responses = 1, min_interval = 5 }
 
+==== Whitelist
+
+When Snort is run with the --warn-conf-strict option, warnings will be
+generated for all Lua tables present in the configuration files that do
+not map to Snort module names. Like with other warnings, these will
+upgraded to errors when Snort is run in pedantic mode.
+
+To dynamically add exceptions that should bypass this strict validation,
+two Lua functions are made available to be called during the evaluation
+of Snort configuration files: snort_whitelist_append() and
+snort_whitelist_add_prefix(). Each function takes a whitespace-delimited
+list, the former a list of exact table names and the latter a list of table
+name prefixes to allow.
+
+Examples:
+snort_whitelist_append("table1 table2")
+snort_whitelist_add_prefix("local_ foobar_")
+
+The accumulated contents of the whitelist (both exact and prefix) will be
+dumped when Snort is run in verbose mode (-v).
+
 ==== Rules
 
 Rules determine what Snort is looking for.  They can be put directly in
index 74432aa177f16df870aef4d1cefbcd495ec6b08f..7b194e470ef7d933dcfd80c86111adeafb56a366 100644 (file)
@@ -202,3 +202,5 @@ file_magic =
     { type = 'HWP', id = 323, category = 'Executables', msg = 'Hangul word processor file', rev = 1, version = '3.0', magic = { { content = '| 48 57 50 20 44 6F 63 75 6D 65 6E 74 20 46 69 6C 65 |', offset = 0, }, }, },
     { type = 'SWF', id = 324, category = 'Multimedia', msg = 'Flash file', rev = 1, magic = { { content = '| 5A 57 53 |', offset = 0}, }, },
 }
+
+snort_whitelist_append("file_magic")
index b641a72c372198bfb8ded1f0a59b996f779b4684..78a36ad1f53237b9fda6efc9ef8b96be6cf0d51e 100644 (file)
@@ -1157,3 +1157,25 @@ default_low_port_scan =
     icmp_sweep = icmp_low_sweep,
 }
 
+---------------------------------------------------------------------------
+-- default whitelist
+---------------------------------------------------------------------------
+default_whitelist =
+[[
+    ftp_command_specs default_ftp_server smtp_default_alt_max_command_lines
+    default_smtp http_methods sip_methods telnet_commands default_wizard
+    default_references default_classifications gtp_v0_msg gtp_v1_msg gtp_v2_msg
+    gtp_v0_info gtp_v1_info gtp_v2_info default_gtp tcp_low_ports
+    tcp_low_decoy tcp_low_sweep tcp_low_dist tcp_med_ports
+    tcp_med_decoy tcp_med_sweep tcp_med_dist tcp_hi_ports tcp_hi_decoy
+    tcp_hi_sweep tcp_hi_dist udp_low_ports udp_low_decoy udp_low_sweep
+    udp_low_dist udp_med_ports udp_med_decoy udp_med_sweep udp_med_dist
+    udp_hi_ports udp_hi_decoy udp_hi_sweep udp_hi_dist ip_low_proto
+    ip_low_decoy ip_low_sweep ip_low_dist ip_med_proto ip_med_decoy
+    ip_med_sweep ip_med_dist ip_hi_proto ip_hi_decoy ip_hi_sweep
+    ip_hi_dist icmp_low_sweep icmp_med_sweep icmp_hi_sweep
+    default_hi_port_scan default_med_port_scan default_low_port_scan
+]]
+
+snort_whitelist_append(default_whitelist)
+
index 2fb6518f9396330fb70d49297255adfc136aa919..f830a4cbfb7df6429e4dab70cffcd7d30bf7fb85 100644 (file)
@@ -37,8 +37,9 @@
 
 enum WarningGroup
 {
-    WARN_DAQ, WARN_CONF, WARN_VARS, WARN_SYMBOLS, WARN_SCRIPTS,
-    WARN_HOSTS, WARN_RULES, WARN_FLOWBITS, WARN_PLUGINS,
+    WARN_DAQ, WARN_CONF, WARN_CONF_STRICT, WARN_VARS,
+    WARN_SYMBOLS, WARN_SCRIPTS, WARN_HOSTS, WARN_RULES,
+    WARN_FLOWBITS, WARN_PLUGINS,
 #ifdef PIGLET
     WARN_PIGLET,
 #endif
index 16b7cf4ddfad5c134fac1a0300ad5a208b8c7d5f..742f3c0c0bab705f9aa09a9f0181dcc630b9bdb3 100644 (file)
@@ -36,6 +36,7 @@
 #include "managers/module_manager.h"
 #include "parser/parse_conf.h"
 #include "parser/parser.h"
+#include "utils/stats.h"
 
 using namespace snort;
 using namespace std;
@@ -44,18 +45,58 @@ using namespace std;
 // helper functions
 //-------------------------------------------------------------------------
 
+string Shell::fatal;
+std::stack<Shell*> Shell::current_shells;
+
 // FIXIT-M Shell::panic() works on Linux but on OSX we can't throw from lua
 // to C++.  unprotected lua calls could be wrapped in a pcall to ensure lua
 // panics don't kill the process.  or we can not use lua for the shell.  :(
-
-string Shell::fatal;
-
 [[noreturn]] int Shell::panic(lua_State* L)
 {
     fatal = lua_tostring(L, -1);
     throw runtime_error(fatal);
 }
 
+Shell* Shell::get_current_shell()
+{
+    if ( !current_shells.empty() )
+        return current_shells.top();
+
+    return nullptr;
+}
+
+bool Shell::is_whitelisted(const std::string& key)
+{
+    Shell* sh = Shell::get_current_shell();
+
+    if ( !sh )
+        return false;
+
+    const Whitelist& whitelist = sh->get_whitelist();
+    const Whitelist& whitelist_prefixes = sh->get_whitelist_prefixes();
+
+    for ( const auto& prefix : whitelist_prefixes )
+    {
+        if (key.compare(0, prefix.length(), prefix) == 0)
+            return true;
+    }
+
+    if ( whitelist.find(key) != whitelist.end() )
+        return true;
+
+    return false;
+}
+
+void Shell::whitelist_append(const char* keyword, bool is_prefix)
+{
+    Shell* sh = Shell::get_current_shell();
+
+    if ( !sh )
+        return;
+
+    sh->whitelist_update(keyword, is_prefix);
+}
+
 // FIXIT-L shell --pause should stop before loading config so Lua state
 // can be examined and modified.
 
@@ -110,36 +151,6 @@ static void load_string(lua_State* L, const char* s)
         FatalError("can't init overrides: %s\n", lua_tostring(L, -1));
 }
 
-static void run_config(lua_State* L, const char* t)
-{
-    Lua::ManageStack ms(L);
-
-    lua_getglobal(L, "snort_config");
-    lua_getglobal(L, t);
-
-    assert(lua_isfunction(L, -2));
-
-    if ( lua_pcall(L, 1, 1, 0) )
-    {
-        const char* err = lua_tostring(L, -1);
-        FatalError("%s\n", err);
-    }
-}
-
-static bool config_lua(
-    lua_State* L, const char* file, string& s, const char* tweaks, bool is_fatal)
-{
-    if ( file && *file )
-        if (!load_config(L, file, tweaks, is_fatal))
-            return false;
-
-    if ( !s.empty() )
-        load_string(L, s.c_str());
-
-    run_config(L, "_G");
-
-    return true;
-}
 
 //-------------------------------------------------------------------------
 // public methods
@@ -153,6 +164,8 @@ Shell::Shell(const char* s, bool load_defaults)
     if ( !lua )
         FatalError("Lua state instantiation failed\n");
 
+    current_shells.push(this);
+
     lua_atpanic(lua, Shell::panic);
     luaL_openlibs(lua);
 
@@ -166,6 +179,8 @@ Shell::Shell(const char* s, bool load_defaults)
 
     if ( load_defaults )
         load_string(lua, ModuleManager::get_lua_coreinit());
+
+    current_shells.pop();
 }
 
 Shell::~Shell()
@@ -227,14 +242,31 @@ bool Shell::configure(SnortConfig* sc, bool is_fatal, bool is_root)
 
     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) )
+    current_shells.push(this);
+
+    if (!path.empty() and !load_config(lua, path.c_str(), sc->tweaks.c_str(), is_fatal))
+    {
+        current_shells.pop();
         return false;
+    }
+
+    if ( !overrides.empty() )
+        load_string(lua, overrides.c_str());
+
+    if ( SnortConfig::log_verbose() )
+        print_whitelist();
+
+    load_string(lua, ModuleManager::get_lua_finalize());
+
+    clear_whitelist();
+    current_shells.pop();
 
     set_default_policy(sc);
     ModuleManager::set_config(nullptr);
     loaded = true;
 
     pop_parse_location();
+
     return true;
 }
 
@@ -272,3 +304,39 @@ void Shell::execute(const char* cmd, string& rsp)
     }
 }
 
+//-------------------------------------------------------------------------
+// private methods
+//-------------------------------------------------------------------------
+
+void Shell::print_whitelist() const
+{
+    std::string output;
+    if ( !whitelist.empty() )
+    {
+        output = "Lua Whitelist Keywords for " + file + ":";
+        LogMessage("\t%s\n",output.c_str());
+        for ( const auto& wl : whitelist )
+            LogMessage("\t\t%s\n", wl.c_str());
+    }
+
+    if ( !whitelist_prefixes.empty() )
+    {
+        output = "Lua Whitelist Prefixes for " + file + ":";
+        LogMessage("\t%s\n",output.c_str());
+        for ( const auto& wlp : whitelist_prefixes )
+            LogMessage("\t\t%s\n", wlp.c_str());
+    }
+}
+
+void Shell::whitelist_update(const char* s, bool is_prefix)
+{
+    Whitelist* wlist = nullptr;
+    if ( is_prefix )
+        wlist = &whitelist_prefixes;
+    else
+        wlist = &whitelist;
+
+    if ( s )
+        wlist->emplace(s);
+}
+
index 23d3c5ad7993c26887e97286dc780c25f2a8e783..4f26b0ad07747b3adc2116a6ca92a78e6123f47e 100644 (file)
@@ -22,6 +22,8 @@
 
 // Shell encapsulates a Lua state.  There is one for each policy file.
 
+#include <set>
+#include <stack>
 #include <string>
 
 struct lua_State;
@@ -34,6 +36,8 @@ struct SnortConfig;
 class Shell
 {
 public:
+    typedef std::set<std::string> Whitelist;
+
     Shell(const char* file = nullptr, bool load_defaults = false);
     ~Shell();
 
@@ -54,9 +58,33 @@ public:
     bool get_loaded() const
     { return loaded; }
 
+public:
+    static bool is_whitelisted(const std::string& key);
+    static void whitelist_append(const char* keyword, bool is_prefix);
+
 private:
     [[noreturn]] static int panic(lua_State*);
+    static Shell* get_current_shell();
+
+private:
     static std::string fatal;
+    static std::stack<Shell*> current_shells;
+
+private:
+    void clear_whitelist()
+    {
+        whitelist.clear();
+        whitelist_prefixes.clear();
+    }
+
+    const Whitelist& get_whitelist() const
+    { return whitelist; }
+
+    const Whitelist& get_whitelist_prefixes() const
+    { return whitelist_prefixes; }
+
+    void print_whitelist() const;
+    void whitelist_update(const char* keyword, bool is_prefix);
 
 private:
     bool loaded;
@@ -64,6 +92,8 @@ private:
     std::string file;
     std::string parse_from;
     std::string overrides;
+    Whitelist whitelist;
+    Whitelist whitelist_prefixes;
 };
 
 #endif
index 738b585abff4f240a81660e1367e0c4da7249d14..22ddc02e3938412301ff59f1c418127564b79319 100644 (file)
@@ -464,6 +464,9 @@ SnortConfig* Snort::get_reload_config(const char* fname)
         return nullptr;
     }
 
+    if ( SnortConfig::log_verbose() )
+        InspectorManager::print_config(sc);
+
     if ((sc->file_mask != 0) && (sc->file_mask != SnortConfig::get_conf()->file_mask))
         umask(sc->file_mask);
 
index 9720f301799e886c99822ce1b66df545ecf348dc..a6d5f750fc02226887aebdc7465af4667b2882c6 100644 (file)
@@ -539,6 +539,9 @@ static const Parameter s_params[] =
     { "--warn-conf", Parameter::PT_IMPLIED, nullptr, nullptr,
       "warn about configuration issues" },
 
+    { "--warn-conf-strict", Parameter::PT_IMPLIED, nullptr, nullptr,
+      "warn about unrecognized elements in configuration files" },
+
     { "--warn-daq", Parameter::PT_IMPLIED, nullptr, nullptr,
       "warn about DAQ issues, usually related to mode" },
 
@@ -1017,6 +1020,9 @@ bool SnortModule::set(const char*, Value& v, SnortConfig* sc)
     else if ( v.is("--warn-conf") )
         sc->warning_flags |= (1 << WARN_CONF);
 
+    else if ( v.is("--warn-conf-strict") )
+        sc->warning_flags |= (1 << WARN_CONF_STRICT);
+
     else if ( v.is("--warn-daq") )
         sc->warning_flags |= (1 << WARN_DAQ);
 
index b52dae63bdbf4ea5508c3f64ec1297ddb14643ba..854f509d405c2dd4c38e8e2397f4fbc611385408 100644 (file)
@@ -9,6 +9,7 @@ set (LUA_INCLUDES
 set (CPP_INCLUDES
     ${CMAKE_CURRENT_BINARY_DIR}/lua_bootstrap.h
     ${CMAKE_CURRENT_BINARY_DIR}/lua_coreinit.h
+    ${CMAKE_CURRENT_BINARY_DIR}/lua_finalize.h
 )
 
 set( MANAGERS_INCLUDES
@@ -53,11 +54,19 @@ add_custom_command (
     OUTPUT lua_bootstrap.h snort_config.lua
     COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/lua_wrap.sh ${CMAKE_CURRENT_SOURCE_DIR} bootstrap > lua_bootstrap.h
     COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/bootstrap.lua ${CMAKE_CURRENT_BINARY_DIR}/snort_config.lua
+    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/bootstrap.lua
+)
+
+add_custom_command (
+    OUTPUT lua_finalize.h
+    COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/lua_wrap.sh ${CMAKE_CURRENT_SOURCE_DIR} finalize > lua_finalize.h
+    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/finalize.lua
 )
 
 add_custom_command (
     OUTPUT lua_coreinit.h
     COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/lua_wrap.sh ${CMAKE_CURRENT_SOURCE_DIR} coreinit > lua_coreinit.h
+    DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/coreinit.lua
 )
 
 include_directories (${CMAKE_CURRENT_BINARY_DIR})
index 902d4bd8cc7c675feaf76aec3cd70dcbbeca45a6..17b20ea0ea77f4b12240fda18dfe4890627e9933 100644 (file)
@@ -15,7 +15,7 @@
 -- with this program; if not, write to the Free Software Foundation, Inc.,
 -- 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 ---------------------------------------------------------------------------
--- snort_config.lua author Russ Combs <rucombs@cisco.com>
+-- bootstrap.lua author Russ Combs <rucombs@cisco.com>
 
 ---------------------------------------------------------------------------
 -- Snort uses this to configure Lua settings into C++
 ffi = require("ffi")
 
 ffi.cdef[[
-bool open_table(const char*, int);
-void close_table(const char*, int);
-bool set_bool(const char*, bool);
-bool set_number(const char*, double);
-bool set_string(const char*, const char*);
-bool set_alias(const char*, const char*);
 const char* push_include_path(const char*);
 void pop_include_path();
+void snort_whitelist_append(const char*);
+void snort_whitelist_add_prefix(const char*);
 ]]
 
-function snort_traverse(tab, fqn)
-    local key, val
-
-    for key,val in pairs(tab) do
-        -- skip Lua reserved symbols
-        if ( string.sub(key, 1, 1) ~= '_' ) then
-            if ( type(val) == 'string' ) then
-                snort_set(fqn, key, val)
-            end
-        end
-    end
-
-    for key,val in pairs(tab) do
-        -- skip Lua reserved symbols
-        if ( string.sub(key, 1, 1) ~= '_' ) then
-            if ( type(val) ~= 'string' ) then
-                snort_set(fqn, key, val)
+function whitelist_append(list, is_prefix)
+    for w in list:gmatch("%S+") do
+        if ( type(w) == 'string' ) then
+            if ( w:match('^%a') ~= nil ) then
+                if ( is_prefix ) then
+                    ffi.C.snort_whitelist_add_prefix(w)
+                else
+                    ffi.C.snort_whitelist_append(w)
+                end
             end
         end
     end
 end
 
-function snort_set(fqn, key, val)
-    local name
-    local idx = 0
-    local what = type(val)
-
-    if ( not fqn ) then
-        name = key
-
-    elseif ( type(key) == 'number' ) then
-        name = fqn
-        idx = key
-
-    else
-        name = fqn .. '.' .. key
-    end
-
-    if ( what == 'boolean' ) then
-        ffi.C.set_bool(name, val)
-
-    elseif ( what == 'number' ) then
-        ffi.C.set_number(name, val)
-
-    elseif ( what == 'string' ) then
-        ffi.C.set_string(name, val)
-
-    elseif ( what == 'table' ) then
-        if ( ffi.C.open_table(name, idx) ) then
-            snort_traverse(val, name)
-            ffi.C.close_table(name, idx)
-        end
-    end
+function snort_whitelist_append(list)
+    whitelist_append(list, false)
 end
 
-function load_aliases()
-    for i,v in ipairs(binder) do
-        if ( v.use and type(v.use) == "table" ) then
-            if ( v.use.name and v.use.type ) then
-                ffi.C.set_alias(v.use.name, v.use.type)
-                tab = _G[v.use.name]
+function snort_whitelist_add_prefix(list)
+    whitelist_append(list, true)
+end
 
-                if ( tab ) then
-                    snort_set(nil, v.use.name, _G[v.use.name])
-                end
+function initialize_whitelist(tab)
+    for key, val in pairs(tab) do
+        -- skip Lua reserved symbols
+        if ( string.sub(key, 1, 1) ~= '_' ) then
+            if ( type(val) == 'table' ) then
+                ffi.C.snort_whitelist_append(key)
             end
         end
     end
 end
 
-function snort_config(tab)
-    snort_traverse(tab)
-
-    if ( binder and type(binder) == 'table' ) then
-        load_aliases()
-    end
-end
-
 ---------------------------------------------------------------------------
 -- path magic for includes
 ---------------------------------------------------------------------------
@@ -150,3 +101,5 @@ function include(file)
     ffi.C.pop_include_path()
 end
 
+initialize_whitelist(_G)
+initialize_whitelist = nil
index e789eecf9ed373c7c1d089676fd6e6dd9a53c4d2..7990f94ed085d55908790447610e4e73987c3b7a 100644 (file)
@@ -14,7 +14,12 @@ Only the action, codec, and inspector managers have thread local state:
 Some Lua files are here as they are coupled closely with C++ code in this
 directory (module_manager.cc):
 
-* snort_config.lua provides the ability to parse a Lua configuration.  It
+* bootstrap.lua provides FFI for adding table names and prefixes to
+  snort's lua whitelist. This whitelist is used to ignore warnings
+  when snort modules are not found for table names. This file also
+  has the FFI used to resolve file includes in lua file.
+
+* finalize.lua provides the ability to parse a Lua configuration.  It
   is much easier to traverse the Lua tables via Lua itself.  This file
   leverages the LuaJIT FFI to open and close tables and set values.
 
diff --git a/src/managers/finalize.lua b/src/managers/finalize.lua
new file mode 100644 (file)
index 0000000..d3dabb1
--- /dev/null
@@ -0,0 +1,111 @@
+---------------------------------------------------------------------------
+-- Copyright (C) 2014-2020 Cisco and/or its affiliates. All rights reserved.
+--
+-- This program is free software; you can redistribute it and/or modify it
+-- under the terms of the GNU General Public License Version 2 as published
+-- by the Free Software Foundation.  You may not use, modify or distribute
+-- this program under any other version of the GNU General Public License.
+--
+-- 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
+-- General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License along
+-- with this program; if not, write to the Free Software Foundation, Inc.,
+-- 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+---------------------------------------------------------------------------
+-- finalize.lua author Russ Combs <rucombs@cisco.com>
+
+---------------------------------------------------------------------------
+-- Snort uses this to configure Lua settings into C++
+---------------------------------------------------------------------------
+
+ffi = require("ffi")
+
+ffi.cdef[[
+bool open_table(const char*, int);
+void close_table(const char*, int);
+bool set_bool(const char*, bool);
+bool set_number(const char*, double);
+bool set_string(const char*, const char*);
+bool set_alias(const char*, const char*);
+]]
+
+function snort_traverse(tab, fqn)
+    for key,val in pairs(tab) do
+        -- skip Lua reserved symbols
+        if ( string.sub(key, 1, 1) ~= '_' ) then
+            if ( type(val) == 'string' ) then
+                snort_set(fqn, key, val)
+            end
+        end
+    end
+
+    for key,val in pairs(tab) do
+        -- skip Lua reserved symbols
+        if ( string.sub(key, 1, 1) ~= '_' ) then
+            if ( type(val) ~= 'string' ) then
+                snort_set(fqn, key, val)
+            end
+        end
+    end
+end
+
+function snort_set(fqn, key, val)
+    local name
+    local idx = 0
+    local what = type(val)
+
+    if ( not fqn ) then
+        name = key
+
+    elseif ( type(key) == 'number' ) then
+        name = fqn
+        idx = key
+
+    else
+        name = fqn .. '.' .. key
+    end
+
+    if ( what == 'boolean' ) then
+        ffi.C.set_bool(name, val)
+
+    elseif ( what == 'number' ) then
+        ffi.C.set_number(name, val)
+
+    elseif ( what == 'string' ) then
+        ffi.C.set_string(name, val)
+
+    elseif ( what == 'table' ) then
+        if ( ffi.C.open_table(name, idx) ) then
+            snort_traverse(val, name)
+            ffi.C.close_table(name, idx)
+        end
+    end
+end
+
+function load_aliases()
+    for i,v in ipairs(binder) do
+        if ( v.use and type(v.use) == "table" ) then
+            if ( v.use.name and v.use.type ) then
+                ffi.C.set_alias(v.use.name, v.use.type)
+                local tab = _G[v.use.name]
+
+                if ( tab ) then
+                    snort_whitelist_append(v.use.name)
+                    snort_set(nil, v.use.name, _G[v.use.name])
+                end
+            end
+        end
+    end
+end
+
+function snort_config(tab)
+    if ( binder and type(binder) == 'table' ) then
+        load_aliases()
+    end
+    snort_traverse(tab)
+end
+
+snort_config(_G)
index 5cc1edf30f1424f41ea2c8137e59ca91d9f598fd..1b66efe7ab6f9b035fbee52d6c3ac55611c30d28 100644 (file)
@@ -53,6 +53,7 @@
 // "Lua" includes
 #include "lua_bootstrap.h"
 #include "lua_coreinit.h"
+#include "lua_finalize.h"
 
 using namespace snort;
 using namespace std;
@@ -98,6 +99,8 @@ extern "C"
 
     const char* push_include_path(const char* file);
     void pop_include_path();
+    void snort_whitelist_append(const char*);
+    void snort_whitelist_add_prefix(const char*);
 }
 
 //-------------------------------------------------------------------------
@@ -107,6 +110,9 @@ extern "C"
 const char* ModuleManager::get_lua_bootstrap()
 { return lua_bootstrap; }
 
+const char* ModuleManager::get_lua_finalize()
+{ return lua_finalize; }
+
 const char* ModuleManager::get_lua_coreinit()
 { return lua_coreinit; }
 
@@ -705,6 +711,16 @@ SO_PUBLIC bool set_alias(const char* from, const char* to)
     return true;
 }
 
+SO_PUBLIC void snort_whitelist_append(const char* s)
+{
+    Shell::whitelist_append(s, false);
+}
+
+SO_PUBLIC void snort_whitelist_add_prefix(const char* s)
+{
+    Shell::whitelist_append(s, true);
+}
+
 SO_PUBLIC bool open_table(const char* s, int idx)
 {
     const char* orig = s;
@@ -721,7 +737,11 @@ SO_PUBLIC bool open_table(const char* s, int idx)
     ModHook* h = get_hook(key.c_str());
 
     if ( !h || (h->api && h->api->type == PT_IPS_OPTION) )
+    {
+        if ( !Shell::is_whitelisted(key) )
+            ParseWarning(WARN_CONF_STRICT, "unknown table %s", key.c_str());
         return false;
+    }
 
     // FIXIT-M only basic modules, inspectors and ips actions can be reloaded at present
     if ( ( Snort::is_reloading() ) and h->api
index ce82b05e9532166632464f0cbead50310f97362c..46facfecddc65477e2902c1ecc1c0891e019ae75 100644 (file)
@@ -51,6 +51,7 @@ public:
     SO_PUBLIC static std::list<Module*> get_all_modules();
 
     static const char* get_lua_bootstrap();
+    static const char* get_lua_finalize();
     static const char* get_lua_coreinit();
 
     static void list_modules(const char* = nullptr);