#include "signature.h"
+#include "hash/ghash.h"
#include "log/messages.h"
#include "main/snort_config.h"
#include "parser/parser.h"
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)
{
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)
FileCapture::FileCapture(int64_t min_size, int64_t max_size)
{
- reserved = false;
capture_size = 0;
last = head = nullptr;
current_data = nullptr;
{
FileCaptureBlock* file_block = head;
- if (reserved)
+ if (file_info)
file_counts.files_released_total++;
else
file_counts.files_freed_total++;
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++;
current_block = head;
- reserved = true;
-
file_info = new FileInfo(*file);
return FILE_CAPTURE_SUCCESS;
// 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:
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 */
}
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) ||
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)
// 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;
}
}
FileVerdict FileEnforcer::cached_verdict_lookup(Flow* flow, FileInfo* file,
- FilePolicy& inspect)
+ FilePolicyBase* policy)
{
FileVerdict verdict = FILE_VERDICT_UNKNOWN;
XHashNode* hash_node;
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;
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?
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 */
#include "file_flows.h"
+#include "main/snort_config.h"
#include "managers/inspector_manager.h"
#include "protocols/packet.h"
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;
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());
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);
}
/*
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)
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);
}
}
#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();
//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);
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
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)
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 ()
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;
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() )
default:
break;
}
- if ( file_config->trace_type )
- print(std::cout);
+ if ( config->trace_type )
+ print(std::cout, config);
}
}
{
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()]++;
}
}
}
-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);
}
/*
* 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;
}
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)
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);
}
}
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
{
}
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);
}
/*
* 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;
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)
{
}
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) ||
}
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)
{
}
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 =
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)
file_capture = nullptr;
}
- file_capture_enabled = false;
+ config_file_capture(false);
}
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;
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;
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;
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);
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();
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
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);
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);
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;
+}
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:
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;
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)
{
* 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;
// 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)
{
return 0;
}
- ret = process_all(flow);
+ ret = process_all(flow, config, policy);
}
else if ((current_offset < context->get_file_size()) && (current_offset < offset))
{
#include "file_api.h"
class Flow;
+class FileConfig;
class FileSegment
{
// 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;
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
#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"
#include "hash/ghash.h"
#include "main/snort_config.h"
+#include "utils/util.h"
#include <CppUTest/CommandLineTestRunner.h>
#include <CppUTest/TestHarness.h>
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)
{
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() { }
#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"
// 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"
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;
#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"
[](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
//-------------------------------------------------------------------------
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*)
{
}