]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1062 in SNORT/snort3 from file_api_fw to master
authorHui Cao (huica) <huica@cisco.com>
Tue, 7 Nov 2017 17:04:14 +0000 (12:04 -0500)
committerHui Cao (huica) <huica@cisco.com>
Tue, 7 Nov 2017 17:04:14 +0000 (12:04 -0500)
Squashed commit of the following:

commit 49a45a058c9a86b51050f4068a5aa5e631a1555b
Author: huica <huica@cisco.com>
Date:   Fri Nov 3 16:49:47 2017 -0400

    File policy and file config update to allow user define customized file
    policy through file api

23 files changed:
src/detection/signature.cc
src/file_api/file_api.h
src/file_api/file_cache.cc
src/file_api/file_capture.cc
src/file_api/file_capture.h
src/file_api/file_enforcer.cc
src/file_api/file_enforcer.h
src/file_api/file_flows.cc
src/file_api/file_flows.h
src/file_api/file_lib.cc
src/file_api/file_lib.h
src/file_api/file_policy.cc
src/file_api/file_policy.h
src/file_api/file_segment.cc
src/file_api/file_segment.h
src/filters/rate_filter.cc
src/hash/test/ghash_test.cc
src/ips_options/test/ips_regex_test.cc
src/loggers/alert_sf_socket.cc
src/main/snort_config.h
src/profiler/rule_profiler.cc
src/search_engines/test/hyperscan_test.cc
src/search_engines/test/search_tool_test.cc

index 828f098ff400bcaad3f51bd06fa069e8b07a1901..b691e488a3b9ed708df22ba3aa5e59dd318ea54c 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "signature.h"
 
+#include "hash/ghash.h"
 #include "log/messages.h"
 #include "main/snort_config.h"
 #include "parser/parser.h"
index 217ba26e987c9d0bdf04d29ad91c53b7f5a62407..5d151142d1687f96ebd13af3e550e176fc8ffc33 100644 (file)
@@ -111,8 +111,29 @@ struct FileState
 
 class FileContext;
 struct FileCaptureInfo;
+class Flow;
+class FileInfo;
 
-#define DEFAULT_FILE_ID   0
+class SO_PUBLIC FilePolicyBase
+{
+public:
+
+    FilePolicyBase() = default;
+    // This is called when a new flow is queried for the first time
+    // Check & update what file policy is enabled on this flow/file
+    virtual void policy_check(Flow*, FileInfo* ) { }
+
+    // This is called after file type is known
+    virtual FileVerdict type_lookup(Flow*, FileInfo*)
+    { return FILE_VERDICT_UNKNOWN; }
+
+    // This is called after file signature is complete
+    virtual FileVerdict signature_lookup(Flow*, FileInfo*)
+    { return FILE_VERDICT_UNKNOWN; }
+
+    virtual void log_file_action(Flow*, int) { }
+
+};
 
 inline void initFilePosition(FilePosition* position, uint64_t processed_size)
 {
index e4136a200a3a35ea7e88d5eb1d22a1f8cfa110cf..6ccf3f6724be7d7724668f8a8c791f538f0a9b8b 100644 (file)
@@ -44,7 +44,13 @@ static int file_cache_free_func(void*, void* data)
 
 FileCache::FileCache()
 {
-    int max_files = SnortConfig::get_conf()->file_config.max_files_cached;
+    FileConfig* conf = get_file_config();
+    int max_files;
+    if (conf)
+        max_files = conf->max_files_cached;
+    else
+        max_files = DEFAULT_MAX_FILES_CACHED;
+
     fileHash = xhash_new(max_files, sizeof(FileHashKey), sizeof(FileNode),
         0, 1, nullptr, file_cache_free_func, 1);
     if (!fileHash)
index 98d36380eb51d3485b1d337924911ba892cdc1a4..4b2d6cb850a9d7aaade5d39312c73b0b7e820764 100644 (file)
@@ -82,7 +82,6 @@ void FileCapture::writer_thread()
 
 FileCapture::FileCapture(int64_t min_size, int64_t max_size)
 {
-    reserved = false;
     capture_size = 0;
     last = head = nullptr;
     current_data = nullptr;
@@ -96,7 +95,7 @@ FileCapture::~FileCapture()
 {
     FileCaptureBlock* file_block = head;
 
-    if (reserved)
+    if (file_info)
         file_counts.files_released_total++;
     else
         file_counts.files_freed_total++;
@@ -104,7 +103,7 @@ FileCapture::~FileCapture()
     while (file_block)
     {
         FileCaptureBlock* next_block = file_block->next;
-        if (reserved)
+        if (file_info)
         {
             if (file_mempool->m_release(file_block) != FILE_MEM_SUCCESS)
                 file_counts.file_buffers_release_errors++;
@@ -405,8 +404,6 @@ FileCaptureState FileCapture::reserve_file(const FileInfo* file)
 
     current_block = head;
 
-    reserved = true;
-
     file_info = new FileInfo(*file);
 
     return FILE_CAPTURE_SUCCESS;
index 9c3540c15135158d1501f8dddde17cc7b0f8549b..a88693f5ff725ff0a3c30b4c69285add407d1df5 100644 (file)
@@ -64,9 +64,6 @@ public:
     // Preserve the file in memory until it is released
     FileCaptureState reserve_file(const FileInfo*);
 
-    // Whether file is reserved for store or analysis
-    bool is_reserved() { return reserved; }
-
     // Get the file that is reserved in memory, this should be called repeatedly
     // until nullptr is returned to get the full file
     // Returns:
@@ -108,7 +105,6 @@ private:
     static std::queue<FileCapture*> files_waiting;
     static bool running;
 
-    bool reserved;
     uint64_t capture_size;
     FileCaptureBlock* last;  /* last block of file data */
     FileCaptureBlock* head;  /* first block of file data */
index 5453e2dfff4dea7d6203898c6abde50f26325779..db5205620105b6331f4bf985d8e6ec83b0d9f2bd 100644 (file)
@@ -67,16 +67,16 @@ void FileEnforcer::update_file_node(FileNode* node, FileInfo* file)
 }
 
 FileVerdict FileEnforcer::check_verdict(Flow* flow, FileNode* node,
-    XHashNode* hash_node, FilePolicy& inspect)
+    XHashNode* hash_node, FilePolicyBase* policy)
 {
     assert(node->file);
 
-    FileVerdict verdict = inspect.type_lookup(flow, node->file);
+    FileVerdict verdict = policy->type_lookup(flow, node->file);
 
     if ((verdict == FILE_VERDICT_UNKNOWN) ||
         (verdict == FILE_VERDICT_STOP_CAPTURE))
     {
-        verdict = inspect.signature_lookup(flow, node->file);
+        verdict = policy->signature_lookup(flow, node->file);
     }
 
     if ((verdict == FILE_VERDICT_UNKNOWN) ||
@@ -157,18 +157,26 @@ int FileEnforcer::store_verdict(Flow* flow, FileInfo* file)
     return 0;
 }
 
-bool FileEnforcer::apply_verdict(Flow* flow, FileInfo* file, FileVerdict verdict)
+bool FileEnforcer::apply_verdict(Flow* flow, FileInfo* file, FileVerdict verdict,
+    bool resume, FilePolicyBase* policy)
 {
     if ( verdict == FILE_VERDICT_UNKNOWN )
         return false;
 
     file->verdict = verdict;
 
-    if (verdict == FILE_VERDICT_BLOCK)
+    if (verdict == FILE_VERDICT_LOG)
+    {
+        if (resume)
+            policy->log_file_action(flow, FILE_RESUME_LOG);
+    }
+    else if (verdict == FILE_VERDICT_BLOCK)
     {
         // can't block session inside a session
         Active::set_delayed_action(Active::ACT_BLOCK, true);
         store_verdict(flow, file);
+        if (resume)
+            policy->log_file_action(flow, FILE_RESUME_BLOCK);
         return true;
     }
     else if (verdict == FILE_VERDICT_REJECT)
@@ -176,12 +184,16 @@ bool FileEnforcer::apply_verdict(Flow* flow, FileInfo* file, FileVerdict verdict
         // can't reset session inside a session
         Active::set_delayed_action(Active::ACT_RESET, true);
         store_verdict(flow, file);
+        if (resume)
+            policy->log_file_action(flow, FILE_RESUME_BLOCK);
         return true;
     }
     else if (verdict == FILE_VERDICT_PENDING)
     {
         /*Take the cached verdict*/
         Active::set_delayed_action(Active::ACT_DROP, true);
+        if (resume)
+            policy->log_file_action(flow, FILE_RESUME_BLOCK);
         return true;
     }
 
@@ -189,7 +201,7 @@ bool FileEnforcer::apply_verdict(Flow* flow, FileInfo* file, FileVerdict verdict
 }
 
 FileVerdict FileEnforcer::cached_verdict_lookup(Flow* flow, FileInfo* file,
-    FilePolicy& inspect)
+    FilePolicyBase* policy)
 {
     FileVerdict verdict = FILE_VERDICT_UNKNOWN;
     XHashNode* hash_node;
@@ -233,7 +245,8 @@ FileVerdict FileEnforcer::cached_verdict_lookup(Flow* flow, FileInfo* file,
             return verdict;
         }
         /*Query the file policy in case verdict has been changed*/
-        verdict = check_verdict(flow, node, hash_node, inspect);
+        verdict = check_verdict(flow, node, hash_node, policy);
+        apply_verdict(flow, node->file, verdict, true, policy);
     }
 
     return verdict;
index d05785df6adb9750223172a7488a5d8fc6dc786a..14700ac60449ad9ae130dd1565cb8b275f2b3239 100644 (file)
@@ -49,8 +49,8 @@ public:
 
     FileEnforcer();
     ~FileEnforcer();
-    FileVerdict cached_verdict_lookup(Flow*, FileInfo*, FilePolicy&);
-    bool apply_verdict(Flow*, FileInfo*, FileVerdict);
+    FileVerdict cached_verdict_lookup(Flow*, FileInfo*, FilePolicyBase*);
+    bool apply_verdict(Flow*, FileInfo*, FileVerdict, bool resume, FilePolicyBase*);
 
 private:
 // FIXIT-L Merge definition with duplicate in file_cache.h?
@@ -65,7 +65,7 @@ PADDING_GUARD_BEGIN
 PADDING_GUARD_END
 
     void update_file_node(FileNode*, FileInfo*);
-    FileVerdict check_verdict(Flow*, FileNode*, XHashNode*, FilePolicy&);
+    FileVerdict check_verdict(Flow*, FileNode*, XHashNode*, FilePolicyBase*);
     int store_verdict(Flow*, FileInfo*);
 
     /* The hash table of expected files */
index b79ea40afa37e6f52ae0e2ad9b1d1dbe8255f526..9b8edcbbccf5ed9278bdbe1b876294f2b3ed6fe0 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "file_flows.h"
 
+#include "main/snort_config.h"
 #include "managers/inspector_manager.h"
 #include "protocols/packet.h"
 
@@ -47,15 +48,36 @@ FileFlows* FileFlows::get_file_flows(Flow* flow)
     if (fd)
         return fd;
 
-    if (FileService::is_file_service_enabled())
+    FileInspect* fi = (FileInspect*)InspectorManager::get_inspector(FILE_ID_NAME);
+
+    if (FileService::is_file_service_enabled() and fi)
     {
-        fd = new FileFlows(flow);
+        fd = new FileFlows(flow, fi);
         flow->set_flow_data(fd);
     }
+    else
+        return fd;
+
+    FileConfig* fc = fi->config;
+    if (fc and fd)
+    {
+        fd->set_file_config(fc);
+        fd->set_file_policy(&(fc->get_file_policy()));
+    }
 
     return fd;
 }
 
+FilePolicyBase* FileFlows::get_file_policy(Flow* flow)
+{
+    FileFlows* fd = (FileFlows*)flow->get_flow_data(FileFlows::file_flow_data_id);
+
+    if (fd)
+        return fd->get_file_policy(flow);
+
+    return nullptr;
+}
+
 void FileFlows::set_current_file_context(FileContext* ctx)
 {
     current_context = ctx;
@@ -101,7 +123,7 @@ FileContext* FileFlows::find_main_file_context(FilePosition pos, FileDirection d
 
     context = new FileContext;
     main_context = context;
-    context->check_policy(flow, dir);
+    context->check_policy(flow, dir, file_policy);
 
     if (!index)
         context->set_file_id(get_new_file_instance());
@@ -155,25 +177,26 @@ bool FileFlows::file_process(uint64_t file_id, const uint8_t* file_data,
 
     if (!context->get_processed_bytes())
     {
-        context->check_policy(flow, dir);
+        context->check_policy(flow, dir, file_policy);
         context->set_file_id(file_id);
     }
 
     if (context->verdict != FILE_VERDICT_UNKNOWN)
     {
         /*A new file session, but policy might be different*/
-        context->check_policy(flow, dir);
+        context->check_policy(flow, dir, file_policy);
 
         if ((context->get_file_sig_sha256())
             || !context->is_file_signature_enabled())
         {
             /* Just check file type and signature */
             FilePosition position = SNORT_FILE_FULL;
-            return context->process(flow, file_data, data_size, position);
+            return context->process(flow, file_data, data_size, position,
+                file_config, file_policy);
         }
     }
 
-    return context->process(flow, file_data, data_size, offset);
+    return context->process(flow, file_data, data_size, offset, file_config, file_policy);
 }
 
 /*
@@ -198,7 +221,7 @@ bool FileFlows::file_process(const uint8_t* file_data, int data_size,
     set_current_file_context(context);
 
     context->set_signature_state(gen_signature);
-    return context->process(flow, file_data, data_size, position);
+    return context->process(flow, file_data, data_size, position, file_config, file_policy);
 }
 
 void FileFlows::set_file_name(const uint8_t* fname, uint32_t name_size)
@@ -212,7 +235,7 @@ void FileFlows::set_file_name(const uint8_t* fname, uint32_t name_size)
         if (fname and name_size)
             context->set_file_name((const char*)fname, name_size);
 
-        context->log_file_event(flow);
+        context->log_file_event(flow, file_config);
     }
 }
 
index e5927046948fa8fa9f59c6051e990face2532de6..7da42962be183e41814fca177da9b8642e455786 100644 (file)
 #include "main/snort_types.h"
 
 #include "file_api.h"
+#include "file_config.h"
 #include "file_module.h"
+#include "file_policy.h"
 
 class FileContext;
 class Flow;
 class FileConfig;
 
+class FileInspect : public Inspector
+{
+public:
+    FileInspect(FileIdModule*);
+    ~FileInspect() override;
+    void eval(Packet*) override { }
+
+    FileConfig* config;
+};
+
 class SO_PUBLIC FileFlows : public FlowData
 {
 public:
 
-    FileFlows(Flow* f) : FlowData(file_flow_data_id), flow(f) { }
+    FileFlows(Flow* f, FileInspect* inspect) : FlowData(file_flow_data_id, inspect), flow(f) { }
     ~FileFlows() override;
     static void init()
     { file_flow_data_id = FlowData::create_flow_data_id(); }
 
     // Factory method to get file flows
     static FileFlows* get_file_flows(Flow*);
+    static FilePolicyBase* get_file_policy(Flow*);
 
     FileContext* get_current_file_context();
 
@@ -72,6 +85,11 @@ public:
     //void handle_retransmit(Packet*) override;
     static unsigned file_flow_data_id;
 
+    void set_file_config(FileConfig* fc) { file_config = fc; }
+
+    void set_file_policy(FilePolicyBase* fp) { file_policy = fp; }
+    FilePolicyBase* get_file_policy() { return file_policy; }
+
 private:
     void init_file_context(FileDirection, FileContext*);
     FileContext* find_main_file_context(FilePosition, FileDirection, size_t id = 0);
@@ -82,16 +100,8 @@ private:
     uint64_t current_file_id = 0;
     bool gen_signature = false;
     Flow* flow = nullptr;
-};
-
-class FileInspect : public Inspector
-{
-public:
-    FileInspect(FileIdModule*);
-    ~FileInspect() override;
-    void eval(Packet*) override { }
-
-    FileConfig* config;
+    FileConfig* file_config = nullptr;
+    FilePolicyBase* file_policy = nullptr;
 };
 
 #endif
index fbcc55e14db0b1e97393a5bce764c54746467882..a7a719a739f1a410b49be998bb79c7abb3568180 100644 (file)
@@ -105,6 +105,12 @@ void FileInfo::copy(const FileInfo& other)
     file_id = other.file_id;
     file_name = other.file_name;
     verdict = other.verdict;
+    file_type_enabled = other.file_type_enabled;
+    file_signature_enabled = other.file_signature_enabled;
+    file_capture_enabled = other.file_capture_enabled;
+    file_state = other.file_state;
+    // only one copy of file capture
+    file_capture = nullptr;
 }
 
 FileInfo::FileInfo(const FileInfo& other)
@@ -199,14 +205,54 @@ std::string FileInfo::sha_to_string(const uint8_t* sha256)
     return sha_out;
 }
 
+void FileInfo::config_file_type(bool enabled)
+{
+    file_type_enabled = enabled;
+}
+
+bool FileInfo::is_file_type_enabled()
+{
+    return file_type_enabled;
+}
+
+void FileInfo::config_file_signature(bool enabled)
+{
+    file_signature_enabled = enabled;
+}
+
+bool FileInfo::is_file_signature_enabled()
+{
+    return file_signature_enabled;
+}
+
+void FileInfo::config_file_capture(bool enabled)
+{
+    file_capture_enabled = enabled;
+}
+
+bool FileInfo::is_file_capture_enabled()
+{
+    return file_capture_enabled;
+}
+
+FileCaptureState FileInfo::reserve_file(FileCapture*& dest)
+{
+    if (!file_capture)
+        return FileCapture::error_capture(FILE_CAPTURE_FAIL);
+
+    FileCaptureState state = file_capture->reserve_file(this);
+    config_file_capture(false);
+    dest = file_capture;
+    file_capture = nullptr;
+    return state;
+}
+
 FileContext::FileContext ()
 {
     file_type_context = nullptr;
     file_signature_context = nullptr;
     file_capture = nullptr;
     file_segments = nullptr;
-    inspector = (FileInspect*)InspectorManager::acquire(FILE_ID_NAME, SnortConfig::get_conf());
-    file_config = inspector->config;
 }
 
 FileContext::~FileContext ()
@@ -217,21 +263,20 @@ FileContext::~FileContext ()
         stop_file_capture();
     if (file_segments)
         delete file_segments;
-    InspectorManager::release(inspector);
 }
 
 inline int FileContext::get_data_size_from_depth_limit(FileProcessType type, int
-    data_size)
+    data_size, FileConfig* config)
 {
     uint64_t max_depth;
 
     switch (type)
     {
     case SNORT_FILE_TYPE_ID:
-        max_depth = file_config->file_type_depth;
+        max_depth = config->file_type_depth;
         break;
     case SNORT_FILE_SHA256:
-        max_depth = file_config->file_signature_depth;
+        max_depth = config->file_signature_depth;
         break;
     default:
         return data_size;
@@ -253,7 +298,7 @@ inline void FileContext::finalize_file_type()
     file_type_context = nullptr;
 }
 
-void FileContext::log_file_event(Flow* flow)
+void FileContext::log_file_event(Flow* flow, FileConfig* config)
 {
     // wait for file name is set to log file event
     if ( is_file_name_set() )
@@ -276,8 +321,8 @@ void FileContext::log_file_event(Flow* flow)
         default:
             break;
         }
-        if ( file_config->trace_type )
-            print(std::cout);
+        if ( config->trace_type )
+            print(std::cout, config);
     }
 }
 
@@ -285,23 +330,25 @@ FileVerdict FileContext::file_signature_lookup(Flow* flow)
 {
     if (get_file_sig_sha256() && is_file_signature_enabled())
     {
-        FilePolicy& inspect = file_config->get_file_policy();
-        return inspect.signature_lookup(flow, this);
+        FilePolicyBase* policy = FileFlows::get_file_policy(flow);
+
+        if (policy)
+            return policy->signature_lookup(flow, this);
     }
-    else
-        return FILE_VERDICT_UNKNOWN;
+
+    return FILE_VERDICT_UNKNOWN;
 }
 
-void FileContext::finish_signature_lookup(Flow* flow, bool final_lookup)
+void FileContext::finish_signature_lookup(Flow* flow, bool final_lookup,
+    FileConfig* config, FilePolicyBase* policy)
 {
     if (get_file_sig_sha256())
     {
         //Check file type based on file policy
-        FilePolicy& inspect = file_config->get_file_policy();
-        FileVerdict verdict = inspect.signature_lookup(flow, this);
+        FileVerdict verdict = policy->signature_lookup(flow, this);
         if ( verdict != FILE_VERDICT_UNKNOWN || final_lookup )
         {
-            log_file_event(flow);
+            log_file_event(flow, config);
             config_file_signature(false);
             file_stats->signatures_processed[get_file_type()][get_file_direction()]++;
         }
@@ -313,12 +360,27 @@ void FileContext::finish_signature_lookup(Flow* flow, bool final_lookup)
     }
 }
 
-void FileContext::check_policy(Flow* flow, FileDirection dir)
+void FileContext::set_signature_state(bool gen_sig)
+{
+    if ( gen_sig )
+    {
+        if ( sha256 )
+        {
+            snort_free(sha256);
+            sha256 = nullptr;
+        }
+
+        file_state.sig_state = FILE_SIG_FLUSH;
+    }
+    else
+        file_state.sig_state = FILE_SIG_PROCESSING;
+}
+
+void FileContext::check_policy(Flow* flow, FileDirection dir, FilePolicyBase* policy)
 {
     file_counts.files_total++;
     set_file_direction(dir);
-    FilePolicy& inspect = file_config->get_file_policy();
-    inspect.policy_check(flow, this);
+    policy->policy_check(flow, this);
 }
 
 /*
@@ -327,12 +389,12 @@ void FileContext::check_policy(Flow* flow, FileDirection dir)
  *    false: ignore this file
  */
 bool FileContext::process(Flow* flow, const uint8_t* file_data, int data_size,
-    FilePosition position)
+    FilePosition position, FileConfig* config, FilePolicyBase* policy)
 {
-    if ( file_config->trace_stream )
+    if ( config->trace_stream )
     {
         FileContext::print_file_data(stdout, file_data, data_size,
-            file_config->show_data_depth);
+            config->show_data_depth);
     }
 
     file_counts.file_data_total += data_size;
@@ -344,13 +406,13 @@ bool FileContext::process(Flow* flow, const uint8_t* file_data, int data_size,
     }
 
     if ((FileService::get_file_enforcer()->cached_verdict_lookup(flow, this,
-        file_config->get_file_policy()) != FILE_VERDICT_UNKNOWN))
+        policy) != FILE_VERDICT_UNKNOWN))
         return true;
 
     /*file type id*/
     if (is_file_type_enabled())
     {
-        process_file_type(file_data, data_size, position);
+        process_file_type(file_data, data_size, position, config);
 
         /*Don't care unknown file type*/
         if (get_file_type() == SNORT_FILE_TYPE_UNKNOWN)
@@ -367,9 +429,8 @@ bool FileContext::process(Flow* flow, const uint8_t* file_data, int data_size,
             config_file_type(false);
             file_stats->files_processed[get_file_type()][get_file_direction()]++;
             //Check file type based on file policy
-            FilePolicy& inspect = file_config->get_file_policy();
-            inspect.type_lookup(flow, this);
-            log_file_event(flow);
+            policy->type_lookup(flow, this);
+            log_file_event(flow, config);
         }
     }
 
@@ -377,23 +438,23 @@ bool FileContext::process(Flow* flow, const uint8_t* file_data, int data_size,
     if (is_file_signature_enabled())
     {
         if (!sha256)
-            process_file_signature_sha256(file_data, data_size, position);
+            process_file_signature_sha256(file_data, data_size, position, config);
 
         file_stats->data_processed[get_file_type()][get_file_direction()]
             += data_size;
 
         update_file_size(data_size, position);
 
-        if ( file_config->trace_signature )
+        if ( config->trace_signature )
             print_file_sha256(std::cout);
 
         /*Fails to capture, when out of memory or size limit, need lookup*/
         if (is_file_capture_enabled())
         {
-            process_file_capture(file_data, data_size, position);
+            process_file_capture(file_data, data_size, position, config);
         }
 
-        finish_signature_lookup(flow, ( file_state.sig_state != FILE_SIG_FLUSH ) );
+        finish_signature_lookup(flow, ( file_state.sig_state != FILE_SIG_FLUSH ), config, policy);
     }
     else
     {
@@ -404,11 +465,11 @@ bool FileContext::process(Flow* flow, const uint8_t* file_data, int data_size,
 }
 
 bool FileContext::process(Flow* flow, const uint8_t* file_data, int data_size,
-    uint64_t offset)
+    uint64_t offset, FileConfig* config, FilePolicyBase* policy)
 {
     if (!file_segments)
         file_segments = new FileSegments(this);
-    return file_segments->process(flow, file_data, data_size, offset);
+    return file_segments->process(flow, file_data, data_size, offset, config, policy);
 }
 
 /*
@@ -421,7 +482,8 @@ bool FileContext::process(Flow* flow, const uint8_t* file_data, int data_size,
  * 3) file magics are exhausted in depth
  *
  */
-void FileContext::process_file_type(const uint8_t* file_data, int size, FilePosition position)
+void FileContext::process_file_type(const uint8_t* file_data, int size, FilePosition position,
+    FileConfig* config)
 {
     int data_size;
 
@@ -430,7 +492,7 @@ void FileContext::process_file_type(const uint8_t* file_data, int size, FilePosi
         return;
 
     /* Check whether file type depth is reached*/
-    data_size = get_data_size_from_depth_limit(SNORT_FILE_TYPE_ID, size);
+    data_size = get_data_size_from_depth_limit(SNORT_FILE_TYPE_ID, size, config);
 
     if (data_size < 0)
     {
@@ -439,7 +501,7 @@ void FileContext::process_file_type(const uint8_t* file_data, int size, FilePosi
     }
 
     file_type_id =
-        file_config->find_file_type_id(file_data, data_size, processed_bytes, &file_type_context);
+        config->find_file_type_id(file_data, data_size, processed_bytes, &file_type_context);
 
     /* Check whether file transfer is done or type depth is reached*/
     if ( (position == SNORT_FILE_END)  || (position == SNORT_FILE_FULL) ||
@@ -450,9 +512,9 @@ void FileContext::process_file_type(const uint8_t* file_data, int size, FilePosi
 }
 
 void FileContext::process_file_signature_sha256(const uint8_t* file_data, int size,
-    FilePosition position)
+    FilePosition position, FileConfig* config)
 {
-    int data_size = get_data_size_from_depth_limit(SNORT_FILE_SHA256, size);
+    int data_size = get_data_size_from_depth_limit(SNORT_FILE_SHA256, size, config);
 
     if (data_size != size)
     {
@@ -520,12 +582,12 @@ void FileContext::process_file_signature_sha256(const uint8_t* file_data, int si
 }
 
 FileCaptureState FileContext::process_file_capture(const uint8_t* file_data,
-    int data_size, FilePosition position)
+    int data_size, FilePosition position, FileConfig* config)
 {
     if (!file_capture)
     {
-        file_capture = new FileCapture(file_config->capture_min_size,
-            file_config->capture_max_size);
+        file_capture = new FileCapture(config->capture_min_size,
+            config->capture_max_size);
     }
 
     file_state.capture_state =
@@ -537,18 +599,6 @@ FileCaptureState FileContext::process_file_capture(const uint8_t* file_data,
     return file_state.capture_state;
 }
 
-FileCaptureState FileContext::reserve_file(FileCapture*& dest)
-{
-    if (!file_capture || !is_file_capture_enabled())
-        return FileCapture::error_capture(FILE_CAPTURE_FAIL);
-
-    FileCaptureState state = file_capture->reserve_file(this);
-    config_file_capture(false);
-    dest = file_capture;
-    file_capture = nullptr;
-    return state;
-}
-
 void FileContext::stop_file_capture()
 {
     if (file_capture)
@@ -557,7 +607,7 @@ void FileContext::stop_file_capture()
         file_capture = nullptr;
     }
 
-    file_capture_enabled = false;
+    config_file_capture(false);
 }
 
 void FileContext::update_file_size(int data_size, FilePosition position)
@@ -570,36 +620,6 @@ void FileContext::update_file_size(int data_size, FilePosition position)
     }
 }
 
-void FileContext::config_file_type(bool enabled)
-{
-    file_type_enabled = enabled;
-}
-
-bool FileContext::is_file_type_enabled()
-{
-    return file_type_enabled;
-}
-
-void FileContext::config_file_signature(bool enabled)
-{
-    file_signature_enabled = enabled;
-}
-
-bool FileContext::is_file_signature_enabled()
-{
-    return file_signature_enabled;
-}
-
-void FileContext::config_file_capture(bool enabled)
-{
-    file_capture_enabled = enabled;
-}
-
-bool FileContext::is_file_capture_enabled()
-{
-    return file_capture_enabled;
-}
-
 uint64_t FileContext::get_processed_bytes()
 {
     return processed_bytes;
@@ -722,10 +742,10 @@ void FileContext::print_file_name(std::ostream& log)
         snort_free(outbuf);
 }
 
-void FileContext::print(std::ostream& log)
+void FileContext::print(std::ostream& log, FileConfig* config)
 {
     print_file_name(log);
-    log << "File type: " << file_config->file_type_name(file_type_id)
+    log << "File type: " << config->file_type_name(file_type_id)
         << '('<< file_type_id  << ')' << std::endl;
     log << "File size: " << file_size << std::endl;
     log << "Processed size: " << processed_bytes << std::endl;
index 0e1960303927e0760049530591eec5846b159845..408b29fa957a8ef0a959cc6181a62bf1bfd31478 100644 (file)
@@ -62,6 +62,20 @@ public:
     size_t get_file_id() const;
     FileVerdict verdict = FILE_VERDICT_UNKNOWN;
 
+    // Configuration functions
+    void config_file_type(bool enabled);
+    bool is_file_type_enabled();
+    void config_file_signature(bool enabled);
+    bool is_file_signature_enabled();
+    void config_file_capture(bool enabled);
+    bool is_file_capture_enabled();
+
+    // Preserve the file in memory until it is released
+    // The file reserved will be returned and it will be detached from file context/session
+    FileCaptureState reserve_file(FileCapture*& dest);
+
+    FileState get_file_state() { return file_state; }
+
 protected:
     std::string file_name;
     bool file_name_set = false;
@@ -70,6 +84,11 @@ protected:
     uint32_t file_type_id = SNORT_FILE_TYPE_CONTINUE;
     uint8_t* sha256 = nullptr;
     size_t file_id = 0;
+    FileCapture* file_capture = nullptr;
+    bool file_type_enabled = false;
+    bool file_signature_enabled = false;
+    bool file_capture_enabled = false;
+    FileState file_state = { FILE_CAPTURE_SUCCESS, FILE_SIG_PROCESSING };
 
 private:
     void copy(const FileInfo& other);
@@ -81,51 +100,29 @@ public:
     FileContext();
     ~FileContext() override;
 
-    void check_policy(Flow*, FileDirection);
+    void check_policy(Flow*, FileDirection, FilePolicyBase*);
 
     // main processing functions
 
     // Return:
     //    true: continue processing/log/block this file
     //    false: ignore this file
-    bool process(Flow*, const uint8_t* file_data, int data_size, FilePosition);
-    bool process(Flow*, const uint8_t* file_data, int data_size, uint64_t offset);
-    void process_file_type(const uint8_t* file_data, int data_size, FilePosition position);
-    void process_file_signature_sha256(const uint8_t* file_data, int data_size, FilePosition pos);
+    bool process(Flow*, const uint8_t* file_data, int data_size, FilePosition,
+        FileConfig*, FilePolicyBase*);
+    bool process(Flow*, const uint8_t* file_data, int data_size, uint64_t offset,
+        FileConfig*, FilePolicyBase*);
+    void process_file_type(const uint8_t* file_data, int data_size, FilePosition,
+        FileConfig*);
+    void process_file_signature_sha256(const uint8_t* file_data, int data_size,
+        FilePosition, FileConfig*);
     void update_file_size(int data_size, FilePosition position);
     void stop_file_capture();
     FileCaptureState process_file_capture(const uint8_t* file_data, int data_size,
-        FilePosition pos);
-    void log_file_event(Flow*);
+        FilePosition, FileConfig*);
+    void log_file_event(Flow*, FileConfig*);
     FileVerdict file_signature_lookup(Flow*);
 
-    // Preserve the file in memory until it is released
-    // The file reserved will be returned and it will be detached from file context/session
-    FileCaptureState reserve_file(FileCapture*& dest);
-
-    // Configuration functions
-    void config_file_type(bool enabled);
-    bool is_file_type_enabled();
-    void config_file_signature(bool enabled);
-    bool is_file_signature_enabled();
-    void config_file_capture(bool enabled);
-    bool is_file_capture_enabled();
-
-    void set_signature_state(bool gen_sig)
-    {
-        if ( gen_sig )
-        {
-            if ( sha256 )
-            {
-                snort_free(sha256);
-                sha256 = nullptr;
-            }
-
-            file_state.sig_state = FILE_SIG_FLUSH;
-        }
-        else
-            file_state.sig_state = FILE_SIG_PROCESSING;
-    }
+    void set_signature_state(bool gen_sig);
 
     //File properties
     uint64_t get_processed_bytes();
@@ -133,25 +130,19 @@ public:
     void print_file_sha256(std::ostream&);
     void print_file_name(std::ostream&);
     static void print_file_data(FILE* fp, const uint8_t* data, int len, int max_depth);
-    void print(std::ostream&);
+    void print(std::ostream&, FileConfig*);
     char* get_UTF8_fname(size_t* converted_len);
 
 private:
-    bool file_type_enabled = false;
-    bool file_signature_enabled = false;
-    bool file_capture_enabled = false;
     uint64_t processed_bytes = 0;
     void* file_type_context;
     void* file_signature_context;
-    FileConfig* file_config;
-    FileInspect* inspector;
-    FileCapture* file_capture;
     FileSegments* file_segments;
-    FileState file_state = { FILE_CAPTURE_SUCCESS, FILE_SIG_PROCESSING };
 
-    inline int get_data_size_from_depth_limit(FileProcessType type, int data_size);
+    inline int get_data_size_from_depth_limit(FileProcessType type, int data_size,
+        FileConfig*);
     inline void finalize_file_type();
-    inline void finish_signature_lookup(Flow*, bool);
+    inline void finish_signature_lookup(Flow*, bool, FileConfig*, FilePolicyBase*);
 };
 
 #endif
index 44761ee2ff885dda9f9ba2ab2377e54046c099dc..c63beb8081c529a28f12f819d42e4292b375a0f4 100644 (file)
@@ -141,7 +141,7 @@ FileVerdict FilePolicy::match_file_signature(Flow*, FileInfo* file)
     return FILE_VERDICT_UNKNOWN;
 }
 
-void FilePolicy::policy_check(Flow*, FileContext* file)
+void FilePolicy::policy_check(Flow*, FileInfo* file)
 {
     // TODO: enable based on file policy rules on flow
     file->config_file_type(type_enabled);
@@ -154,31 +154,13 @@ FileVerdict FilePolicy::type_lookup(Flow* flow, FileInfo* file)
     FileRule rule = match_file_rule(nullptr, file);
     FileEnforcer* file_enforcer = FileService::get_file_enforcer();
     if (file_enforcer)
-        file_enforcer->apply_verdict(flow, file, rule.use.verdict);
-    return rule.use.verdict;
-}
-
-FileVerdict FilePolicy::type_lookup(Flow* flow, FileContext* file)
-{
-    type_lookup(flow, (FileInfo*)file);
-    FileRule rule = match_file_rule(nullptr, file);
+        file_enforcer->apply_verdict(flow, file, rule.use.verdict, false, this);
     file->config_file_signature(rule.use.signature_enabled);
     file->config_file_capture(rule.use.capture_enabled);
-
     return rule.use.verdict;
 }
 
 FileVerdict FilePolicy::signature_lookup(Flow* flow, FileInfo* file)
-{
-    FileVerdict verdict = match_file_signature(nullptr, file);
-    FileEnforcer* file_enforcer = FileService::get_file_enforcer();
-    if (file_enforcer)
-        file_enforcer->apply_verdict(flow, file, verdict);
-
-    return verdict;
-}
-
-FileVerdict FilePolicy::signature_lookup(Flow* flow, FileContext* file)
 {
     FileRule& rule = match_file_rule(nullptr, file);
 
@@ -192,6 +174,10 @@ FileVerdict FilePolicy::signature_lookup(Flow* flow, FileContext* file)
             delete captured;
     }
 
-    return (signature_lookup(flow, (FileInfo*)file));
-}
+    FileVerdict verdict = match_file_signature(nullptr, file);
+    FileEnforcer* file_enforcer = FileService::get_file_enforcer();
+    if (file_enforcer)
+        file_enforcer->apply_verdict(flow, file, verdict, false, this);
 
+    return verdict;
+}
index 56f7dca2bdf28d19c7a0ef7b8b7ad64ef4a4d33b..cad51ec2d0bd6926d7d860ac7bf98ea11769a10c 100644 (file)
@@ -51,34 +51,25 @@ public:
 
 class FileInfo;
 
-class FilePolicy
+class FilePolicy: public FilePolicyBase
 {
 public:
-    FilePolicy() = default;
 
-    // This is called when a new flow is queried for the first time
-    // Check & update what file policy is enabled on this flow/file
-    void policy_check(Flow* flow, FileContext* file);
+    FilePolicy() { }
+    ~FilePolicy() { }
 
-    // This is called after file type is known
-    virtual FileVerdict type_lookup(Flow* flow, FileContext* file);
+    void policy_check(Flow* flow, FileInfo* file) override;
 
     // This is called after file type is known
-    virtual FileVerdict type_lookup(Flow* flow, FileInfo* file);
-
-    // This is called after file signature is complete
-    virtual FileVerdict signature_lookup(Flow* flow, FileContext* file);
+    FileVerdict type_lookup(Flow* flow, FileInfo* file) override;
 
     // This is called after file signature is complete
-    virtual FileVerdict signature_lookup(Flow* flow, FileInfo* file);
+    FileVerdict signature_lookup(Flow* flow, FileInfo* file) override;
 
     void insert_file_rule(FileRule&);
     void set_file_type(bool enabled);
     void set_file_signature(bool enabled);
     void set_file_capture(bool enabled);
-    bool is_type_id_enabled() { return type_enabled; }
-    bool is_signature_enabled() { return signature_enabled; }
-    bool is_capture_enabled() { return capture_enabled; }
     void load();
 
 private:
index 239b3ed277ee5713883d98c5d2c447fe22f53844..fbe698e0fd2109edd3004d0f1d846c85e1aa0378 100644 (file)
@@ -150,14 +150,15 @@ FilePosition FileSegments::get_file_position(uint64_t data_size, uint64_t file_s
     return SNORT_FILE_MIDDLE;
 }
 
-int FileSegments::process_one(Flow* flow, const uint8_t* file_data, int data_size)
+int FileSegments::process_one(Flow* flow, const uint8_t* file_data, int data_size,
+    FileConfig* config, FilePolicyBase* policy)
 {
     FilePosition position = get_file_position(data_size, context->get_file_size());
 
-    return context->process(flow, file_data, data_size, position);
+    return context->process(flow, file_data, data_size, position, config, policy);
 }
 
-int FileSegments::process_all(Flow* flow)
+int FileSegments::process_all(Flow* flow, FileConfig* config, FilePolicyBase* policy)
 {
     int ret = 1;
 
@@ -165,7 +166,7 @@ int FileSegments::process_all(Flow* flow)
     while (current_segment && (current_offset == current_segment->offset))
     {
         ret = process_one(flow, (const uint8_t*)current_segment->data->data(),
-            current_segment->data->size());
+            current_segment->data->size(), config, policy);
 
         if (!ret)
         {
@@ -190,7 +191,7 @@ int FileSegments::process_all(Flow* flow)
  *    0: ignore this file
  */
 int FileSegments::process(Flow* flow, const uint8_t* file_data, uint64_t data_size,
-    uint64_t offset)
+    uint64_t offset, FileConfig* config, FilePolicyBase* policy)
 {
     int ret = 0;
 
@@ -202,7 +203,7 @@ int FileSegments::process(Flow* flow, const uint8_t* file_data, uint64_t data_si
     // Walk through the segments that can be flushed
     if (current_offset == offset)
     {
-        ret =  process_one(flow, file_data, data_size);
+        ret =  process_one(flow, file_data, data_size, config, policy);
         current_offset += data_size;
         if (!ret)
         {
@@ -210,7 +211,7 @@ int FileSegments::process(Flow* flow, const uint8_t* file_data, uint64_t data_si
             return 0;
         }
 
-        ret = process_all(flow);
+        ret = process_all(flow, config, policy);
     }
     else if ((current_offset < context->get_file_size()) && (current_offset < offset))
     {
index 6021327177a83cbe1da78460b9075c9af7aa2412..ae858448341aba98d9f705cbc88b693a0772cd67 100644 (file)
@@ -27,6 +27,7 @@
 #include "file_api.h"
 
 class Flow;
+class FileConfig;
 
 class FileSegment
 {
@@ -50,7 +51,8 @@ public:
 
     // Process file segments with current_offset specified. If file segment is out of order,
     // it will be put into the file segments queue.
-    int process(Flow*, const uint8_t* file_data, uint64_t data_size, uint64_t offset);
+    int process(Flow*, const uint8_t* file_data, uint64_t data_size, uint64_t offset,
+        FileConfig*, FilePolicyBase*);
 
 private:
     FileSegment* head = nullptr;
@@ -59,8 +61,9 @@ private:
 
     void add(const uint8_t* file_data, uint64_t data_size, uint64_t offset);
     FilePosition get_file_position(uint64_t data_size, uint64_t file_size);
-    int process_one(Flow*, const uint8_t* file_data, int data_size);
-    int process_all(Flow*);
+    int process_one(Flow*, const uint8_t* file_data, int data_size, FileConfig*,
+        FilePolicyBase*);
+    int process_all(Flow*, FileConfig*, FilePolicyBase*);
 };
 
 #endif
index 449c827d68a4964eb95dd3a4c247040200ee861c..d7bfe4168fc3b1c8ac9d01de2839c58058a36dda 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "detection/rules.h"
 #include "detection/treenodes.h"
+#include "hash/ghash.h"
 #include "main/snort_config.h"
 #include "protocols/packet.h"
 #include "utils/util.h"
index 165b59dd6c4c0ad86c7e0fb4727924be522ba6ff..2c20c6096203d9242293a5fe9047a9efbbb7f2ab 100644 (file)
@@ -26,6 +26,7 @@
 #include "hash/ghash.h"
 
 #include "main/snort_config.h"
+#include "utils/util.h"
 
 #include <CppUTest/CommandLineTestRunner.h>
 #include <CppUTest/TestHarness.h>
@@ -42,14 +43,6 @@ SnortConfig::~SnortConfig() = default;
 SnortConfig* SnortConfig::get_conf()
 { return snort_conf; }
 
-// implement functions for virtual
-FileVerdict FilePolicy::type_lookup(Flow* , FileContext* ) { return FILE_VERDICT_UNKNOWN;}
-FileVerdict FilePolicy::type_lookup(Flow* , FileInfo* ) { return FILE_VERDICT_UNKNOWN;}
-FileVerdict FilePolicy::signature_lookup(Flow* , FileContext* ) { return FILE_VERDICT_UNKNOWN;}
-FileVerdict FilePolicy::signature_lookup(Flow* , FileInfo* ) { return FILE_VERDICT_UNKNOWN;}
-
-FileIdentifier::~FileIdentifier() = default;
-
 // user free function
 static void myfree(void* p)
 {
index a286f469cf0be2206a3b884d096e688715a0d259..57fccc5d9c9610d12f0bfa91466c9d2e7523c8da 100644 (file)
@@ -79,20 +79,6 @@ SnortConfig* SnortConfig::get_conf()
 unsigned get_instance_id()
 { return 0; }
 
-FileIdentifier::~FileIdentifier() { }
-
-FileVerdict FilePolicy::type_lookup(Flow*, FileContext*)
-{ return FILE_VERDICT_UNKNOWN; }
-
-FileVerdict FilePolicy::type_lookup(Flow*, FileInfo*)
-{ return FILE_VERDICT_UNKNOWN; }
-
-FileVerdict FilePolicy::signature_lookup(Flow*, FileContext*)
-{ return FILE_VERDICT_UNKNOWN; }
-
-FileVerdict FilePolicy::signature_lookup(Flow*, FileInfo*)
-{ return FILE_VERDICT_UNKNOWN; }
-
 MemoryContext::MemoryContext(MemoryTracker&) { }
 MemoryContext::~MemoryContext() { }
 
index 972a9052d803f81def58cbb99a60fb7e3ef96f00..baa6c3625ad9e3ceffeb9abdc55cb619ba2b6ff7 100644 (file)
@@ -30,6 +30,7 @@
 #include "events/event.h"
 #include "framework/logger.h"
 #include "framework/module.h"
+#include "hash/ghash.h"
 #include "log/messages.h"
 #include "main/snort_config.h"
 #include "managers/event_manager.h"
index fb7f494cd3044611759e19cec8e33265b20cb7fa..6f51e1c2e07382c604d406950cbb2ee1c152b927 100644 (file)
@@ -24,7 +24,6 @@
 // FIXIT-L privatize most of this stuff.
 
 #include "events/event_queue.h"
-#include "file_api/file_config.h"
 #include "framework/bits.h"
 #include "main/policy.h"
 #include "main/thread.h"
@@ -261,8 +260,6 @@ public:
     class FastPatternConfig* fast_pattern_config = nullptr;
     struct EventQueueConfig* event_queue_config = nullptr;
 
-    class FileConfig file_config;
-
     /* XXX XXX policy specific? */
     struct ThresholdConfig* threshold_config = nullptr;
     struct RateFilterConfig* rate_filter_config = nullptr;
index 076eaa4213f1c0238c02e2e7d210d368f69da77e..be06fd72338c6d3a340c6382395212e08145d636 100644 (file)
@@ -37,6 +37,7 @@
 #include "detection/detection_options.h"  // ... FIXIT-W
 
 #include "detection/treenodes.h"
+#include "hash/ghash.h"
 #include "main/snort_config.h"
 #include "main/thread_config.h"
 #include "parser/parser.h"
index 20fa9d06db216afab16b3e8429f023de82fb30b2..d8ccacc88c88604094b2c71aa949267a8d48eb5d 100644 (file)
@@ -116,20 +116,6 @@ static MpseAgent s_agent =
     [](void** ppl) { CHECK(*ppl == s_list); }
 };
 
-FileIdentifier::~FileIdentifier() { }
-
-FileVerdict FilePolicy::type_lookup(Flow*, FileContext*)
-{ return FILE_VERDICT_UNKNOWN; }
-
-FileVerdict FilePolicy::type_lookup(Flow*, FileInfo*)
-{ return FILE_VERDICT_UNKNOWN; }
-
-FileVerdict FilePolicy::signature_lookup(Flow*, FileContext*)
-{ return FILE_VERDICT_UNKNOWN; }
-
-FileVerdict FilePolicy::signature_lookup(Flow*, FileInfo*)
-{ return FILE_VERDICT_UNKNOWN; }
-
 //-------------------------------------------------------------------------
 // base tests
 //-------------------------------------------------------------------------
index dd256102b7a58984a235c0e1f2feb4f0099603d3..d6be375540a6e4b700b1335fb848007e0558d2b2 100644 (file)
@@ -63,20 +63,6 @@ SnortConfig* SnortConfig::get_conf()
 unsigned get_instance_id()
 { return 0; }
 
-FileIdentifier::~FileIdentifier() { }
-
-FileVerdict FilePolicy::type_lookup(Flow*, FileContext*)
-{ return FILE_VERDICT_UNKNOWN; }
-
-FileVerdict FilePolicy::type_lookup(Flow*, FileInfo*)
-{ return FILE_VERDICT_UNKNOWN; }
-
-FileVerdict FilePolicy::signature_lookup(Flow*, FileContext*)
-{ return FILE_VERDICT_UNKNOWN; }
-
-FileVerdict FilePolicy::signature_lookup(Flow*, FileInfo*)
-{ return FILE_VERDICT_UNKNOWN; }
-
 void LogValue(const char*, const char*, FILE*)
 {
 }