From: Ron Dempster (rdempste) Date: Thu, 24 Mar 2022 17:58:44 +0000 (+0000) Subject: Pull request #3319: control, shell: add a command to set the network policy to be... X-Git-Tag: 3.1.27.0~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=be7b11c94bb4d2e232e4c07c3f7231269bb49c09;p=thirdparty%2Fsnort3.git Pull request #3319: control, shell: add a command to set the network policy to be used by subsequent commands Merge in SNORT/snort3 from ~RDEMPSTE/snort3:command to master Squashed commit of the following: commit 3c3f144b75ada597b83130c7ce1613934d77b0ff Author: Ron Dempster (rdempste) Date: Mon Mar 14 08:18:08 2022 -0400 control, shell: add a command to set the network policy to be used by subsequent commands --- diff --git a/src/control/control.cc b/src/control/control.cc index ff4964a91..cfe7cfe41 100644 --- a/src/control/control.cc +++ b/src/control/control.cc @@ -120,6 +120,9 @@ int ControlConn::read_commands() return commands_found; } +void ControlConn::set_user_network_policy() +{ shell->set_user_network_policy(); } + int ControlConn::execute_commands() { int executed = 0; diff --git a/src/control/control.h b/src/control/control.h index a211b46a5..993986ac9 100644 --- a/src/control/control.h +++ b/src/control/control.h @@ -60,6 +60,8 @@ public: int execute_commands(); void shutdown(); + void set_user_network_policy(); + SO_PUBLIC bool is_local() const { return local; } SO_PUBLIC bool respond(const char* format, va_list& ap); SO_PUBLIC bool respond(const char* format, ...) __attribute__((format (printf, 2, 3))); diff --git a/src/main/CMakeLists.txt b/src/main/CMakeLists.txt index ebcd871db..da6580c96 100644 --- a/src/main/CMakeLists.txt +++ b/src/main/CMakeLists.txt @@ -32,6 +32,8 @@ add_library (main OBJECT help.h modules.cc modules.h + network_module.cc + network_module.h oops_handler.cc oops_handler.h policy.cc diff --git a/src/main/ac_shell_cmd.cc b/src/main/ac_shell_cmd.cc index 89b2ce111..ce0ca4851 100644 --- a/src/main/ac_shell_cmd.cc +++ b/src/main/ac_shell_cmd.cc @@ -37,6 +37,7 @@ ACShellCmd::ACShellCmd(ControlConn* conn, AnalyzerCommand* ac) : AnalyzerCommand bool ACShellCmd::execute(Analyzer& analyzer, void** state) { + ctrlcon->set_user_network_policy(); return ac->execute(analyzer, state); } diff --git a/src/main/modules.cc b/src/main/modules.cc index 3fb387d60..a2d134786 100644 --- a/src/main/modules.cc +++ b/src/main/modules.cc @@ -65,6 +65,7 @@ #include "target_based/snort_protocols.h" #include "trace/trace_module.h" +#include "network_module.h" #include "snort_config.h" #include "snort_module.h" #include "thread_config.h" @@ -1007,88 +1008,6 @@ bool AttributeTableModule::set(const char*, Value& v, SnortConfig* sc) return true; } -//------------------------------------------------------------------------- -// network module -//------------------------------------------------------------------------- - -static const Parameter network_params[] = -{ - { "checksum_drop", Parameter::PT_MULTI, - "all | ip | noip | tcp | notcp | udp | noudp | icmp | noicmp | none", "none", - "drop if checksum is bad" }, - - { "checksum_eval", Parameter::PT_MULTI, - "all | ip | noip | tcp | notcp | udp | noudp | icmp | noicmp | none", "all", - "checksums to verify" }, - - { "id", Parameter::PT_INT, "0:65535", "0", - "correlate unified2 events with configuration" }, - - { "min_ttl", Parameter::PT_INT, "1:255", "1", - "alert / normalize packets with lower TTL / hop limit " - "(you must enable rules and / or normalization also)" }, - - { "new_ttl", Parameter::PT_INT, "1:255", "1", - "use this value for responses and when normalizing" }, - - { "layers", Parameter::PT_INT, "3:255", "40", - "the maximum number of protocols that Snort can correctly decode" }, - - { "max_ip6_extensions", Parameter::PT_INT, "0:255", "0", - "the maximum number of IP6 options Snort will process for a given IPv6 layer " - "before raising 116:456 (0 = unlimited)" }, - - { "max_ip_layers", Parameter::PT_INT, "0:255", "0", - "the maximum number of IP layers Snort will process for a given packet " - "before raising 116:293 (0 = unlimited)" }, - - { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } -}; - -#define network_help \ - "configure basic network parameters" - -class NetworkModule : public Module -{ -public: - NetworkModule() : Module("network", network_help, network_params) { } - bool set(const char*, Value&, SnortConfig*) override; - - Usage get_usage() const override - { return CONTEXT; } -}; - -bool NetworkModule::set(const char*, Value& v, SnortConfig* sc) -{ - NetworkPolicy* p = get_network_policy(); - - if ( v.is("checksum_drop") ) - ConfigChecksumDrop(v.get_string()); - - else if ( v.is("checksum_eval") ) - ConfigChecksumMode(v.get_string()); - - else if ( v.is("id") ) - p->user_policy_id = v.get_uint16(); - - else if ( v.is("min_ttl") ) - p->min_ttl = v.get_uint8(); - - else if ( v.is("new_ttl") ) - p->new_ttl = v.get_uint8(); - - else if (v.is("layers")) - sc->num_layers = v.get_uint8(); - - else if (v.is("max_ip6_extensions")) - sc->max_ip6_extensions = v.get_uint8(); - - else if (v.is("max_ip_layers")) - sc->max_ip_layers = v.get_uint8(); - - return true; -} - //------------------------------------------------------------------------- // inspection policy module //------------------------------------------------------------------------- diff --git a/src/main/network_module.cc b/src/main/network_module.cc new file mode 100644 index 000000000..b8d53a2d5 --- /dev/null +++ b/src/main/network_module.cc @@ -0,0 +1,128 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2014-2022 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. +//-------------------------------------------------------------------------- + +// network_module.cc author Ron Dempster + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "network_module.h" + +#include + +#include "main/policy.h" +#include "main/shell.h" +#include "main/snort_config.h" +#include "parser/config_file.h" + +using namespace snort; + +static const Parameter network_params[] = +{ + { "checksum_drop", Parameter::PT_MULTI, + "all | ip | noip | tcp | notcp | udp | noudp | icmp | noicmp | none", "none", + "drop if checksum is bad" }, + + { "checksum_eval", Parameter::PT_MULTI, + "all | ip | noip | tcp | notcp | udp | noudp | icmp | noicmp | none", "all", + "checksums to verify" }, + + { "id", Parameter::PT_INT, "0:65535", "0", + "correlate unified2 events with configuration" }, + + { "min_ttl", Parameter::PT_INT, "1:255", "1", + "alert / normalize packets with lower TTL / hop limit " + "(you must enable rules and / or normalization also)" }, + + { "new_ttl", Parameter::PT_INT, "1:255", "1", + "use this value for responses and when normalizing" }, + + { "layers", Parameter::PT_INT, "3:255", "40", + "the maximum number of protocols that Snort can correctly decode" }, + + { "max_ip6_extensions", Parameter::PT_INT, "0:255", "0", + "the maximum number of IP6 options Snort will process for a given IPv6 layer " + "before raising 116:456 (0 = unlimited)" }, + + { "max_ip_layers", Parameter::PT_INT, "0:255", "0", + "the maximum number of IP layers Snort will process for a given packet " + "before raising 116:293 (0 = unlimited)" }, + + { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr } +}; + +#define network_help "configure basic network parameters" + +static int network_set_policy(lua_State* L) +{ + int user_id = luaL_optint(L, 1, 0); + Shell::set_network_policy_user_id(L, user_id); + return 0; +} + +const Parameter network_set_policy_params[] = +{ + {"id", Parameter::PT_INT, "0:65535", 0, "user network policy id"}, + {nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr} +}; + +const Command network_cmds[] = +{ + {"set_policy", network_set_policy, network_set_policy_params, + "set the network policy for commands given the user policy id"}, + {nullptr, nullptr, nullptr, nullptr} +}; + +NetworkModule::NetworkModule() : snort::Module("network", network_help, network_params) +{ } + +const Command* NetworkModule::get_commands() const +{ return network_cmds; } + +bool NetworkModule::set(const char*, Value& v, SnortConfig* sc) +{ + NetworkPolicy* p = get_network_policy(); + + if ( v.is("checksum_drop") ) + ConfigChecksumDrop(v.get_string()); + + else if ( v.is("checksum_eval") ) + ConfigChecksumMode(v.get_string()); + + else if ( v.is("id") ) + p->user_policy_id = v.get_uint16(); + + else if ( v.is("min_ttl") ) + p->min_ttl = v.get_uint8(); + + else if ( v.is("new_ttl") ) + p->new_ttl = v.get_uint8(); + + else if (v.is("layers")) + sc->num_layers = v.get_uint8(); + + else if (v.is("max_ip6_extensions")) + sc->max_ip6_extensions = v.get_uint8(); + + else if (v.is("max_ip_layers")) + sc->max_ip_layers = v.get_uint8(); + + return true; +} + diff --git a/src/main/network_module.h b/src/main/network_module.h new file mode 100644 index 000000000..403e56822 --- /dev/null +++ b/src/main/network_module.h @@ -0,0 +1,40 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2014-2022 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. +//-------------------------------------------------------------------------- + +// network_module.cc author Ron Dempster + +#ifndef NETWORK_MODULE_H +#define NETWORK_MODULE_H + +#include "framework/module.h" + + +class NetworkModule : public snort::Module +{ +public: + NetworkModule(); + ~NetworkModule() override = default; + bool set(const char*, snort::Value&, snort::SnortConfig*) override; + + const snort::Command* get_commands() const override; + + Usage get_usage() const override + { return CONTEXT; } +}; + +#endif diff --git a/src/main/policy.h b/src/main/policy.h index 5956e2ff7..c38a0f049 100644 --- a/src/main/policy.h +++ b/src/main/policy.h @@ -55,6 +55,8 @@ struct PortTable; struct vartable_t; struct sfip_var_t; +#define UNDEFINED_USER_POLICY_ID 65536 + typedef unsigned int PolicyId; typedef snort::GHash PortVarTable; diff --git a/src/main/shell.cc b/src/main/shell.cc index 4807f5b85..5d56c5625 100644 --- a/src/main/shell.cc +++ b/src/main/shell.cc @@ -91,6 +91,8 @@ BaseConfigNode* Shell::s_current_node = nullptr; bool Shell::s_close_table = true; string Shell::lua_sandbox; +const char* const Shell::lua_shell_id = "the_shell"; + // 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. :( @@ -441,6 +443,9 @@ Shell::Shell(const char* s, bool load_defaults) : loaded = false; load_string(lua_bootstrap, false, "bootstrap"); install_version_strings(lua); + Shell** shell_ud = static_cast(lua_newuserdata(lua, sizeof(Shell*))); + *(shell_ud) = this; + lua_setglobal(lua, lua_shell_id); bootstrapped = true; current_shells.pop(); @@ -563,6 +568,24 @@ void Shell::install(const char* name, const luaL_Reg* reg) luaL_register(lua, name, reg); } +void Shell::set_network_policy_user_id(lua_State* L, uint32_t user_id) +{ + lua_getglobal(L, lua_shell_id); + Shell* shell = *static_cast(lua_touserdata(L, -1)); + lua_pop(L, 1); + shell->network_user_policy_id = user_id; +} + +void Shell::set_user_network_policy() +{ + if (UNDEFINED_USER_POLICY_ID > network_user_policy_id) + { + NetworkPolicy* np = + SnortConfig::get_conf()->policy_map->get_user_network(network_user_policy_id); + set_network_policy(np); + } +} + void Shell::execute(const char* cmd, string& rsp) { set_default_policy(SnortConfig::get_conf()); @@ -575,7 +598,10 @@ void Shell::execute(const char* cmd, string& rsp) err = luaL_loadbuffer(lua, cmd, strlen(cmd), "shell"); if ( !err ) + { + set_user_network_policy(); err = lua_pcall(lua, 0, 0, 0); + } } catch (...) { diff --git a/src/main/shell.h b/src/main/shell.h index a4a329304..07d534b3b 100644 --- a/src/main/shell.h +++ b/src/main/shell.h @@ -29,6 +29,7 @@ #include "dump_config/config_data.h" #include "framework/parameter.h" +#include "policy.h" struct lua_State; @@ -69,6 +70,8 @@ public: lua_State* get_lua() const { return lua; } + void set_user_network_policy(); + public: static bool is_trusted(const std::string& key); static void allowlist_append(const char* keyword, bool is_prefix); @@ -86,6 +89,8 @@ public: static void set_lua_sandbox(const char* s) { lua_sandbox = s; } + static void set_network_policy_user_id(lua_State*, uint32_t user_id); + private: static void add_config_root_node(const std::string& root_name, snort::Parameter::Type type); @@ -100,6 +105,7 @@ private: static BaseConfigNode* s_current_node; static bool s_close_table; static std::string lua_sandbox; + static const char* const lua_shell_id; private: void clear_allowlist() @@ -137,6 +143,7 @@ private: Allowlist internal_allowlist; Allowlist allowlist_prefixes; ConfigData config_data; + uint32_t network_user_policy_id = UNDEFINED_USER_POLICY_ID; bool load_defaults; }; diff --git a/src/managers/inspector_manager.cc b/src/managers/inspector_manager.cc index 9c0307242..6db5bff7b 100644 --- a/src/managers/inspector_manager.cc +++ b/src/managers/inspector_manager.cc @@ -1285,14 +1285,20 @@ Inspector* InspectorManager::get_inspector(const char* key, Module::Usage usage, } else if (Module::CONTEXT == usage) { - TrafficPolicy* il = get_network_policy()->traffic_policy; + NetworkPolicy* np = get_network_policy(); + if (!np) + return nullptr; + TrafficPolicy* il = np->traffic_policy; assert(il); PHInstance* p = il->get_instance_by_type(key, type); return p ? p->handler : nullptr; } else { - FrameworkPolicy* il = get_inspection_policy()->framework_policy; + InspectionPolicy* ip = get_inspection_policy(); + if (!ip) + return nullptr; + FrameworkPolicy* il = ip->framework_policy; assert(il); PHInstance* p = il->get_instance_by_type(key, type); return p ? p->handler : nullptr; @@ -1326,8 +1332,11 @@ Inspector* InspectorManager::get_service_inspector_by_id(const SnortProtocolId p bool InspectorManager::delete_inspector(SnortConfig* sc, const char* iname) { + NetworkPolicy* np = get_network_policy(); + if (!np) + return false; FrameworkPolicy* fp = - sc->policy_map->get_network_policy(0)->get_inspection_policy()->framework_policy; + np->get_inspection_policy()->framework_policy; return fp->delete_inspector(sc, iname); }