]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #3205: Move global inspectors and selectors to the policy map
authorRon Dempster (rdempste) <rdempste@cisco.com>
Thu, 13 Jan 2022 14:29:13 +0000 (14:29 +0000)
committerRon Dempster (rdempste) <rdempste@cisco.com>
Thu, 13 Jan 2022 14:29:13 +0000 (14:29 +0000)
Merge in SNORT/snort3 from ~RDEMPSTE/snort3:global to master

Squashed commit of the following:

commit 3e62d9c7bf8bfaddb89e9b9419efd08d78a9a7bb
Author: Ron Dempster (rdempste) <rdempste@cisco.com>
Date:   Tue Dec 7 11:06:41 2021 -0500

    policy: add a file_policy to the network policy and use it

commit 0b136c2654fa7d4ffadcb5ad3b080e723bc43bc2
Author: Ron Dempster (rdempste) <rdempste@cisco.com>
Date:   Fri Dec 3 16:19:22 2021 -0500

    main: move policy selector and flow tracking from snort config to policy map

commit 69d9c2d07434a6ebe0968231f9ad503b43a0a1f4
Author: Ron Dempster (rdempste) <rdempste@cisco.com>
Date:   Fri Dec 3 16:18:11 2021 -0500

    main: only add policies to the user policy map at the end of table processing

commit 20377e6bd1f74bbe37c615ce4b4aacf3c401c8c7
Author: Ron Dempster (rdempste) <rdempste@cisco.com>
Date:   Fri Dec 3 16:16:04 2021 -0500

    control: fix macro definitions

35 files changed:
lua/max_detect.lua
lua/security.lua
lua/snort.lua
src/control/control.h
src/file_api/CMakeLists.txt
src/file_api/file_api.cc [new file with mode: 0644]
src/file_api/file_api.h
src/file_api/file_config.cc
src/file_api/file_config.h
src/file_api/file_flows.cc
src/file_api/file_flows.h
src/file_api/file_lib.cc
src/file_api/file_module.cc
src/file_api/file_module.h
src/file_api/file_service.h
src/framework/CMakeLists.txt
src/framework/file_policy.cc [moved from src/file_api/file_policy.cc with 97% similarity]
src/framework/file_policy.h [moved from src/file_api/file_policy.h with 98% similarity]
src/framework/inspector.cc
src/framework/inspector.h
src/framework/module.cc
src/framework/policy_selector.h
src/log/log.cc
src/main/help.cc
src/main/modules.cc
src/main/policy.cc
src/main/policy.h
src/main/snort_config.cc
src/main/snort_config.h
src/managers/inspector_manager.cc
src/managers/inspector_manager.h
src/managers/policy_selector_manager.cc
src/network_inspectors/appid/appid_api.cc
src/service_inspectors/http2_inspect/http2_data_cutter.cc
tools/snort2lua/config_states/config_file.cc

index 19a8c57514ecaa3f063dac0536347f4bed226cca..418f45519f77e0a74eb81077656d6b63eb8984eb 100644 (file)
@@ -6,9 +6,6 @@
 
 arp_spoof = nil
 
--- bug: false will limit http file_data
-file_id.enable_signature = true
-
 ftp_server.check_encrypted = true
 
 detection =
index 3a046c44acd3bab40c7dc920d91d7cddf0b46ecd..c2613d94f7947bc537626634a2ab9e630b9a84d9 100644 (file)
@@ -5,9 +5,6 @@
 
 arp_spoof = nil
 
--- bug: false will limit http file_data
-file_id.enable_signature = true
-
 ftp_server.check_encrypted = true
 
 detection =
index 7343bb0f7bdebb8f97d3926e25132a1f50596a76..3579a4d53f2bc01c6493a2ab9f4b368c582cc611 100644 (file)
@@ -86,6 +86,7 @@ http2_inspect = { }
 
 -- see file_magic.lua for file id rules
 file_id = { file_rules = file_magic }
+file_policy = { }
 
 -- the following require additional configuration to be fully effective:
 
index d6f271774d4d7bc6fe122d095d5850e627bbde4d..b797e483434998efb934d5de54a38677635b6893 100644 (file)
@@ -80,7 +80,7 @@ private:
     time_t touched;
 };
 
-#define LogRespond(cn, ...)       if (cn) cn->respond(__VA_ARGS__); else LogMessage(__VA_ARGS__)
-#define LogfRespond(cn, fh, ...)  if (cn) cn->respond(__VA_ARGS__); else LogMessage(fh, __VA_ARGS__)
+#define LogRespond(cn, ...)       do { if (cn) cn->respond(__VA_ARGS__); else LogMessage(__VA_ARGS__); } while(0)
+#define LogfRespond(cn, fh, ...)  do { if (cn) cn->respond(__VA_ARGS__); else LogMessage(fh, __VA_ARGS__); } while(0)
 
 #endif
index 2eddff6991132195ed9241080a76a254452150b9..32fa5969d6c59879b758ad71117529df4caca2cb 100644 (file)
@@ -7,7 +7,6 @@ set( FILE_API_INCLUDES
     file_identifier.h
     file_lib.h
     file_module.h
-    file_policy.h
     file_segment.h
     file_service.h
 )
@@ -16,6 +15,7 @@ add_library ( file_api OBJECT
     ${FILE_API_INCLUDES}
     circular_buffer.cc
     circular_buffer.h
+    file_api.cc
     file_capture.cc
     file_cache.cc
     file_cache.h
@@ -27,7 +27,6 @@ add_library ( file_api OBJECT
     file_mempool.cc
     file_mempool.h
     file_module.cc
-    file_policy.cc
     file_segment.cc
     file_service.cc
     file_stats.cc
diff --git a/src/file_api/file_api.cc b/src/file_api/file_api.cc
new file mode 100644 (file)
index 0000000..b644a79
--- /dev/null
@@ -0,0 +1,43 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2021-2021 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.
+//--------------------------------------------------------------------------
+// file_api.cc author Ron Dempster <rdempste@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "file_api/file_api.h"
+
+using namespace snort;
+
+FilePolicyBase::FilePolicyBase()
+{ ref_count = 1; }
+
+FilePolicyBase::~FilePolicyBase()
+{ assert(!ref_count); }
+
+void FilePolicyBase::delete_file_policy(FilePolicyBase* policy)
+{
+    if (policy)
+    {
+        assert(policy->ref_count);
+        unsigned ref = --policy->ref_count;
+        if (!ref)
+            delete policy;
+    }
+}
index d7d1c87b7d65fa38077e9d31927beb7c6f490255..991a0d9241f1c7dcd08f097f58f9ac0eb236cdee 100644 (file)
@@ -26,6 +26,7 @@
 // Currently, it provides three sets of APIs: file processing, MIME processing,
 // and configurations.
 
+#include <atomic>
 #include <bitset>
 #include <cstring>
 #include <string>
@@ -138,8 +139,8 @@ class SO_PUBLIC FilePolicyBase
 {
 public:
 
-    FilePolicyBase() = default;
-    virtual ~FilePolicyBase() = default;
+    FilePolicyBase();
+    virtual ~FilePolicyBase();
 
     // This is called when a new flow is queried for the first time
     // Check & update what file policy is enabled on this flow/file
@@ -154,6 +155,14 @@ public:
     { return FILE_VERDICT_UNKNOWN; }
 
     virtual void log_file_action(Flow*, FileInfo*, FileAction) { }
+
+    void add_ref()
+    { ++ref_count; }
+
+    SO_PUBLIC static void delete_file_policy(FilePolicyBase*);
+
+private:
+    std::atomic_uint ref_count;
 };
 
 inline void initFilePosition(FilePosition* position, uint64_t processed_size)
index 81d5c869ccae826e19c6b9a7dbe8a4f979e44005..3170dc9fdc26388e8f2e33e0bb705106cfbf8c09 100644 (file)
@@ -63,11 +63,6 @@ void FileConfig::process_file_rule(FileMagicRule& rule)
     fileIdentifier.insert_file_rule(rule);
 }
 
-void FileConfig::process_file_policy_rule(FileRule& rule)
-{
-    filePolicy.insert_file_rule(rule);
-}
-
 const FileMagicRule* FileConfig::get_rule_from_id(uint32_t id) const
 {
     return fileIdentifier.get_rule_from_id(id);
@@ -109,7 +104,7 @@ FileConfig* get_file_config(const SnortConfig* sc)
     if ( !sc )
         sc = SnortConfig::get_conf();
 
-    FileInspect* fi = (FileInspect*)InspectorManager::get_inspector(FILE_ID_NAME, true, sc);
+    FileInspect* fi = (FileInspect*)InspectorManager::get_file_inspector(sc);
 
     if (fi)
         return (fi->config);
index 3e380da2d5d3b959e3e92eb8a388c524e4b204be..bb3f4ca7d345cb6dfa411fc834590cfa53cd6c43 100644 (file)
@@ -25,7 +25,6 @@
 // This provides the basic configuration for file processing
 #include "main/snort_config.h"
 #include "file_api/file_identifier.h"
-#include "file_api/file_policy.h"
 
 #define DEFAULT_FILE_TYPE_DEPTH 1460
 #define DEFAULT_FILE_SIGNATURE_DEPTH 10485760 /*10 Mbytes*/
@@ -49,11 +48,8 @@ public:
     void get_magic_rule_ids_from_type(const std::string&, const std::string&,
         snort::FileTypeBitSet&) const;
     void process_file_rule(FileMagicRule&);
-    void process_file_policy_rule(FileRule&);
     bool process_file_magic(FileMagicData&);
     uint32_t find_file_type_id(const uint8_t* buf, int len, uint64_t file_offset, void** context);
-    FilePolicy& get_file_policy() { return filePolicy; }
-    const FilePolicy& get_file_policy() const { return filePolicy; }
     std::string file_type_name(uint32_t id) const;
 
     int64_t file_type_depth = DEFAULT_FILE_TYPE_DEPTH;
@@ -73,11 +69,9 @@ public:
     bool trace_type = false;
     bool trace_signature = false;
     bool trace_stream = false;
-    int64_t verdict_delay = 0;
 
 private:
     FileIdentifier fileIdentifier;
-    FilePolicy filePolicy;
 };
 
 std::string file_type_name(uint32_t id);
index e01bb21cae2f4309deb19a7d58bd8cad3ef15809..ad4387df38df8d541a9339a90537163d19fe8932 100644 (file)
@@ -136,14 +136,13 @@ FileFlows* FileFlows::get_file_flows(Flow* flow, bool to_create)
     if (!to_create or fd)
         return fd;
 
-    FileInspect* fi = (FileInspect*)InspectorManager::get_inspector(FILE_ID_NAME, true);
+    FileInspect* fi = (FileInspect*)InspectorManager::get_file_inspector();
 
     if (FileService::is_file_service_enabled() and fi)
     {
         fd = new FileFlows(flow, fi);
         flow->set_flow_data(fd);
-        if (fi->config)
-            fd->set_file_policy(&(fi->config->get_file_policy()));
+        fd->set_file_policy(get_network_policy()->get_base_file_policy());
     }
 
     return fd;
@@ -223,6 +222,8 @@ FileFlows::~FileFlows()
     {
         delete elem.second;
     }
+
+    FilePolicyBase::delete_file_policy(file_policy);
 }
 
 FileContext* FileFlows::find_main_file_context(FilePosition pos, FileDirection dir, size_t index)
@@ -297,7 +298,7 @@ FileContext* FileFlows::get_file_context(
             context = new FileContext;
             partially_processed_contexts[multi_file_processing_id] = context;
             FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL, GET_CURRENT_PACKET,
-                "get_file_context:creating new context\n"); 
+                "get_file_context:creating new context\n");
             if (partially_processed_contexts.size() > file_counts.max_concurrent_files_per_flow)
                 file_counts.max_concurrent_files_per_flow = partially_processed_contexts.size();
         }
@@ -352,7 +353,7 @@ bool FileFlows::file_process(Packet* p, uint64_t file_id, const uint8_t* file_da
     if ((file_depth < 0) or (offset > (uint64_t)file_depth))
     {
         FILE_DEBUG(file_trace , DEFAULT_TRACE_OPTION_ID, TRACE_ERROR_LEVEL, p,
-             "file depth less than zero or offset is more than file depth , returning\n"); 
+             "file depth less than zero or offset is more than file depth , returning\n");
         return false;
     }
 
@@ -418,7 +419,7 @@ bool FileFlows::file_process(Packet* p, uint64_t file_id, const uint8_t* file_da
         }
     }
 
-    FILE_DEBUG(file_trace , DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL, p, 
+    FILE_DEBUG(file_trace , DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL, p,
        "calling context process data_size %d, offset %lu, position %d\n",
         data_size, offset, position);
     continue_processing = context->process(p, file_data, data_size, offset, file_policy, position);
@@ -539,18 +540,16 @@ bool FileInspect::configure(SnortConfig*)
 
 static void file_config_show(const FileConfig* fc)
 {
-    const FilePolicy& fp = fc->get_file_policy();
-
-    if ( ConfigLogger::log_flag("enable_type", fp.get_file_type()) )
+    if ( ConfigLogger::log_flag("enable_type", FileService::is_file_type_id_enabled()) )
         ConfigLogger::log_value("type_depth", fc->file_type_depth);
 
-    if ( ConfigLogger::log_flag("enable_signature", fp.get_file_signature()) )
+    if ( ConfigLogger::log_flag("enable_signature", FileService::is_file_signature_enabled()) )
         ConfigLogger::log_value("signature_depth", fc->file_signature_depth);
 
     if ( ConfigLogger::log_flag("block_timeout_lookup", fc->block_timeout_lookup) )
         ConfigLogger::log_value("block_timeout", fc->file_block_timeout);
 
-    if ( ConfigLogger::log_flag("enable_capture", fp.get_file_capture()) )
+    if ( ConfigLogger::log_flag("enable_capture", FileService::is_file_capture_enabled()) )
     {
         ConfigLogger::log_value("capture_memcap", fc->capture_memcap);
         ConfigLogger::log_value("capture_max_size", fc->capture_max_size);
@@ -566,7 +565,6 @@ static void file_config_show(const FileConfig* fc)
     ConfigLogger::log_flag("trace_type", fc->trace_type);
     ConfigLogger::log_flag("trace_signature", fc->trace_signature);
     ConfigLogger::log_flag("trace_stream", fc->trace_stream);
-    ConfigLogger::log_value("verdict_delay", fc->verdict_delay);
 }
 
 void FileInspect::show(const SnortConfig*) const
@@ -615,7 +613,7 @@ static const InspectApi file_inspect_api =
         mod_ctor,
         mod_dtor
     },
-    IT_PASSIVE,
+    IT_FILE,
     PROTO_BIT__NONE,
     nullptr,
     "file",
index 6816453c10434c605948ac0efa630fd5c5a247f2..3656749afcebbc2d9d4b04dea763bb6f56a32bc6 100644 (file)
@@ -29,7 +29,6 @@
 
 #include "file_api.h"
 #include "file_module.h"
-#include "file_policy.h"
 
 #include <map>
 
@@ -103,7 +102,13 @@ public:
 
     static unsigned file_flow_data_id;
 
-    void set_file_policy(FilePolicyBase* fp) { file_policy = fp; }
+    void set_file_policy(FilePolicyBase* fp)
+    {
+        assert(fp);
+        FilePolicyBase::delete_file_policy(file_policy);
+        fp->add_ref();
+        file_policy = fp;
+    }
     FilePolicyBase* get_file_policy() { return file_policy; }
 
 private:
index 8e4604e076cc00d2805f2b130ced86283078e48e..5d31fba6b51e7ce26b5c7cd6b6f6a9519eca688f 100644 (file)
@@ -308,7 +308,7 @@ FileContext::FileContext ()
     file_signature_context = nullptr;
     file_capture = nullptr;
     file_segments = nullptr;
-    inspector = (FileInspect*)InspectorManager::acquire(FILE_ID_NAME, true);
+    inspector = (FileInspect*)InspectorManager::acquire_file_inspector();
     config = inspector->config;
 }
 
@@ -392,7 +392,7 @@ void FileContext::finish_signature_lookup(Packet* p, bool final_lookup, FilePoli
     if (get_file_sig_sha256())
     {
         verdict = policy->signature_lookup(p, this);
-        FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL, 
+        FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL,
             p, "finish signature lookup verdict %d\n", verdict);
         if ( verdict != FILE_VERDICT_UNKNOWN || final_lookup )
         {
@@ -543,7 +543,7 @@ bool FileContext::process(Packet* p, const uint8_t* file_data, int data_size,
     /* file signature calculation */
     if (is_file_signature_enabled())
     {
-        FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL, p, 
+        FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL, p,
             "file signature is enabled\n");
         if (!sha256)
             process_file_signature_sha256(file_data, data_size, position);
@@ -639,13 +639,13 @@ void FileContext::process_file_signature_sha256(const uint8_t* file_data, int da
 {
     if ((int64_t)processed_bytes + data_size > config->file_signature_depth)
     {
-        FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_INFO_LEVEL, GET_CURRENT_PACKET, 
+        FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_INFO_LEVEL, GET_CURRENT_PACKET,
             "process_file_signature_sha256:FILE_SIG_DEPTH_FAIL\n");
         file_state.sig_state = FILE_SIG_DEPTH_FAIL;
         return;
     }
 
-    FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL, GET_CURRENT_PACKET, 
+    FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL, GET_CURRENT_PACKET,
         "processing file signature position: %d sig state %d \n", position, file_state.sig_state);
     switch (position)
     {
@@ -654,7 +654,7 @@ void FileContext::process_file_signature_sha256(const uint8_t* file_data, int da
             file_signature_context = snort_calloc(sizeof(SHA256_CTX));
         SHA256_Init((SHA256_CTX*)file_signature_context);
         SHA256_Update((SHA256_CTX*)file_signature_context, file_data, data_size);
-        FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL, GET_CURRENT_PACKET, 
+        FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL, GET_CURRENT_PACKET,
             "position is start of file\n");
         if (file_state.sig_state == FILE_SIG_FLUSH)
         {
@@ -671,7 +671,7 @@ void FileContext::process_file_signature_sha256(const uint8_t* file_data, int da
         if (!file_signature_context)
             return;
         SHA256_Update((SHA256_CTX*)file_signature_context, file_data, data_size);
-        FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL, GET_CURRENT_PACKET, 
+        FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL, GET_CURRENT_PACKET,
             "position is middle of the file\n");
         if (file_state.sig_state == FILE_SIG_FLUSH)
         {
@@ -693,7 +693,7 @@ void FileContext::process_file_signature_sha256(const uint8_t* file_data, int da
         sha256 = new uint8_t[SHA256_HASH_SIZE];
         SHA256_Final(sha256, (SHA256_CTX*)file_signature_context);
         file_state.sig_state = FILE_SIG_DONE;
-        FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL, GET_CURRENT_PACKET, 
+        FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL, GET_CURRENT_PACKET,
             "position is end of the file\n");
         break;
 
@@ -705,7 +705,7 @@ void FileContext::process_file_signature_sha256(const uint8_t* file_data, int da
         sha256 = new uint8_t[SHA256_HASH_SIZE];
         SHA256_Final(sha256, (SHA256_CTX*)file_signature_context);
         file_state.sig_state = FILE_SIG_DONE;
-        FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL, GET_CURRENT_PACKET, 
+        FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL, GET_CURRENT_PACKET,
             "position is full file\n");
         break;
 
@@ -747,9 +747,9 @@ void FileContext::update_file_size(int data_size, FilePosition position)
 {
     processed_bytes += data_size;
 
-    FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL, 
-        GET_CURRENT_PACKET, 
-        "Updating file size of file_id %lu at position %d with processed_bytes %lu\n", 
+    FILE_DEBUG(file_trace, DEFAULT_TRACE_OPTION_ID, TRACE_DEBUG_LEVEL,
+        GET_CURRENT_PACKET,
+        "Updating file size of file_id %lu at position %d with processed_bytes %lu\n",
         file_id, position, processed_bytes);
     if ((position == SNORT_FILE_END)or (position == SNORT_FILE_FULL))
     {
index 931578a9c821c6042214cd508cd6ce5eb40b8d2a..49bb22d1b61beace04fb48ec043815bc660d967c 100644 (file)
@@ -82,48 +82,6 @@ static const Parameter file_rule_params[] =
     { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
 };
 
-// File policy
-static const Parameter file_when_params[] =
-{
-    // FIXIT-M when.policy_id should be an arbitrary string auto converted
-    // into index for binder matching and lookups
-    { "file_type_id", Parameter::PT_INT, "0:max32", "0",
-      "unique ID for file type in file magic rule" },
-
-    { "sha256", Parameter::PT_STRING, nullptr, nullptr,
-      "SHA 256" },
-
-    { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
-};
-
-static const Parameter file_use_params[] =
-{
-    { "verdict", Parameter::PT_ENUM, "unknown | log | stop | block | reset ", "unknown",
-      "what to do with matching traffic" },
-
-    { "enable_file_type", Parameter::PT_BOOL, nullptr, "false",
-      "true/false -> enable/disable file type identification" },
-
-    { "enable_file_signature", Parameter::PT_BOOL, nullptr, "false",
-      "true/false -> enable/disable file signature" },
-
-    { "enable_file_capture", Parameter::PT_BOOL, nullptr, "false",
-      "true/false -> enable/disable file capture" },
-
-    { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
-};
-
-static const Parameter file_policy_rule_params[] =
-{
-    { "when", Parameter::PT_TABLE, file_when_params, nullptr,
-      "match criteria" },
-
-    { "use", Parameter::PT_TABLE, file_use_params, nullptr,
-      "target configuration" },
-
-    { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
-};
-
 static const Parameter file_id_params[] =
 {
     { "type_depth", Parameter::PT_INT, "0:max53", "1460",
@@ -159,24 +117,12 @@ static const Parameter file_id_params[] =
     { "max_files_per_flow", Parameter::PT_INT, "1:max53", "128",
       "maximal number of files able to be concurrently processed per flow" },
 
-    { "enable_type", Parameter::PT_BOOL, nullptr, "true",
-      "enable type ID" },
-
-    { "enable_signature", Parameter::PT_BOOL, nullptr, "false",
-      "enable signature calculation" },
-
-    { "enable_capture", Parameter::PT_BOOL, nullptr, "false",
-      "enable file capture" },
-
     { "show_data_depth", Parameter::PT_INT, "0:max53", "100",
       "print this many octets" },
 
     { "file_rules", Parameter::PT_LIST, file_rule_params, nullptr,
       "list of file magic rules" },
 
-    { "file_policy", Parameter::PT_LIST, file_policy_rule_params, nullptr,
-      "list of file rules" },
-
     { "trace_type", Parameter::PT_BOOL, nullptr, "false",
       "enable runtime dump of type info" },
 
@@ -186,9 +132,6 @@ static const Parameter file_id_params[] =
     { "trace_stream", Parameter::PT_BOOL, nullptr, "false",
       "enable runtime dump of file data" },
 
-    { "verdict_delay", Parameter::PT_INT, "0:max53", "0",
-      "number of queries to return final verdict" },
-
     { "b64_decode_depth", Parameter::PT_INT, "-1:65535", "-1",
       "base64 decoding depth (-1 no limit)" },
 
@@ -271,8 +214,6 @@ bool FileIdModule::set(const char*, Value& v, SnortConfig*)
     if (!fc)
         fc = new FileConfig;
 
-    FilePolicy& fp = fc->get_file_policy();
-
     if ( v.is("type_depth") )
         fc->file_type_depth = v.get_int64();
 
@@ -306,23 +247,6 @@ bool FileIdModule::set(const char*, Value& v, SnortConfig*)
     else if ( v.is("max_files_per_flow") )
         fc->max_files_per_flow = v.get_uint64();
 
-    else if ( v.is("enable_type") )
-    {
-        fp.set_file_type(v.get_bool());
-    }
-    else if ( v.is("enable_signature") )
-    {
-        fp.set_file_signature(v.get_bool());
-    }
-    else if ( v.is("enable_capture") )
-    {
-        if (v.get_bool() and Snort::is_reloading() and !FileService::is_file_capture_enabled())
-        {
-            ReloadError("Changing file_id.enable_capture requires a restart.\n");
-            return false;
-        }
-        fp.set_file_capture(v.get_bool());
-    }
     else if ( v.is("show_data_depth") )
         fc->show_data_depth = v.get_int64();
 
@@ -335,11 +259,6 @@ bool FileIdModule::set(const char*, Value& v, SnortConfig*)
     else if ( v.is("trace_stream") )
         fc->trace_stream = v.get_bool();
 
-    else if ( v.is("verdict_delay") )
-    {
-        fc->verdict_delay = v.get_int64();
-        fp.set_verdict_delay(fc->verdict_delay);
-    }
     else if ( v.is("decompress_pdf") )
         FileService::decode_conf.set_decompress_pdf(v.get_bool());
 
@@ -377,9 +296,6 @@ bool FileIdModule::set(const char*, Value& v, SnortConfig*)
         FileService::decode_conf.set_uu_depth(mime);
     }
 
-    else if ( v.is("file_rules") )
-        return true;
-
     else if ( v.is("rev") )
         rule.rev = v.get_uint32();
 
@@ -408,53 +324,12 @@ bool FileIdModule::set(const char*, Value& v, SnortConfig*)
     else if ( v.is("version") )
         rule.version = v.get_string();
 
-    else if ( v.is("magic") )
-        return true;
-
     else if ( v.is("content") )
         magic.content_str = v.get_string();
 
     else if ( v.is("offset") )
         magic.offset = v.get_uint32();
 
-    else if ( v.is("file_policy") )
-        return true;
-
-    else if ( v.is("when") )
-        return true;
-
-    else if ( v.is("file_type_id") )
-        file_rule.when.type_id = v.get_uint32();
-
-    else if ( v.is("sha256") )
-        file_rule.when.sha256 = v.get_string();
-
-    else if ( v.is("use") )
-        return true;
-
-    else if ( v.is("verdict") )
-    {
-        file_rule.use.verdict = (FileVerdict)v.get_uint8();
-        if (file_rule.use.verdict == FileVerdict::FILE_VERDICT_REJECT)
-            need_active = true;
-    }
-
-    else if ( v.is("enable_file_type") )
-        file_rule.use.type_enabled = v.get_bool();
-
-    else if ( v.is("enable_file_signature") )
-        file_rule.use.signature_enabled = v.get_bool();
-
-    else if ( v.is("enable_file_capture") )
-    {
-        file_rule.use.capture_enabled = v.get_bool();
-        if (file_rule.use.capture_enabled && Snort::is_reloading()
-            && !FileService::is_file_capture_enabled())
-        {
-            ReloadError("Changing file_id.enable_file_capture requires a restart.\n");
-            return false;
-        }
-    }
     return true;
 }
 
@@ -471,10 +346,6 @@ bool FileIdModule::begin(const char* fqn, int idx, SnortConfig*)
     {
         magic.clear();
     }
-    else if ( !strcmp(fqn, "file_id.file_policy") )
-    {
-        file_rule.clear();
-    }
 
     return true;
 }
@@ -493,10 +364,6 @@ bool FileIdModule::end(const char* fqn, int idx, SnortConfig*)
         fc->process_file_magic(magic);
         rule.file_magics.emplace_back(magic);
     }
-    else if ( !strcmp(fqn, "file_id.file_policy") )
-    {
-        fc->process_file_policy_rule(file_rule);
-    }
 
     return true;
 }
@@ -504,12 +371,7 @@ bool FileIdModule::end(const char* fqn, int idx, SnortConfig*)
 void FileIdModule::load_config(FileConfig*& dst)
 {
     dst = fc;
-
-    if (fc)
-    {
-        fc->get_file_policy().load();
-        fc = nullptr;
-    }
+    fc = nullptr;
 }
 
 void FileIdModule::show_dynamic_stats()
index b5d86d93b673f86bfcffb26c1a850c93be065500..000e37017c92ea478ecbeff5c2643ee8ec39f4e5 100644 (file)
@@ -26,7 +26,6 @@
 
 #include "file_config.h"
 #include "file_identifier.h"
-#include "file_policy.h"
 #include "main/snort_debug.h"
 #include "utils/util.h"
 //-------------------------------------------------------------------------
@@ -76,9 +75,7 @@ public:
 private:
     FileMagicRule rule;
     FileMagicData magic;
-    FileRule file_rule;
     FileConfig *fc = nullptr;
-    bool need_active = false;
 };
 
 enum FileSid
index 6ec08342347b4fde9604ccc55d0a1059d1d03de7..f96288002127d646d05dffa62e09db9d356f82a0 100644 (file)
@@ -24,7 +24,6 @@
 
 // This provides a wrapper to start/stop file service
 
-#include "file_api/file_policy.h"
 #include "main/snort_config.h"
 #include "main/snort_types.h"
 #include "mime/file_mime_config.h"
index 6499cc5225b71d0dcf624026670fc8700939c10e..a4afae34f38f6a2ff52c02168e0049e107abcfea 100644 (file)
@@ -31,6 +31,7 @@ add_library ( framework OBJECT
     codec.cc
     cursor.cc
     data_bus.cc
+    file_policy.cc
     inspector.cc
     ips_option.cc
     packet_constraints.cc
similarity index 97%
rename from src/file_api/file_policy.cc
rename to src/framework/file_policy.cc
index af81d0bba28f978eab315f8a76615991a60062d9..cd8ca57aad9fa049f07113dce0006293d57061f2 100644 (file)
 #include "config.h"
 #endif
 
-#include "file_policy.h"
+#include "framework/file_policy.h"
 
+#include "file_api/file_capture.h"
+#include "file_api/file_lib.h"
+#include "file_api/file_service.h"
 #include "hash/hashes.h"
 
-#include "file_capture.h"
-#include "file_lib.h"
-#include "file_service.h"
-
 using namespace snort;
 
 static FileRule emptyRule;
similarity index 98%
rename from src/file_api/file_policy.h
rename to src/framework/file_policy.h
index a0c3164a8c6a5785945f9ecfc7ebfcb9ef03425c..d166505d413a2ae726e808108854ea309a29c309 100644 (file)
@@ -23,7 +23,7 @@
 #include <map>
 #include <vector>
 
-#include "file_api.h"
+#include "file_api/file_api.h"
 
 namespace snort
 {
@@ -88,7 +88,6 @@ private:
     bool signature_enabled = false;
     bool capture_enabled = false;
     int64_t verdict_delay = 0;
-
 };
 
 #endif
index 636a37330dfd35643b37feee1beb91ae55481d86..ca8341e74b8232896ed548a1492503e63bb22d3f 100644 (file)
@@ -136,6 +136,7 @@ static const char* InspectorTypeNames[IT_MAX] =
     "service",
     "control",
     "probe",
+    "file",
 };
 
 const char* InspectApi::get_type(InspectorType type)
index bb88bad8dfcd1b7b12b24198fddb98d0466c4d16..0dc3804c3c41c2fb756f32ff129ccd6bddcce086 100644 (file)
@@ -194,6 +194,7 @@ enum InspectorType
     IT_SERVICE,  // extract and analyze service PDUs (eg dce, http, ssl)
     IT_CONTROL,  // process all packets before detection (eg appid)
     IT_PROBE,    // process all packets after detection (eg perf_monitor, port_scan)
+    IT_FILE,     // file identification inspector
     IT_MAX
 };
 
index 3c9f5adbd7486801f0f304b14c78540a8f14cd40..a1b39f4a7489f7b229bd3d1d7392bf43d75c6a7c 100644 (file)
@@ -176,6 +176,7 @@ void Module::reset_stats()
 PegCount Module::get_global_count(const char* name) const
 {
     const PegInfo* infos = get_pegs();
+    assert(infos);
 
     for ( unsigned i = 0; infos[i].name; i++ )
     {
index 1be0b480de32b2f712e778415ce522416c590a87..4f420a27a9a0967a393ea7294e31a40821acff93 100644 (file)
@@ -79,7 +79,7 @@ public:
         if (ps)
             ps->get_api()->dtor(ps);
     }
-    const PolicySelectorApi* get_api()
+    const PolicySelectorApi* get_api() const
     { return api; }
     virtual bool select_default_policies(const _daq_pkt_hdr*, const SnortConfig*) = 0;
     virtual void show() const = 0;
index c9d9b9b7d40fa40b970463eff3957de3f0037a4e..e1a23f6d59479e85f13f365cae3e8fbd0731d1fd 100644 (file)
@@ -83,7 +83,8 @@ FILE* OpenAlertFile(const char* filearg)
         FatalError("OpenAlertFile() => fopen() alert file %s: %s\n",
             filename, get_error(errno));
     }
-    setvbuf(file, (char*)nullptr, _IOLBF, (size_t)0);
+    else
+        setvbuf(file, (char*)nullptr, _IOLBF, (size_t)0);
 
     return file;
 }
index 6b6975716ceceedd65b6835417f322dee3b11aae..6497d31709e74737b69c4e894dedf27ee4de966f 100644 (file)
@@ -256,7 +256,7 @@ void config_markup(SnortConfig*, const char*)
     fprintf(stdout, "max31 = 2147483647\n");
     fprintf(stdout, "max32 = 4294967295\n");
     fprintf(stdout, "max53 = 9007199254740992\n");
-    fprintf(stdout, "maxSZ = %zu\n", (sizeof(size_t) == 4) ? 4294967295 : 9007199254740992);
+    fprintf(stdout, "maxSZ = %lu\n", (sizeof(size_t) == 4) ? 4294967295LU : 9007199254740992LU);
     exit(0);
 }
 
index cd5b9f0390566ec7324eee4d080a23e1db16683e..dec205545f6dc4f9ad3d76d8751e86abcb3c99e1 100644 (file)
 #include "detection/fp_config.h"
 #include "detection/rules.h"
 #include "detection/tag.h"
+#include "file_api/file_service.h"
 #include "filters/detection_filter.h"
 #include "filters/rate_filter.h"
 #include "filters/sfrf.h"
 #include "filters/sfthd.h"
 #include "filters/sfthreshold.h"
 #include "flow/ha_module.h"
+#include "framework/file_policy.h"
 #include "framework/module.h"
 #include "host_tracker/host_tracker_module.h"
 #include "host_tracker/host_cache_module.h"
@@ -1051,6 +1053,7 @@ class NetworkModule : public Module
 public:
     NetworkModule() : Module("network", network_help, network_params) { }
     bool set(const char*, Value&, SnortConfig*) override;
+    bool end(const char*, int, SnortConfig*) override;
 
     Usage get_usage() const override
     { return CONTEXT; }
@@ -1067,10 +1070,7 @@ bool NetworkModule::set(const char*, Value& v, SnortConfig* sc)
         ConfigChecksumMode(v.get_string());
 
     else if ( v.is("id") )
-    {
         p->user_policy_id = v.get_uint16();
-        sc->policy_map->set_user_network(p);
-    }
 
     else if ( v.is("min_ttl") )
         p->min_ttl = v.get_uint8();
@@ -1090,6 +1090,16 @@ bool NetworkModule::set(const char*, Value& v, SnortConfig* sc)
     return true;
 }
 
+bool NetworkModule::end(const char*, int idx, SnortConfig* sc)
+{
+    if (!idx)
+    {
+        NetworkPolicy* p = get_network_policy();
+        sc->policy_map->set_user_network(p);
+    }
+    return true;
+}
+
 //-------------------------------------------------------------------------
 // inspection policy module
 //-------------------------------------------------------------------------
@@ -1122,6 +1132,7 @@ class InspectionModule : public Module
 public:
     InspectionModule() : Module("inspection", inspection_help, inspection_params) { }
     bool set(const char*, Value&, SnortConfig*) override;
+    bool end(const char*, int, SnortConfig*) override;
 
     Usage get_usage() const override
     { return INSPECT; }
@@ -1132,10 +1143,7 @@ bool InspectionModule::set(const char*, Value& v, SnortConfig* sc)
     InspectionPolicy* p = get_inspection_policy();
 
     if ( v.is("id") )
-    {
         p->user_policy_id = v.get_uint16();
-        sc->policy_map->set_user_inspection(p);
-    }
 
 #ifdef HAVE_UUID
     else if ( v.is("uuid") )
@@ -1164,13 +1172,18 @@ bool InspectionModule::set(const char*, Value& v, SnortConfig* sc)
     }
 
     else if ( v.is("max_aux_ip") )
-    {
         sc->max_aux_ip = v.get_int16();
-        return true;
-    }
 
     return true;
 }
+
+bool InspectionModule::end(const char*, int, SnortConfig* sc)
+{
+    InspectionPolicy* p = get_inspection_policy();
+    sc->policy_map->set_user_inspection(p);
+    return true;
+}
+
 //-------------------------------------------------------------------------
 // Ips policy module
 //-------------------------------------------------------------------------
@@ -1284,7 +1297,7 @@ private:
 bool IpsModule::matches(const char*, std::string&)
 { return true; }
 
-bool IpsModule::set(const char* fqn, Value& v, SnortConfig* sc)
+bool IpsModule::set(const char* fqn, Value& v, SnortConfig*)
 {
     IpsPolicy* p = get_ips_policy();
 
@@ -1298,10 +1311,7 @@ bool IpsModule::set(const char* fqn, Value& v, SnortConfig* sc)
         p->enable_builtin_rules = v.get_bool();
 
     else if ( v.is("id") )
-    {
         p->user_policy_id = v.get_uint16();
-        sc->policy_map->set_user_ips(p);
-    }
 
     else if ( v.is("include") )
         p->include = v.get_string();
@@ -1351,7 +1361,7 @@ bool IpsModule::set(const char* fqn, Value& v, SnortConfig* sc)
     return true;
 }
 
-bool IpsModule::end(const char* fqn, int idx, SnortConfig*)
+bool IpsModule::end(const char* fqn, int idx, SnortConfig* sc)
 {
     if ( idx and !strcmp(fqn, "ips.action_map") )
     {
@@ -1367,6 +1377,11 @@ bool IpsModule::end(const char* fqn, int idx, SnortConfig*)
         replace.clear();
         with.clear();
     }
+    else if (!idx and !strcmp(fqn, "ips"))
+    {
+        IpsPolicy* p = get_ips_policy();
+        sc->policy_map->set_user_ips(p);
+    }
     return true;
 }
 
@@ -1996,6 +2011,155 @@ bool HostsModule::end(const char* fqn, int idx, SnortConfig* sc)
     return true;
 }
 
+//-------------------------------------------------------------------------
+// File policy module
+//-------------------------------------------------------------------------
+
+static const Parameter file_when_params[] =
+{
+    // FIXIT-M when.policy_id should be an arbitrary string auto converted
+    // into index for binder matching and lookups
+    { "file_type_id", Parameter::PT_INT, "0:max32", "0",
+      "unique ID for file type in file magic rule" },
+
+    { "sha256", Parameter::PT_STRING, nullptr, nullptr,
+      "SHA 256" },
+
+    { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
+};
+
+static const Parameter file_use_params[] =
+{
+    { "verdict", Parameter::PT_ENUM, "unknown | log | stop | block | reset ", "unknown",
+      "what to do with matching traffic" },
+
+    { "enable_file_type", Parameter::PT_BOOL, nullptr, "false",
+      "true/false -> enable/disable file type identification" },
+
+    { "enable_file_signature", Parameter::PT_BOOL, nullptr, "false",
+      "true/false -> enable/disable file signature" },
+
+    { "enable_file_capture", Parameter::PT_BOOL, nullptr, "false",
+      "true/false -> enable/disable file capture" },
+
+    { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
+};
+
+static const Parameter file_policy_rule_params[] =
+{
+    { "when", Parameter::PT_TABLE, file_when_params, nullptr,
+      "match criteria" },
+
+    { "use", Parameter::PT_TABLE, file_use_params, nullptr,
+      "target configuration" },
+
+    { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
+};
+
+static const Parameter file_policy_params[] =
+{
+    { "enable_type", Parameter::PT_BOOL, nullptr, "true",
+      "enable type ID" },
+
+    { "enable_signature", Parameter::PT_BOOL, nullptr, "false",
+      "enable signature calculation" },
+
+    { "enable_capture", Parameter::PT_BOOL, nullptr, "false",
+      "enable file capture" },
+
+    { "verdict_delay", Parameter::PT_INT, "0:max53", "0",
+      "number of queries to return final verdict" },
+
+    { "rules", Parameter::PT_LIST, file_policy_rule_params, nullptr,
+      "list of file rules" },
+
+    { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
+};
+
+
+#define file_policy_help "configure file policy"
+
+class FilePolicyModule : public Module
+{
+public:
+    FilePolicyModule() : Module("file_policy", file_policy_help, file_policy_params)
+    { }
+    bool begin(const char*, int, SnortConfig*) override;
+    bool set(const char*, Value&, SnortConfig*) override;
+    bool end(const char*, int, SnortConfig*) override;
+
+private:
+    FileRule file_rule;
+};
+
+bool FilePolicyModule::begin(const char* fqn, int idx, SnortConfig*)
+{
+    if (idx && !strcmp(fqn, "file_policy.rules"))
+        file_rule.clear();
+    return true;
+}
+
+bool FilePolicyModule::set(const char*, Value& v, SnortConfig*)
+{
+    FilePolicy* fp = get_network_policy()->get_file_policy();
+    if ( v.is("file_type_id") )
+        file_rule.when.type_id = v.get_uint32();
+
+    else if ( v.is("sha256") )
+        file_rule.when.sha256 = v.get_string();
+
+    else if ( v.is("verdict") )
+        file_rule.use.verdict = (FileVerdict)v.get_uint8();
+
+    else if ( v.is("enable_file_type") )
+        file_rule.use.type_enabled = v.get_bool();
+
+    else if ( v.is("enable_file_signature") )
+        file_rule.use.signature_enabled = v.get_bool();
+
+    else if ( v.is("enable_file_capture") )
+    {
+        file_rule.use.capture_enabled = v.get_bool();
+        if (file_rule.use.capture_enabled && Snort::is_reloading()
+            && !FileService::is_file_capture_enabled())
+        {
+            ReloadError("Changing file_id.enable_file_capture requires a restart.\n");
+            return false;
+        }
+    }
+
+    else if ( v.is("enable_type") )
+        fp->set_file_type(v.get_bool());
+
+    else if ( v.is("enable_signature") )
+        fp->set_file_signature(v.get_bool());
+
+    else if ( v.is("enable_capture") )
+    {
+        if (v.get_bool() and Snort::is_reloading() and !FileService::is_file_capture_enabled())
+        {
+            ReloadError("Changing file_id.enable_capture requires a restart.\n");
+            return false;
+        }
+        fp->set_file_capture(v.get_bool());
+    }
+
+    else if ( v.is("verdict_delay") )
+        fp->set_verdict_delay(v.get_int64());
+
+    return true;
+}
+
+bool FilePolicyModule::end(const char* fqn, int idx, SnortConfig*)
+{
+    if (!idx)
+        get_network_policy()->get_file_policy()->load();
+    if (idx && !strcmp(fqn, "file_policy.rules"))
+        get_network_policy()->add_file_policy_rule(file_rule);
+
+    return true;
+}
+
 //-------------------------------------------------------------------------
 // module manager stuff - move to framework/module_manager.cc
 //-------------------------------------------------------------------------
@@ -2045,6 +2209,7 @@ void module_init()
     ModuleManager::add_module(new NetworkModule);
     ModuleManager::add_module(new InspectionModule);
     ModuleManager::add_module(new IpsModule);
+    ModuleManager::add_module(new FilePolicyModule);
 
     // these modules replace config and hosts.xml
     ModuleManager::add_module(new AttributeTableModule);
index 8213f7e007a27f476db73e35b27fd1c1f7e8cd24..7680beea908847920e0473c880f3835fd9157526 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "actions/actions.h"
 #include "detection/detection_engine.h"
+#include "framework/file_policy.h"
 #include "framework/policy_selector.h"
 #include "log/messages.h"
 #include "managers/inspector_manager.h"
@@ -52,10 +53,14 @@ NetworkPolicy::NetworkPolicy(NetworkPolicy* other_network_policy, const char* ex
 { init(other_network_policy, exclude_name); }
 
 NetworkPolicy::~NetworkPolicy()
-{ InspectorManager::delete_policy(this, cloned); }
+{
+    FilePolicyBase::delete_file_policy(file_policy);
+    InspectorManager::delete_policy(this, cloned);
+}
 
 void NetworkPolicy::init(NetworkPolicy* other_network_policy, const char* exclude_name)
 {
+    file_policy = new FilePolicy;
     if (other_network_policy)
     {
         dbus.clone(other_network_policy->dbus, exclude_name);
@@ -73,6 +78,14 @@ void NetworkPolicy::init(NetworkPolicy* other_network_policy, const char* exclud
     InspectorManager::new_policy(this, other_network_policy);
 }
 
+FilePolicyBase* NetworkPolicy::get_base_file_policy() const
+{ return file_policy; }
+FilePolicy* NetworkPolicy::get_file_policy() const
+{ return file_policy; }
+
+void NetworkPolicy::add_file_policy_rule(FileRule& file_rule)
+{ file_policy->insert_file_rule(file_rule); }
+
 //-------------------------------------------------------------------------
 // inspection policy
 //-------------------------------------------------------------------------
@@ -167,6 +180,9 @@ PolicyMap::PolicyMap(PolicyMap* other_map, const char* exclude_name)
         clone(other_map, exclude_name);
     else
     {
+        file_id = InspectorManager::create_single_instance_inspector_policy();
+        flow_tracking = InspectorManager::create_single_instance_inspector_policy();
+        global_inspector_policy = InspectorManager::create_global_inspector_policy();
         add_shell(new Shell(nullptr, true), true);
         empty_ips_policy = new IpsPolicy(ips_policy.size());
         ips_policy.push_back(empty_ips_policy);
@@ -208,8 +224,13 @@ PolicyMap::~PolicyMap()
         for ( auto p : network_policy )
             delete p;
 
+        InspectorManager::destroy_single_instance_inspector(flow_tracking);
+        InspectorManager::destroy_single_instance_inspector(file_id);
     }
 
+    PolicySelector::free_policy_selector(selector);
+    InspectorManager::destroy_global_inspector_policy(global_inspector_policy, cloned);
+
     shells.clear();
     inspection_policy.clear();
     ips_policy.clear();
@@ -219,6 +240,10 @@ PolicyMap::~PolicyMap()
 
 void PolicyMap::clone(PolicyMap *other_map, const char* exclude_name)
 {
+    global_inspector_policy =
+        InspectorManager::create_global_inspector_policy(other_map->global_inspector_policy);
+    file_id = other_map->file_id;
+    flow_tracking = other_map->flow_tracking;
     shells = other_map->shells;
     ips_policy = other_map->ips_policy;
     empty_ips_policy = other_map->empty_ips_policy;
@@ -423,7 +448,8 @@ void set_default_policy(const SnortConfig* sc)
 
 void select_default_policy(const _daq_pkt_hdr* pkthdr, const SnortConfig* sc)
 {
-    if (!sc->global_selector || !sc->global_selector->select_default_policies(pkthdr, sc))
+    PolicySelector* ps = sc->policy_map->get_policy_selector();
+    if (!ps || !ps->select_default_policies(pkthdr, sc))
     {
         set_network_policy(sc->policy_map->get_network_policy(0));
         set_inspection_policy(sc->policy_map->get_inspection_policy(0));
index 38f4b0d20fe31094744a7719e68067d4a296e011..1dbd08117f9b85a87df5f9a592ef38eae733d994 100644 (file)
@@ -42,8 +42,10 @@ typedef unsigned char uuid_t[16];
 
 namespace snort
 {
+class FilePolicyBase;
 class GHash;
 class IpsAction;
+class PolicySelector;
 struct SnortConfig;
 }
 
@@ -87,6 +89,9 @@ enum DecodeEventFlag
 // Snort ac-split creates the nap (network analysis policy)
 // Snort++ breaks the nap into network and inspection
 
+class FilePolicy;
+class FileRule;
+
 struct NetworkPolicy
 {
 public:
@@ -94,6 +99,10 @@ public:
     NetworkPolicy(NetworkPolicy*, const char*);
     ~NetworkPolicy();
 
+    void add_file_policy_rule(FileRule& file_rule);
+    snort::FilePolicyBase* get_base_file_policy() const;
+    FilePolicy* get_file_policy() const;
+
     bool checksum_drops(uint16_t codec_cksum_err_flag)
     { return (checksum_drop & codec_cksum_err_flag) != 0; }
 
@@ -109,6 +118,9 @@ public:
     bool icmp_checksums()
     { return (checksum_eval & CHECKSUM_FLAG__ICMP) != 0; }
 
+protected:
+    FilePolicy* file_policy;
+
 public:
     struct TrafficPolicy* traffic_policy;
     snort::DataBus dbus;
@@ -221,6 +233,9 @@ struct PolicyTuple
         inspection(ins_pol), ips(ips_pol), network(net_pol) { }
 };
 
+struct GlobalInspectorPolicy;
+class SingleInstanceInspectorPolicy;
+
 class PolicyMap
 {
 public:
@@ -290,6 +305,21 @@ public:
     void set_cloned(bool state)
     { cloned = state; }
 
+    snort::PolicySelector* get_policy_selector() const
+    { return selector; }
+
+    void set_policy_selector(snort::PolicySelector* new_selector)
+    { selector = new_selector; }
+
+    SingleInstanceInspectorPolicy* get_file_id()
+    { return file_id; }
+
+    SingleInstanceInspectorPolicy* get_flow_tracking()
+    { return flow_tracking; }
+
+    GlobalInspectorPolicy* get_global_inspector_policy()
+    { return global_inspector_policy; }
+
     const Shell* get_shell_by_policy(unsigned id) const
     {
         auto it = std::find_if(std::begin(shell_map), std::end(shell_map),
@@ -311,6 +341,11 @@ private:
     std::unordered_map<unsigned, InspectionPolicy*> user_inspection;
     std::unordered_map<unsigned, IpsPolicy*> user_ips;
 
+    snort::PolicySelector* selector = nullptr;
+    SingleInstanceInspectorPolicy* file_id;
+    SingleInstanceInspectorPolicy* flow_tracking;
+    GlobalInspectorPolicy* global_inspector_policy;
+
     bool cloned = false;
 };
 
index aab108c3ac562565728062c02291678ba1475a42..5d379a669cdc4a14b47e90a04d097fd2c2c45f41 100644 (file)
@@ -275,8 +275,6 @@ SnortConfig::~SnortConfig()
     if ( plugins )
         delete plugins;
     delete payload_injector_config;
-    InspectorManager::free_flow_tracking(flow_tracking);
-    PolicySelector::free_policy_selector(global_selector);
     clear_reload_resource_tuner_list();
 
     trim_heap();
index 8e0bc59d72c043bf823d1ca68288f5816324307a..ecacaa64207ecb6cfa8613ea7171205116355f86 100644 (file)
@@ -149,7 +149,6 @@ struct IpsActionsConfig;
 struct LatencyConfig;
 struct MemoryConfig;
 struct PayloadInjectorConfig;
-struct PHInstance;
 struct Plugins;
 struct PORT_RULE_MAP;
 struct RateFilterConfig;
@@ -163,7 +162,6 @@ struct ThresholdConfig;
 namespace snort
 {
 class GHash;
-class PolicySelector;
 class ProtocolReference;
 class ThreadConfig;
 class XHash;
@@ -394,10 +392,6 @@ public:
     PolicyMap* policy_map = nullptr;
     std::string tweaks;
 
-    PolicySelector* global_selector = nullptr;
-    PHInstance* flow_tracking = nullptr;
-    PHInstance* removed_flow_tracking = nullptr;
-
     uint16_t tunnel_mask = 0;
 
     int16_t max_aux_ip = 16;
index 7f03987d2b59c9b5f43aecfb64f67ce917d8a882..5eca04b4897deb41216e40fd1724676d05aec330 100644 (file)
@@ -137,6 +137,9 @@ struct PHInstance
 
     ReloadType get_reload_type()
     { return reload_type; }
+
+    void tinit();
+    void tterm();
 };
 
 PHInstance::PHInstance(PHClass& p, SnortConfig* sc, Module* mod) : pp_class(p)
@@ -224,8 +227,56 @@ struct InspectorList
 
     virtual void handle_new_reenabled(SnortConfig*, bool, bool) = 0;
     virtual void vectorize(SnortConfig*) = 0;
+
+    void tinit();
+    void tterm();
+    void tterm_removed();
+
+    void populate_removed(SnortConfig*, InspectorList*);
+    void clear_removed();
 };
 
+void InspectorList::tinit()
+{
+    for ( auto* p : ilist )
+        p->tinit();
+}
+
+void InspectorList::tterm()
+{
+    for ( auto* p : ilist )
+        p->tterm();
+}
+
+void InspectorList::tterm_removed()
+{
+    for ( auto* p : removed_ilist )
+        p->tterm();
+}
+
+static PHInstance* get_instance(InspectorList* il, const char* keyword);
+
+void InspectorList::populate_removed(SnortConfig* sc, InspectorList* old)
+{
+    for (auto it = old->ilist.begin(); it != old->ilist.end(); ++it)
+    {
+        PHInstance* instance = get_instance(this, (*it)->name.c_str());
+        if (!instance)
+        {
+            removed_ilist.emplace_back(*it);
+            (*it)->handler->add_global_ref();
+            (*it)->handler->tear_down(sc);
+        }
+    }
+}
+
+void InspectorList::clear_removed()
+{
+    for ( auto* p : removed_ilist )
+        p->handler->rem_global_ref();
+    removed_ilist.clear();
+}
+
 struct TrafficPolicy : public InspectorList
 {
     PHVector passive;
@@ -266,8 +317,148 @@ void TrafficPolicy::vectorize(SnortConfig*)
             break;
 
         default:
-            ParseError("Network policy (context usage) does not handle %s inspector type\n",
-                InspectApi::get_type(p->pp_class.api.type));
+            ParseError(
+                "Network policy (context usage) does not handle inspector %s with type %s\n",
+                p->pp_class.api.base.name, InspectApi::get_type(p->pp_class.api.type));
+            break;
+        }
+    }
+}
+
+class SingleInstanceInspectorPolicy
+{
+public:
+    SingleInstanceInspectorPolicy() = default;
+    ~SingleInstanceInspectorPolicy();
+
+    bool get_new(SnortConfig*, Module*, PHClass&, PHInstance*&);
+    void populate_removed(SnortConfig*, SingleInstanceInspectorPolicy*);
+    void clear_removed();
+    void configure(SnortConfig*);
+    void tinit();
+    void tterm();
+    void tterm_removed();
+    void print_config(SnortConfig*, const char* title);
+
+    PHInstance* instance = nullptr;
+    PHInstance* removed_instance = nullptr;
+};
+
+SingleInstanceInspectorPolicy::~SingleInstanceInspectorPolicy()
+{
+    if (instance)
+    {
+        if ( IT_PASSIVE == instance->handler->get_api()->type )
+            s_trash2.emplace_back(instance->handler);
+        else
+            s_trash.emplace_back(instance->handler);
+
+        delete instance;
+    }
+    assert(nullptr == removed_instance);
+}
+
+bool SingleInstanceInspectorPolicy::get_new(SnortConfig*sc, Module* mod, PHClass& pc,
+    PHInstance*& ppi)
+{
+    if (instance)
+        return false;
+    ppi = new PHInstance(pc, sc, mod);
+    if ( ppi->handler )
+        instance = ppi;
+    else
+    {
+        delete ppi;
+        ppi = nullptr;
+    }
+    return true;
+}
+
+void SingleInstanceInspectorPolicy::populate_removed(SnortConfig* sc,
+    SingleInstanceInspectorPolicy* old)
+{
+    if (old->instance && !instance)
+    {
+        removed_instance = old->instance;
+        removed_instance->handler->add_global_ref();
+        removed_instance->handler->tear_down(sc);
+    }
+}
+
+void SingleInstanceInspectorPolicy::clear_removed()
+{
+    if (removed_instance)
+    {
+        removed_instance->handler->rem_global_ref();
+        removed_instance = nullptr;
+    }
+}
+
+void SingleInstanceInspectorPolicy::configure(SnortConfig* sc)
+{
+    if (instance)
+        instance->handler->configure(sc);
+}
+
+void SingleInstanceInspectorPolicy::tinit()
+{
+    if (instance)
+        instance->tinit();
+}
+
+void SingleInstanceInspectorPolicy::tterm()
+{
+    if (instance)
+        instance->tterm();
+}
+
+void SingleInstanceInspectorPolicy::tterm_removed()
+{
+    if (removed_instance)
+        removed_instance->tterm();
+}
+
+void SingleInstanceInspectorPolicy::print_config(SnortConfig* sc, const char* title)
+{
+    if (instance)
+    {
+        LogLabel(title);
+        const std::string name = InspectorManager::generate_inspector_label(instance);
+        LogLabel(name.c_str());
+        instance->handler->show(sc);
+    }
+}
+
+struct GlobalInspectorPolicy : public InspectorList
+{
+    PHVector passive;
+    PHVector probe;
+
+    void handle_new_reenabled(SnortConfig*, bool, bool) override
+    { }
+    void vectorize(SnortConfig*) override;
+};
+
+void GlobalInspectorPolicy::vectorize(SnortConfig*)
+{
+    passive.alloc(ilist.size());
+    probe.alloc(ilist.size());
+    for ( auto* p : ilist )
+    {
+        switch ( p->pp_class.api.type )
+        {
+        case IT_PASSIVE:
+            passive.add(p);
+            break;
+
+        case IT_PROBE:
+            probe.add(p);
+            break;
+
+        default:
+            ParseError(
+                "Global inspector policy (global usage) does not handle inspector %s with type %s\n",
+                p->pp_class.api.base.name, InspectApi::get_type(p->pp_class.api.type));
             break;
         }
     }
@@ -279,7 +470,6 @@ struct FrameworkPolicy : public InspectorList
     PHVector packet;
     PHVector network;
     PHVector service;
-    PHVector probe;
 
     Inspector* binder;
     Inspector* wizard;
@@ -293,6 +483,7 @@ struct FrameworkPolicy : public InspectorList
     void vectorize(SnortConfig*) override;
     void add_inspector_to_cache(PHInstance*, SnortConfig*);
     void remove_inspector_from_cache(Inspector*);
+    bool delete_inspector(SnortConfig*, const char* iname);
 };
 
 void FrameworkPolicy::add_inspector_to_cache(PHInstance* p, SnortConfig* sc)
@@ -361,7 +552,6 @@ void FrameworkPolicy::vectorize(SnortConfig* sc)
     packet.alloc(ilist.size());
     network.alloc(ilist.size());
     service.alloc(ilist.size());
-    probe.alloc(ilist.size());
 
     for ( auto* p : ilist )
     {
@@ -393,17 +583,9 @@ void FrameworkPolicy::vectorize(SnortConfig* sc)
             wizard = p->handler;
             break;
 
-        case IT_PROBE:
-        {
-            // probes always run
-            // add them to default so they can be found on InspectorManager::probe
-            sc->policy_map->get_inspection_policy(0)->framework_policy->probe.add(p);
-            break;
-        }
-
         default:
-            ParseError("Inspection policy does not handle %s inspector type\n",
-                InspectApi::get_type(p->pp_class.api.type));
+            ParseError("Inspection policy does not handle inspector %s with type %s\n",
+                p->pp_class.api.base.name, InspectApi::get_type(p->pp_class.api.type));
             break;
         }
     }
@@ -414,10 +596,26 @@ void FrameworkPolicy::vectorize(SnortConfig* sc)
     for ( auto* p : ilist )
         add_inspector_to_cache(p, sc);
 
-    if ( !binder and (sc->flow_tracking or wizard) )
+    if ( !binder and (sc->policy_map->get_flow_tracking()->instance or wizard) )
         instantiate_default_binder(sc, this);
 }
 
+bool FrameworkPolicy::delete_inspector(SnortConfig* sc, const char* iname)
+{
+    std::vector<PHInstance*>::iterator old_it;
+    if ( get_instance(this, iname, old_it) )
+    {
+        (*old_it)->set_reloaded(RELOAD_TYPE_DELETED);
+        remove_inspector_from_cache((*old_it)->handler);
+        ilist.erase(old_it);
+        std::vector<PHInstance*>::iterator bind_it;
+        if ( get_instance(this, bind_id, bind_it) )
+            (*bind_it)->handler->remove_inspector_binding(sc, iname);
+        return true;
+    }
+    return false;
+}
+
 //-------------------------------------------------------------------------
 // global stuff
 //-------------------------------------------------------------------------
@@ -531,8 +729,38 @@ void InspectorManager::empty_trash()
 // policy stuff
 //-------------------------------------------------------------------------
 
-static bool get_instance(
-    InspectorList* il, const char* keyword,
+SingleInstanceInspectorPolicy* InspectorManager::create_single_instance_inspector_policy()
+{ return new SingleInstanceInspectorPolicy; }
+
+void InspectorManager::destroy_single_instance_inspector(SingleInstanceInspectorPolicy* p)
+{ delete p; }
+
+GlobalInspectorPolicy* InspectorManager::create_global_inspector_policy(GlobalInspectorPolicy* other_pp)
+{
+    GlobalInspectorPolicy* pp = new GlobalInspectorPolicy;
+
+    if ( other_pp )
+        pp->ilist = other_pp->ilist;
+
+    return pp;
+}
+
+void InspectorManager::destroy_global_inspector_policy(GlobalInspectorPolicy* pp, bool cloned)
+{
+    for ( auto* p : pp->ilist )
+    {
+        if ( cloned and !(p->is_reloaded()) )
+            continue;
+        if ( IT_PASSIVE == p->handler->get_api()->type )
+            s_trash2.emplace_back(p->handler);
+        else
+            s_trash.emplace_back(p->handler);
+        delete p;
+    }
+    delete pp;
+}
+
+static bool get_instance(InspectorList* il, const char* keyword,
     std::vector<PHInstance*>::iterator& it)
 {
     for ( it = il->ilist.begin(); it != il->ilist.end(); ++it )
@@ -649,6 +877,9 @@ void InspectorManager::delete_policy(NetworkPolicy* pi, bool cloned)
 
 void InspectorManager::update_policy(SnortConfig* sc)
 {
+    GlobalInspectorPolicy* pp = sc->policy_map->get_global_inspector_policy();
+    for ( auto* p : pp->ilist )
+        p->set_reloaded(RELOAD_TYPE_NONE);
     InspectionPolicy* ip = sc->policy_map->get_inspection_policy();
     for ( auto* p : ip->framework_policy->ilist )
         p->set_reloaded(RELOAD_TYPE_NONE);
@@ -669,55 +900,47 @@ Binder* InspectorManager::get_binder()
 
 void InspectorManager::clear_removed_inspectors(SnortConfig* sc)
 {
-    if (sc->removed_flow_tracking)
-    {
-        sc->removed_flow_tracking->handler->rem_global_ref();
-        sc->removed_flow_tracking = nullptr;
-    }
+    SingleInstanceInspectorPolicy* fid = sc->policy_map->get_file_id();
+    fid->clear_removed();
+    SingleInstanceInspectorPolicy* ft = sc->policy_map->get_flow_tracking();
+    ft->clear_removed();
+    GlobalInspectorPolicy* pp = sc->policy_map->get_global_inspector_policy();
+    pp->clear_removed();
     TrafficPolicy* tp = sc->policy_map->get_network_policy()->traffic_policy;
-    for ( auto* p : tp->removed_ilist )
-        p->handler->rem_global_ref();
-    tp->removed_ilist.clear();
+    tp->clear_removed();
     FrameworkPolicy* fp = sc->policy_map->get_inspection_policy()->framework_policy;
-    for ( auto* p : fp->removed_ilist )
-        p->handler->rem_global_ref();
-    fp->removed_ilist.clear();
+    fp->clear_removed();
 }
 
 void InspectorManager::tear_down_removed_inspectors(const SnortConfig* old, SnortConfig* sc)
 {
-    if (old->flow_tracking && !sc->flow_tracking)
-    {
-        sc->removed_flow_tracking = old->flow_tracking;
-        sc->removed_flow_tracking->handler->add_global_ref();
-        sc->removed_flow_tracking->handler->tear_down(sc);
-    }
+    SingleInstanceInspectorPolicy* old_fid = old->policy_map->get_file_id();
+    SingleInstanceInspectorPolicy* fid = sc->policy_map->get_file_id();
+    fid->populate_removed(sc, old_fid);
+
+    SingleInstanceInspectorPolicy* old_ft = old->policy_map->get_flow_tracking();
+    SingleInstanceInspectorPolicy* ft = sc->policy_map->get_flow_tracking();
+    ft->populate_removed(sc, old_ft);
+
+    GlobalInspectorPolicy* pp = sc->policy_map->get_global_inspector_policy();
+    GlobalInspectorPolicy* old_pp = old->policy_map->get_global_inspector_policy();
+    pp->populate_removed(sc, old_pp);
 
     TrafficPolicy* tp = get_default_network_policy(sc)->traffic_policy;
     TrafficPolicy* old_tp = get_default_network_policy(old)->traffic_policy;
-    for (auto it = old_tp->ilist.begin(); it != old_tp->ilist.end(); ++it)
-    {
-        PHInstance* instance = get_instance(tp, (*it)->name.c_str());
-        if (!instance)
-        {
-            tp->removed_ilist.emplace_back(*it);
-            (*it)->handler->add_global_ref();
-            (*it)->handler->tear_down(sc);
-        }
-    }
+    tp->populate_removed(sc, old_tp);
 
     FrameworkPolicy* fp = get_default_inspection_policy(sc)->framework_policy;
     FrameworkPolicy* old_fp = get_default_inspection_policy(old)->framework_policy;
-    for (auto it = old_fp->ilist.begin(); it != old_fp->ilist.end(); ++it)
-    {
-        PHInstance* instance = get_instance(fp, (*it)->name.c_str());
-        if (!instance)
-        {
-            fp->removed_ilist.emplace_back(*it);
-            (*it)->handler->add_global_ref();
-            (*it)->handler->tear_down(sc);
-        }
-    }
+    fp->populate_removed(sc, old_fp);
+}
+
+Inspector* InspectorManager::get_file_inspector(const SnortConfig* sc)
+{
+    if ( !sc )
+        sc = SnortConfig::get_conf();
+    SingleInstanceInspectorPolicy* fid = sc->policy_map->get_file_id();
+    return fid->instance ? fid->instance->handler : nullptr;
 }
 
 // FIXIT-P cache get_inspector() returns or provide indexed lookup
@@ -726,10 +949,10 @@ Inspector* InspectorManager::get_inspector(const char* key, bool dflt_only, cons
     InspectionPolicy* pi;
     NetworkPolicy* ni;
 
+    if ( !sc )
+        sc = SnortConfig::get_conf();
     if ( dflt_only )
     {
-        if ( !sc )
-            sc = SnortConfig::get_conf();
         pi = get_default_inspection_policy(sc);
         ni = get_default_network_policy(sc);
     }
@@ -752,6 +975,20 @@ Inspector* InspectorManager::get_inspector(const char* key, bool dflt_only, cons
         if ( p )
             return p->handler;
     }
+
+    GlobalInspectorPolicy* pp = sc->policy_map->get_global_inspector_policy();
+    PHInstance* p = get_instance(pp, key);
+    if ( p )
+        return p->handler;
+
+    SingleInstanceInspectorPolicy* ft = sc->policy_map->get_flow_tracking();
+    if ( ft->instance && ft->instance->name == key )
+        return ft->instance->handler;
+
+    SingleInstanceInspectorPolicy* fid = sc->policy_map->get_file_id();
+    if ( fid->instance && fid->instance->name == key )
+        return fid->instance->handler;
+
     return nullptr;
 }
 
@@ -779,24 +1016,8 @@ Inspector* InspectorManager::get_service_inspector_by_id(const SnortProtocolId p
 
 bool InspectorManager::delete_inspector(SnortConfig* sc, const char* iname)
 {
-    bool ok = false;
     FrameworkPolicy* fp = sc->policy_map->get_inspection_policy()->framework_policy;
-    std::vector<PHInstance*>::iterator old_it;
-
-    if ( get_instance(fp, iname, old_it) )
-    {
-        (*old_it)->set_reloaded(RELOAD_TYPE_DELETED);
-        fp->remove_inspector_from_cache((*old_it)->handler);
-        fp->ilist.erase(old_it);
-        ok = true;
-        std::vector<PHInstance*>::iterator bind_it;
-        if ( get_instance(fp, bind_id, bind_it) )
-        {
-            (*bind_it)->handler->remove_inspector_binding(sc, iname);
-        }
-    }
-
-    return ok;
+    return fp->delete_inspector(sc, iname);
 }
 
 void InspectorManager::free_inspector(Inspector* p)
@@ -804,16 +1025,6 @@ void InspectorManager::free_inspector(Inspector* p)
     p->get_api()->dtor(p);
 }
 
-void InspectorManager::free_flow_tracking(PHInstance* pi)
-{
-    if (pi)
-    {
-        Inspector* i = pi->handler;
-        delete pi;
-        free_inspector(i);
-    }
-}
-
 InspectSsnFunc InspectorManager::get_session(uint16_t proto)
 {
     for ( auto* p : s_handlers )
@@ -880,6 +1091,26 @@ static PHGlobal& get_thread_local_plugin(const InspectApi& api)
     return s_tl_handlers->back();
 }
 
+void PHInstance::tinit()
+{
+    PHGlobal& phg = get_thread_local_plugin(pp_class.api);
+    if ( !phg.instance_initialized )
+    {
+        handler->tinit();
+        phg.instance_initialized = true;
+    }
+}
+
+void PHInstance::tterm()
+{
+    PHGlobal& phg = get_thread_local_plugin(pp_class.api);
+    if ( phg.instance_initialized )
+    {
+        handler->tterm();
+        phg.instance_initialized = false;
+    }
+}
+
 void InspectorManager::thread_init(const SnortConfig* sc)
 {
     Inspector::slot = get_instance_id();
@@ -896,43 +1127,23 @@ void InspectorManager::thread_init(const SnortConfig* sc)
 
     // pin->tinit() only called for default policy
     set_default_policy(sc);
-    if (sc->flow_tracking)
-    {
-        PHGlobal& phg = get_thread_local_plugin(sc->flow_tracking->pp_class.api);
-        if ( !phg.instance_initialized )
-        {
-            sc->flow_tracking->handler->tinit();
-            phg.instance_initialized = true;
-        }
-    }
+    SingleInstanceInspectorPolicy* fid = sc->policy_map->get_file_id();
+    fid->tinit();
+    SingleInstanceInspectorPolicy* ft = sc->policy_map->get_flow_tracking();
+    ft->tinit();
+
+    GlobalInspectorPolicy* pp = sc->policy_map->get_global_inspector_policy();
+    pp->tinit();
 
     InspectionPolicy* pi = get_inspection_policy();
     if ( pi && pi->framework_policy )
-    {
-        for ( auto* p : pi->framework_policy->ilist )
-        {
-            PHGlobal& phg = get_thread_local_plugin(p->pp_class.api);
-            if ( !phg.instance_initialized )
-            {
-                p->handler->tinit();
-                phg.instance_initialized = true;
-            }
-        }
-    }
+        pi->framework_policy->tinit();
 
     for ( unsigned i = 0; i < sc->policy_map->network_policy_count(); i++)
     {
         NetworkPolicy* npi = sc->policy_map->get_network_policy(i);
         set_network_policy(npi);
-        for ( auto* p : npi->traffic_policy->ilist )
-        {
-            PHGlobal& phg = get_thread_local_plugin(p->pp_class.api);
-            if ( !phg.instance_initialized )
-            {
-                p->handler->tinit();
-                phg.instance_initialized = true;
-            }
-        }
+        npi->traffic_policy->tinit();
     }
 }
 
@@ -951,77 +1162,44 @@ void InspectorManager::thread_reinit(const SnortConfig* sc)
     }
 
     set_default_policy(sc);
-    if (sc->flow_tracking)
-    {
-        PHGlobal& phg = get_thread_local_plugin(sc->flow_tracking->pp_class.api);
-        if ( !phg.instance_initialized )
-        {
-            if (phg.api.tinit)
-                sc->flow_tracking->handler->tinit();
-            phg.instance_initialized = true;
-        }
-    }
+    SingleInstanceInspectorPolicy* fid = sc->policy_map->get_file_id();
+    fid->tinit();
+    SingleInstanceInspectorPolicy* ft = sc->policy_map->get_flow_tracking();
+    ft->tinit();
+
+    GlobalInspectorPolicy* pp = sc->policy_map->get_global_inspector_policy();
+    pp->tinit();
 
     for ( unsigned i = 0; i < sc->policy_map->network_policy_count(); i++)
     {
         NetworkPolicy* npi = sc->policy_map->get_network_policy(i);
         set_network_policy(npi);
-
-        for ( auto* p : npi->traffic_policy->ilist )
-        {
-            PHGlobal& phg = get_thread_local_plugin(p->pp_class.api);
-            if ( !phg.instance_initialized )
-            {
-                p->handler->tinit();
-                phg.instance_initialized = true;
-            }
-        }
+        npi->traffic_policy->tinit();
 
         // pin->tinit() only called for default policy
         InspectionPolicy* pi = get_default_inspection_policy(sc);
         if ( pi && pi->framework_policy )
-        {
-            // Call pin->tinit() for anything that hasn't yet
-            for ( auto* p : pi->framework_policy->ilist )
-            {
-                PHGlobal& phg = get_thread_local_plugin(p->pp_class.api);
-                if ( !phg.instance_initialized )
-                {
-                    p->handler->tinit();
-                    phg.instance_initialized = true;
-                }
-            }
-        }
+            pi->framework_policy->tinit();
     }
 }
 
 void InspectorManager::thread_stop_removed(const SnortConfig* sc)
 {
-    if (sc->removed_flow_tracking)
-    {
-        PHGlobal& phg = get_thread_local_plugin(sc->removed_flow_tracking->pp_class.api);
-        if ( phg.instance_initialized )
-        {
-            sc->removed_flow_tracking->handler->tterm();
-            phg.instance_initialized = false;
-        }
-    }
+    SingleInstanceInspectorPolicy* fid = sc->policy_map->get_file_id();
+    fid->tterm_removed();
+
+    SingleInstanceInspectorPolicy* ft = sc->policy_map->get_flow_tracking();
+    ft->tterm_removed();
+
+    GlobalInspectorPolicy* pp = sc->policy_map->get_global_inspector_policy();
+    pp->tterm_removed();
 
     // pin->tinit() only called for default policy
     NetworkPolicy* npi = get_default_network_policy(sc);
-
     if ( npi && npi->traffic_policy )
     {
         // Call pin->tterm() for anything that has been initialized and removed
-        for ( auto* p : npi->traffic_policy->removed_ilist )
-        {
-            PHGlobal& phg = get_thread_local_plugin(p->pp_class.api);
-            if ( phg.instance_initialized )
-            {
-                p->handler->tterm();
-                phg.instance_initialized = false;
-            }
-        }
+        npi->traffic_policy->tterm_removed();
     }
 
     // pin->tinit() only called for default policy
@@ -1030,15 +1208,7 @@ void InspectorManager::thread_stop_removed(const SnortConfig* sc)
     if ( pi && pi->framework_policy )
     {
         // Call pin->tterm() for anything that has been initialized and removed
-        for ( auto* p : pi->framework_policy->removed_ilist )
-        {
-            PHGlobal& phg = get_thread_local_plugin(p->pp_class.api);
-            if ( phg.instance_initialized )
-            {
-                p->handler->tterm();
-                phg.instance_initialized = false;
-            }
-        }
+        pi->framework_policy->tterm_removed();
     }
 }
 
@@ -1048,45 +1218,24 @@ void InspectorManager::thread_stop(const SnortConfig* sc)
     if ( !s_tl_handlers )
         return;
 
-    // pin->tterm() only called for default policy
     set_default_policy(sc);
-    if (sc->flow_tracking)
-    {
-        PHGlobal& phg = get_thread_local_plugin(sc->flow_tracking->pp_class.api);
-        if ( phg.instance_initialized )
-        {
-            sc->flow_tracking->handler->tterm();
-            phg.instance_initialized = false;
-        }
-    }
+    SingleInstanceInspectorPolicy* fid = sc->policy_map->get_file_id();
+    fid->tterm();
+    SingleInstanceInspectorPolicy* ft = sc->policy_map->get_flow_tracking();
+    ft->tterm();
+
+    GlobalInspectorPolicy* pp = sc->policy_map->get_global_inspector_policy();
+    pp->tterm();
 
     InspectionPolicy* pi = get_inspection_policy();
     if ( pi && pi->framework_policy )
-    {
-        for ( auto* p : pi->framework_policy->ilist )
-        {
-            PHGlobal& phg = get_thread_local_plugin(p->pp_class.api);
-            if ( phg.instance_initialized )
-            {
-                p->handler->tterm();
-                phg.instance_initialized = false;
-            }
-        }
-    }
+        pi->framework_policy->tterm();
 
     for ( unsigned i = 0; i < sc->policy_map->network_policy_count(); i++)
     {
         NetworkPolicy* npi = sc->policy_map->get_network_policy(i);
         set_network_policy(npi);
-        for ( auto* p : npi->traffic_policy->ilist )
-        {
-            PHGlobal& phg = get_thread_local_plugin(p->pp_class.api);
-            if ( phg.instance_initialized )
-            {
-                p->handler->tterm();
-                phg.instance_initialized = false;
-            }
-        }
+        npi->traffic_policy->tterm();
     }
 }
 
@@ -1127,36 +1276,48 @@ void InspectorManager::instantiate(
     else
     {
         PHInstance* ppi;
-        if (Module::GLOBAL == mod->get_usage() && IT_STREAM == api->type)
+        if (Module::GLOBAL == mod->get_usage() && IT_FILE == api->type)
         {
-            assert(sc);
-            if (sc->flow_tracking)
+            SingleInstanceInspectorPolicy* fid = sc->policy_map->get_file_id();
+            assert(fid);
+            if (!fid->get_new(sc, mod, *ppc, ppi))
             {
-                ParseError("Only one flow tracking inspector may be instantiated\n");
+                ParseError("Only one file identification inspector may be instantiated\n");
                 return;
             }
-            ppi = new PHInstance(*ppc, sc, mod);
-            if ( ppi->handler )
-                sc->flow_tracking = ppi;
-            else
+        }
+        else if (Module::GLOBAL == mod->get_usage() && IT_STREAM == api->type)
+        {
+            SingleInstanceInspectorPolicy* ft = sc->policy_map->get_flow_tracking();
+            assert(ft);
+            if (!ft->get_new(sc, mod, *ppc, ppi))
             {
-                delete ppi;
-                ppi = nullptr;
+                ParseError("Only one flow tracking inspector may be instantiated\n");
+                return;
             }
         }
         else
         {
-            InspectorList* il;
-            if (Module::CONTEXT == mod->get_usage())
-                il = get_network_policy()->traffic_policy;
-            else
-                il = get_inspection_policy()->framework_policy;
-            assert(il);
-
             if ( name )
                 keyword = name;
-
-            ppi = get_new(ppc, il, keyword, mod, sc);
+            if (Module::GLOBAL == mod->get_usage() && IT_SERVICE != api->type)
+            {
+                GlobalInspectorPolicy* il = sc->policy_map->get_global_inspector_policy();
+                assert(il);
+                ppi = get_new(ppc, il, keyword, mod, sc);
+            }
+            else if (Module::CONTEXT == mod->get_usage())
+            {
+                TrafficPolicy* il = get_network_policy()->traffic_policy;
+                assert(il);
+                ppi = get_new(ppc, il, keyword, mod, sc);
+            }
+            else
+            {
+                FrameworkPolicy* il = get_inspection_policy()->framework_policy;
+                assert(il);
+                ppi = get_new(ppc, il, keyword, mod, sc);
+            }
         }
 
         if ( ppi )
@@ -1255,6 +1416,18 @@ static bool configure(SnortConfig* sc, InspectorList* il, bool cloned, bool& new
     return ok;
 }
 
+Inspector* InspectorManager::acquire_file_inspector()
+{
+    Inspector* pi = get_file_inspector();
+
+    if ( !pi )
+        FatalError("unconfigured file inspector\n");
+    else
+        pi->add_global_ref();
+
+    return pi;
+}
+
 Inspector* InspectorManager::acquire(const char* key, bool dflt_only)
 {
     Inspector* pi = get_inspector(key, dflt_only);
@@ -1297,8 +1470,14 @@ bool InspectorManager::configure(SnortConfig* sc, bool cloned)
     }
     ::set_network_policy(sc);
 
-    if (sc->flow_tracking)
-        ok = sc->flow_tracking->handler->configure(sc) && ok;
+    SingleInstanceInspectorPolicy* fid = sc->policy_map->get_file_id();
+    fid->configure(sc);
+
+    SingleInstanceInspectorPolicy* ft = sc->policy_map->get_flow_tracking();
+    ft->configure(sc);
+
+    GlobalInspectorPolicy* pp = sc->policy_map->get_global_inspector_policy();
+    ok = ::configure(sc, pp, cloned, new_ins, reenabled_ins) && ok;
 
     ::set_inspection_policy(sc);
     for ( unsigned idx = 0; idx < sc->policy_map->inspection_policy_count(); ++idx )
@@ -1356,12 +1535,22 @@ void InspectorManager::sort_inspector_list(const InspectorList* il,
 
 void InspectorManager::print_config(SnortConfig* sc)
 {
-    if (sc->flow_tracking)
+    SingleInstanceInspectorPolicy* fid = sc->policy_map->get_file_id();
+    fid->print_config(sc, "File Identification");
+    SingleInstanceInspectorPolicy* ft = sc->policy_map->get_flow_tracking();
+    ft->print_config(sc, "Flow Tracking");
+
+    GlobalInspectorPolicy* pp = sc->policy_map->get_global_inspector_policy();
+    if (!pp->ilist.empty())
     {
-        LogLabel("Flow Tracking");
-        const std::string name = generate_inspector_label(sc->flow_tracking);
-        LogLabel(name.c_str());
-        sc->flow_tracking->handler->show(sc);
+        LogLabel("Global Inspectors");
+        std::map<const std::string, const PHInstance*> pp_sorted_ilist;
+        sort_inspector_list(pp, pp_sorted_ilist);
+        for ( const auto& p : pp_sorted_ilist )
+        {
+            LogLabel(p.first.c_str());
+            p.second->handler->show(sc);
+        }
     }
 
     const auto shell_number = sc->policy_map->shells_count();
@@ -1543,8 +1732,12 @@ void InspectorManager::internal_execute(Packet* p)
     }
 
     const SnortConfig* sc = p->context->conf;
-    if ( !p->has_paf_payload() && sc->flow_tracking )
-        ::execute<T>(p, &sc->flow_tracking, 1);
+    if ( !p->has_paf_payload() )
+    {
+        SingleInstanceInspectorPolicy* ft = sc->policy_map->get_flow_tracking();
+        if (ft->instance )
+            ::execute<T>(p, &ft->instance, 1);
+    }
 
     // must check between each ::execute()
     if ( p->disable_inspect )
@@ -1620,11 +1813,11 @@ void InspectorManager::internal_execute(Packet* p)
 
 void InspectorManager::probe(Packet* p)
 {
-    InspectionPolicy* policy = p->context->conf->policy_map->get_inspection_policy(0);
-    FrameworkPolicy* fp = policy->framework_policy;
+    GlobalInspectorPolicy* pp = p->context->conf->policy_map->get_global_inspector_policy();
+    assert(pp);
 
     if ( !trace_enabled(snort_trace, TRACE_INSPECTOR_MANAGER, DEFAULT_TRACE_LOG_LEVEL, p) )
-        ::execute<false>(p, fp->probe.vec, fp->probe.num, true);
+        ::execute<false>(p, pp->probe.vec, pp->probe.num, true);
     else
     {
         Stopwatch<SnortClock> timer;
@@ -1635,7 +1828,7 @@ void InspectorManager::probe(Packet* p)
 
         timer.start();
 
-        ::execute<true>(p, fp->probe.vec, fp->probe.num, true);
+        ::execute<true>(p, pp->probe.vec, pp->probe.num, true);
 
         trace_ulogf(snort_trace, TRACE_INSPECTOR_MANAGER, p,
             "end inspection, %s, packet %" PRId64", context %" PRId64", total time: %" PRId64" usec\n",
index 45b684a4947270c9b377fb8613789a535669336e..da76869a2e61c88f99895cb156a634636e690c0a 100644 (file)
 #include "framework/inspector.h"
 
 class Binder;
+class SingleInstanceInspectorPolicy;
 struct InspectorList;
 struct InspectionPolicy;
 struct NetworkPolicy;
 struct PHInstance;
+struct GlobalInspectorPolicy;
 
 namespace snort
 {
@@ -67,9 +69,13 @@ public:
 
     static bool delete_inspector(SnortConfig*, const char* iname);
     static void free_inspector(Inspector*);
-    static void free_flow_tracking(PHInstance*);
+    static SingleInstanceInspectorPolicy* create_single_instance_inspector_policy();
+    static void destroy_single_instance_inspector(SingleInstanceInspectorPolicy*);
+    static GlobalInspectorPolicy* create_global_inspector_policy(GlobalInspectorPolicy* = nullptr);
+    static void destroy_global_inspector_policy(GlobalInspectorPolicy*, bool cloned);
     static InspectSsnFunc get_session(uint16_t proto);
 
+    SO_PUBLIC static Inspector* get_file_inspector(const SnortConfig* = nullptr);
     SO_PUBLIC static Inspector* get_inspector(
         const char* key, bool dflt_only = false, const SnortConfig* = nullptr);
 
@@ -78,6 +84,7 @@ public:
 
     SO_PUBLIC static Binder* get_binder();
 
+    SO_PUBLIC static Inspector* acquire_file_inspector();
     SO_PUBLIC static Inspector* acquire(const char* key, bool dflt_only = false);
     SO_PUBLIC static void release(Inspector*);
 
index 45085e3af846944d2e9e67231d12c7cbff01a344..27df15f016da845bff4988be08d8d76a072d4025 100644 (file)
@@ -61,25 +61,26 @@ void PolicySelectorManager::release_plugins()
 void PolicySelectorManager::instantiate(const PolicySelectorApi* api, Module* mod, SnortConfig* sc)
 {
     assert(sc);
-    if (sc->global_selector)
+    if (sc->policy_map->get_policy_selector())
     {
         ParseError("Only one selector may be instantiated\n");
         return;
     }
     assert(api);
-    sc->global_selector = api->ctor(mod);
+    sc->policy_map->set_policy_selector(api->ctor(mod));
 }
 
 void PolicySelectorManager::print_config(const SnortConfig* sc)
 {
     assert(sc);
-    if (sc->global_selector)
+    const PolicySelector* ps = sc->policy_map->get_policy_selector();
+    if (ps)
     {
         LogLabel("Policy Selector");
-        std::string name = sc->global_selector->get_api()->base.name;
+        std::string name = ps->get_api()->base.name;
         name += ":";
         LogLabel(name.c_str());
-        sc->global_selector->show();
+        ps->show();
     }
 }
 
index a6b93faa422eb4360d7be84499c74e261ff3f9b4..ae1c455e86b91f1c51acf40a882f4146dca2017c 100644 (file)
@@ -259,7 +259,7 @@ bool AppIdApi::is_inspection_needed(const Inspector& inspector) const
         return false;
 
     SnortProtocolId id = inspector.get_service();
-    AppIdConfig& config = appid_inspector->get_ctxt().config;
+    const AppIdConfig& config = appid_inspector->get_ctxt().config;
     if (id == config.snort_proto_ids[PROTO_INDEX_HTTP2] or id == config.snort_proto_ids[PROTO_INDEX_SSH])
         return true;
 
index 800d01bce22035c69fe442eb1a4d13630282f027..b2033df98240ffd44296c2bf5deef350ba625910 100644 (file)
@@ -91,7 +91,7 @@ StreamSplitter::Status Http2DataCutter::scan(const uint8_t* data, uint32_t lengt
     uint32_t* flush_offset, uint32_t& data_offset, uint8_t frame_flags)
 {
     Http2Stream* const stream = session_data->find_stream(session_data->current_stream[source_id]);
-        
+
     if (!stream or !stream->is_open(source_id) or stream->is_discard_set(source_id))
         return skip_over_frame(stream, length, flush_offset, data_offset, frame_flags);
 
@@ -164,7 +164,7 @@ StreamSplitter::Status Http2DataCutter::scan(const uint8_t* data, uint32_t lengt
             // here
             assert(false);
             stream->set_state(source_id, STREAM_ERROR);
-            return skip_over_frame(stream, length, flush_offset, data_offset, frame_flags);        
+            return skip_over_frame(stream, length, flush_offset, data_offset, frame_flags);
         }
     }
 
@@ -193,7 +193,6 @@ StreamSplitter::Status Http2DataCutter::scan(const uint8_t* data, uint32_t lengt
             {
                 session_data->stream_in_hi = session_data->current_stream[source_id];
                 session_data->hi_ss[source_id]->prep_partial_flush(session_data->flow, 0);
-                session_data->stream_in_hi = NO_STREAM_ID;
             }
             else
             {
@@ -317,7 +316,7 @@ void Http2DataCutter::discarded_frame_cleanup(Http2Stream* const stream)
     frame_bytes_seen = 0;
     reassemble_data_bytes_read = 0;
     reassemble_state = GET_FRAME_HDR;
-    
+
     if (!stream->is_end_stream_on_data_flush(source_id))
         return;
 
index 16d53eae130bdd2bd57f11b248fb8760c5d93577..61076238c29108c2c67fd72703d20c9aedb6f151 100644 (file)
@@ -41,7 +41,6 @@ bool File::convert(std::istringstream& data_stream)
     std::string args;
     bool retval = true;
 
-    table_api.open_table("file_id");
     while (util::get_string(data_stream, args, ","))
     {
         std::istringstream arg_stream(args);
@@ -53,61 +52,85 @@ bool File::convert(std::istringstream& data_stream)
 
         else if (keyword == "file_capture_memcap")
         {
+            table_api.open_table("file_id");
             table_api.add_diff_option_comment("config file: file_capture_memcap", "capture_memcap");
             tmpval = parse_int_option("capture_memcap", arg_stream, false);
+            table_api.close_table();
         }
         else if (keyword == "file_capture_max")
         {
+            table_api.open_table("file_id");
             table_api.add_diff_option_comment("config file: file_capture_max", "capture_max_size");
             tmpval = parse_int_option("capture_max_size", arg_stream, false);
+            table_api.close_table();
         }
 
         else if (keyword == "file_capture_min")
         {
+            table_api.open_table("file_id");
             table_api.add_diff_option_comment("config file: file_capture_min", "capture_min_size");
             tmpval = parse_int_option("capture_min_size", arg_stream, false);
+            table_api.close_table();
         }
 
         else if (keyword == "file_capture_block_size")
         {
+            table_api.open_table("file_id");
             table_api.add_diff_option_comment("config file: file_capture_block_size", "capture_block_size");
             tmpval = parse_int_option("capture_block_size", arg_stream, false);
+            table_api.close_table();
         }
 
         else if (keyword == "show_data_depth")
+        {
+            table_api.open_table("file_id");
             tmpval = parse_int_option("show_data_depth", arg_stream, false);
+            table_api.close_table();
+        }
 
         else if (keyword == "type_id")
         {
+            table_api.open_table("file_policy");
             table_api.add_diff_option_comment("config file: type_id", "enable_type");
             table_api.add_option("enable_type", true);
+            table_api.close_table();
         }
         else if (keyword == "signature")
         {
+            table_api.open_table("file_policy");
             table_api.add_diff_option_comment("config file: signature", "enable_signature");
             table_api.add_option("enable_signature", true);
+            table_api.close_table();
         }
         else if (keyword == "file_type_depth")
         {
+            table_api.open_table("file_id");
             table_api.add_diff_option_comment("config file: file_type_depth", "type_depth");
             tmpval = parse_int_option("type_depth", arg_stream, false);
+            table_api.close_table();
         }
         else if (keyword == "file_signature_depth")
         {
+            table_api.open_table("file_id");
             table_api.add_diff_option_comment("config file: file_signature_depth",
                 "signature_depth");
             tmpval = parse_int_option("signature_depth", arg_stream, false);
+            table_api.close_table();
         }
         else if (keyword == "file_block_timeout")
         {
+            table_api.open_table("file_id");
             table_api.add_diff_option_comment("config file: file_block_timeout", "block_timeout");
             tmpval = parse_int_option("block_timeout", arg_stream, false);
+            table_api.close_table();
         }
         else if (keyword == "file_lookup_timeout")
         {
+            table_api.open_table("file_id");
             table_api.add_diff_option_comment("config file: file_lookup_timeout",
                 "lookup_timeout");
             tmpval = parse_int_option("lookup_timeout", arg_stream, false);
+            table_api.close_table();
         }
         else
             tmpval = false;
@@ -117,7 +140,9 @@ bool File::convert(std::istringstream& data_stream)
     }
 
     // Always add the file_rules option to reference the file magic rules.
+    table_api.open_table("file_id");
     table_api.add_option("file_rules", "$file_magic");
+    table_api.close_table();
 
     return retval;
 }