file_cache.h
file_flows.h
file_identifier.h
- file_lib.h
+ file_lib.h
+ file_module.h
file_policy.h
file_segment.h
file_service.h
file_flows.h \
file_identifier.h \
file_lib.h \
+file_module.h \
file_policy.h \
file_segment.h \
file_service.h
#include "file_stats.h"
FileMemPool* FileCapture::file_mempool = nullptr;
+int64_t FileCapture::capture_block_size = 0;
std::mutex FileCapture::capture_mutex;
std::condition_variable FileCapture::capture_cv;
}
}
-FileCapture::FileCapture()
+FileCapture::FileCapture(int64_t min_size, int64_t max_size)
{
reserved = 0;
capture_size = 0;
current_data = nullptr;
current_data_len = 0;
capture_state = FILE_CAPTURE_SUCCESS;
+ capture_min_size = min_size;
+ capture_max_size = max_size;
}
FileCapture::~FileCapture()
delete file_info;
}
-void FileCapture::init()
+void FileCapture::init(int64_t memcap, int64_t block_size)
{
- FileConfig& file_config = snort_conf->file_config;
- init_mempool(file_config.capture_memcap, file_config.capture_block_size);
+ capture_block_size = block_size;
+ init_mempool(memcap, capture_block_size);
file_storer = new std::thread(writer_thread);
}
{
FileCaptureBlock* lastBlock = last;
int64_t available_bytes;
- FileConfig& file_config = snort_conf->file_config;
if ( data_size + (int64_t)capture_size > max_size)
{
}
/* Check whether current file block can hold file data*/
- available_bytes = file_config.capture_block_size - lastBlock->length;
+ available_bytes = capture_block_size - lastBlock->length;
if ( data_size > available_bytes)
{
memcpy((uint8_t*)lastBlock + lastBlock->length + sizeof (*lastBlock),
file_current, available_bytes);
- lastBlock->length = file_config.capture_block_size;
+ lastBlock->length = capture_block_size;
file_current += available_bytes;
/* We can support any file capture block size */
last = new_block;
/*Save data to the new block*/
- if (file_current + file_config.capture_block_size < file_end)
+ if (file_current + capture_block_size < file_end)
{
memcpy((uint8_t*)last + sizeof(*new_block),
- file_current, file_config.capture_block_size);
- new_block->length = file_config.capture_block_size;
- file_current += file_config.capture_block_size;
+ file_current, capture_block_size);
+ new_block->length = capture_block_size;
+ file_current += capture_block_size;
}
else
{
FileCaptureState FileCapture::process_buffer(const uint8_t* file_data,
int data_size, FilePosition position)
{
- FileConfig& file_config = snort_conf->file_config;
-
current_data = file_data;
current_data_len = data_size;
file_counts.files_buffered_total++;
}
- return (save_to_file_buffer(file_data, data_size, file_config.capture_max_size));
+ return (save_to_file_buffer(file_data, data_size, capture_max_size));
}
return FILE_CAPTURE_SUCCESS;
{
uint64_t fileSize;
- FileConfig& file_config = snort_conf->file_config;
-
if (capture_state != FILE_CAPTURE_SUCCESS)
{
return error_capture(capture_state);
*/
fileSize = file->get_file_size();
- if ( fileSize < (unsigned)file_config.capture_min_size)
+ if ( fileSize < (unsigned)capture_min_size)
{
file_counts.file_size_min++;
return error_capture(FILE_CAPTURE_MIN);
}
- if ( fileSize > (unsigned)file_config.capture_max_size)
+ if ( fileSize > (unsigned)capture_max_size)
{
file_counts.file_size_max++;
return error_capture(FILE_CAPTURE_MAX);
/*Copy the last piece of file to file buffer*/
if (save_to_file_buffer(current_data,
- current_data_len, file_config.capture_max_size) )
+ current_data_len, capture_max_size) )
{
return error_capture(capture_state);
}
class FileCapture
{
public:
- FileCapture();
+ FileCapture(int64_t capture_min_size, int64_t capture_max_size);
~FileCapture();
// this must be called during snort init
- static void init();
+ static void init(int64_t memcap, int64_t block_size);
// Capture file data to local buffer
// This is the main function call to enable file capture
static FileCaptureState error_capture(FileCaptureState);
+ static int64_t get_block_size() { return capture_block_size; };
+
private:
static void init_mempool(int64_t max_file_mem, int64_t block_size);
void write_file_data(uint8_t* buf, size_t buf_len, FILE* fh);
static FileMemPool* file_mempool;
+ static int64_t capture_block_size;
static std::mutex capture_mutex;
static std::condition_variable capture_cv;
static std::thread* file_storer;
uint32_t current_data_len;
FileCaptureState capture_state;
FileInfo* file_info = nullptr;
+ int64_t capture_min_size;
+ int64_t capture_max_size;
};
#endif
#endif
#include "main/snort_config.h"
+#include "managers/inspector_manager.h"
#include "parser/parse_utils.h"
+#include "file_flows.h"
+
bool FileConfig::process_file_magic(FileMagicData& magic)
{
bool negated = false;
std::string file_type_name(uint32_t id)
{
- return snort_conf->file_config.file_type_name(id);
+ FileConfig* conf = get_file_config();
+ if (conf)
+ return conf->file_type_name(id);
+ else
+ return "NA";
}
+FileConfig* get_file_config ()
+{
+ FileInspect* fi = (FileInspect*)InspectorManager::get_inspector(FILE_ID_NAME);
+
+ if (fi)
+ return (fi->config);
+ else
+ return nullptr;
+}
#define DEFAULT_FILE_CAPTURE_BLOCK_SIZE 32768 // 32 KiB
#define DEFAULT_MAX_FILES_CACHED 65536
+#define FILE_ID_NAME "file_id"
+#define FILE_ID_HELP "configure file identification"
+
class FileConfig
{
public:
};
std::string file_type_name(uint32_t id);
-
+FileConfig* get_file_config ();
#endif
*(node->file) = *file;
}
-FileVerdict FileEnforcer::check_verdict(Flow* flow, FileNode* node, SFXHASH_NODE* hash_node)
+FileVerdict FileEnforcer::check_verdict(Flow* flow, FileNode* node,
+ SFXHASH_NODE* hash_node, FilePolicy& inspect)
{
- // Query the file policy in case verdict has been changed
- // Check file type first
- FilePolicy& inspect = FileService::get_inspect();
-
assert(node->file);
FileVerdict verdict = inspect.type_lookup(flow, node->file);
return false;
}
-FileVerdict FileEnforcer::cached_verdict_lookup(Flow* flow, FileInfo* file)
+FileVerdict FileEnforcer::cached_verdict_lookup(Flow* flow, FileInfo* file,
+ FilePolicy& inspect)
{
FileVerdict verdict = FILE_VERDICT_UNKNOWN;
SFXHASH_NODE* hash_node;
return verdict;
}
/*Query the file policy in case verdict has been changed*/
- verdict = check_verdict(flow, node, hash_node);
+ verdict = check_verdict(flow, node, hash_node, inspect);
}
return verdict;
#include "utils/cpp_macros.h"
#include "file_config.h"
+#include "file_policy.h"
class FileInfo;
FileEnforcer();
~FileEnforcer();
- FileVerdict cached_verdict_lookup(Flow*, FileInfo*);
+ FileVerdict cached_verdict_lookup(Flow*, FileInfo*, FilePolicy&);
bool apply_verdict(Flow*, FileInfo*, FileVerdict);
private:
PADDING_GUARD_END
void update_file_node(FileNode*, FileInfo*);
- FileVerdict check_verdict(Flow*, FileNode*, SFXHASH_NODE*);
+ FileVerdict check_verdict(Flow*, FileNode*, SFXHASH_NODE*, FilePolicy&);
int store_verdict(Flow*, FileInfo*);
/* The hash table of expected files */
#include "config.h"
#endif
+#include "managers/inspector_manager.h"
#include "protocols/packet.h"
#include "file_cache.h"
+#include "file_config.h"
#include "file_lib.h"
#include "file_service.h"
return position;
}
+FileInspect::FileInspect(FileIdModule* fm)
+{
+ fm->fc.get_file_policy().load();
+ config = &(fm->fc);
+}
+
+static Module* mod_ctor()
+{ return new FileIdModule; }
+
+static void mod_dtor(Module* m)
+{ delete m; }
+
+static void file_init()
+{
+ FileFlows::init();
+}
+
+static void file_term()
+{
+}
+
+static Inspector* file_ctor(Module* m)
+{
+ FileIdModule* mod = (FileIdModule*)m;
+ return new FileInspect(mod);
+}
+
+static void file_dtor(Inspector* p)
+{
+ delete p;
+}
+
+static const InspectApi file_inspect_api =
+{
+ {
+ PT_INSPECTOR,
+ sizeof(InspectApi),
+ INSAPI_VERSION,
+ 0,
+ API_RESERVED,
+ API_OPTIONS,
+ FILE_ID_NAME,
+ FILE_ID_HELP,
+ mod_ctor,
+ mod_dtor
+ },
+ IT_PASSIVE,
+ (uint16_t)PktType::NONE,
+ nullptr,
+ "file",
+ file_init,
+ file_term,
+ nullptr, // tinit
+ nullptr, // tterm
+ file_ctor,
+ file_dtor,
+ nullptr, // ssn
+ nullptr // reset
+};
+
+const BaseApi* sin_file = &file_inspect_api.base;
+
#include "main/snort_types.h"
#include "file_api.h"
+#include "file_module.h"
class FileContext;
class Flow;
+class FileConfig;
class SO_PUBLIC FileFlows : public FlowData
{
uint64_t current_file_id = 0;
Flow* flow = nullptr;
};
+
+class FileInspect : public Inspector
+{
+public:
+ FileInspect(FileIdModule*);
+ void eval(Packet*) override { }
+
+ FileConfig* config;
+};
+
#endif
#include "hash/hashes.h"
#include "framework/data_bus.h"
#include "main/snort_config.h"
+#include "managers/inspector_manager.h"
#include "utils/util.h"
#include "file_capture.h"
#include "file_config.h"
#include "file_enforcer.h"
+#include "file_flows.h"
#include "file_service.h"
#include "file_segment.h"
#include "file_stats.h"
{
file_type_context = nullptr;
file_signature_context = nullptr;
- file_config = &(snort_conf->file_config);
file_capture = nullptr;
file_segments = nullptr;
+ inspector = (FileInspect*)InspectorManager::acquire(FILE_ID_NAME, snort_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
{
uint64_t max_depth;
- if (!file_config)
- return data_size;
-
switch (type)
{
case SNORT_FILE_TYPE_ID:
default:
break;
}
- if ( snort_conf->file_config.trace_type )
+ if ( file_config->trace_type )
print(std::cout);
}
}
{
if (get_file_sig_sha256() && is_file_signature_enabled())
{
- FilePolicy& inspect = FileService::get_inspect();
+ FilePolicy& inspect = file_config->get_file_policy();
return inspect.signature_lookup(flow, this);
}
else
if (get_file_sig_sha256())
{
//Check file type based on file policy
- FilePolicy& inspect = FileService::get_inspect();
+ FilePolicy& inspect = file_config->get_file_policy();
inspect.signature_lookup(flow, this);
log_file_event(flow);
config_file_signature(false);
{
file_counts.files_total++;
set_file_direction(dir);
- FilePolicy& inspect = FileService::get_inspect();
+ FilePolicy& inspect = file_config->get_file_policy();
inspect.policy_check(flow, this);
}
bool FileContext::process(Flow* flow, const uint8_t* file_data, int data_size,
FilePosition position)
{
- if ( snort_conf->file_config.trace_stream )
+ if ( file_config->trace_stream )
{
FileContext::print_file_data(stdout, file_data, data_size,
- snort_conf->file_config.show_data_depth);
+ file_config->show_data_depth);
}
file_counts.file_data_total += data_size;
return false;
}
- if ((FileService::get_file_enforcer()->cached_verdict_lookup(flow, this)
- != FILE_VERDICT_UNKNOWN))
+ if ((FileService::get_file_enforcer()->cached_verdict_lookup(flow, this,
+ file_config->get_file_policy()) != FILE_VERDICT_UNKNOWN))
return true;
/*file type id*/
config_file_type(false);
file_stats->files_processed[get_file_type()][get_file_direction()]++;
//Check file type based on file policy
- FilePolicy& inspect = FileService::get_inspect();
+ FilePolicy& inspect = file_config->get_file_policy();
inspect.type_lookup(flow, this);
log_file_event(flow);
}
update_file_size(data_size, position);
- if ( snort_conf->file_config.trace_signature )
+ if ( file_config->trace_signature )
print_file_sha256(std::cout);
/*Fails to capture, when out of memory or size limit, need lookup*/
{
int data_size;
- if (!file_config)
- return;
-
/* file type already found and no magics to continue*/
if (file_type_id && !file_type_context)
return;
{
if (!file_capture)
{
- file_capture = new FileCapture;
+ file_capture = new FileCapture(file_config->capture_min_size,
+ file_config->capture_max_size);
}
file_state.capture_state =
class FileConfig;
class FileSegments;
class Flow;
+class FileInspect;
class SO_PUBLIC FileInfo
{
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 };
nullptr // reset
};
+extern const BaseApi* sin_file;
+
const BaseApi* file_inspectors[] =
{
&fl_api.base,
+ sin_file,
nullptr
};
{ nullptr, nullptr }
};
-#define file_id_help \
- "configure file identification"
-
-FileIdModule::FileIdModule() : Module("file_id", file_id_help, file_id_params) { }
+FileIdModule::FileIdModule() : Module(FILE_ID_NAME, FILE_ID_HELP, file_id_params) { }
const PegInfo* FileIdModule::get_pegs() const
{ return file_pegs; }
Module::sum_stats();
}
-bool FileIdModule::set(const char*, Value& v, SnortConfig* sc)
+bool FileIdModule::set(const char*, Value& v, SnortConfig*)
{
- FileConfig& fc = sc->file_config;
-
FilePolicy& fp = fc.get_file_policy();
if ( v.is("type_depth") )
return true;
}
-bool FileIdModule::end(const char* fqn, int idx, SnortConfig* sc)
+bool FileIdModule::end(const char* fqn, int idx, SnortConfig*)
{
- FileConfig& fc = sc->file_config;
-
if (!idx)
return true;
#include "framework/module.h"
+#include "file_config.h"
#include "file_identifier.h"
#include "file_policy.h"
void sum_stats() override;
+ FileConfig fc;
+
private:
FileMagicRule rule;
FileMagicData magic;
void FileService::post_init()
{
- FilePolicy& fp = get_inspect();
+ FileConfig* conf = get_file_config();
- fp.load();
+ if (!conf)
+ return;
if (file_capture_enabled)
- FileCapture::init();
+ FileCapture::init(conf->capture_memcap, conf->capture_block_size);
}
void FileService::close()
*/
int64_t FileService::get_max_file_depth()
{
- FileConfig& file_config = snort_conf->file_config;
+ FileConfig* file_config = get_file_config();
- if (file_config.file_depth)
- return file_config.file_depth;
+ if (!file_config)
+ return -1;
+
+ if (file_config->file_depth)
+ return file_config->file_depth;
- file_config.file_depth = -1;
+ file_config->file_depth = -1;
if (file_type_id_enabled)
{
- file_config.file_depth = file_config.file_type_depth;
+ file_config->file_depth = file_config->file_type_depth;
}
if (file_signature_enabled)
{
- if (file_config.file_signature_depth > file_config.file_depth)
- file_config.file_depth = file_config.file_signature_depth;
+ if (file_config->file_signature_depth > file_config->file_depth)
+ file_config->file_depth = file_config->file_signature_depth;
}
- if (file_config.file_depth > 0)
+ if (file_config->file_depth > 0)
{
/*Extra byte for deciding whether file data will be over limit*/
- file_config.file_depth++;
- return (file_config.file_depth);
+ file_config->file_depth++;
+ return (file_config->file_depth);
}
else
{
}
}
-FilePolicy& FileService::get_inspect()
-{
- return (snort_conf->file_config.get_file_policy());
-}
-
uint64_t get_file_processed_size(Flow* flow)
{
FileFlows* file_flows = FileFlows::get_file_flows(flow);
static bool is_file_service_enabled();
static int64_t get_max_file_depth();
- static FilePolicy& get_inspect();
static FileEnforcer* get_file_enforcer() { return file_enforcer; }
static FileCache* get_file_cache() { return file_cache; }
// these modules could be in traffic policy
ModuleManager::add_module(new ActiveModule);
- ModuleManager::add_module(new FileIdModule);
ModuleManager::add_module(new LatencyModule);
#include "file_mime_process.h"
-DecodeConfig::DecodeConfig()
-{
- sync_all_depths();
-}
-
void DecodeConfig::set_ignore_data(bool ignored)
{
ignore_data = ignored;
class SO_PUBLIC DecodeConfig
{
public:
- DecodeConfig();
void set_ignore_data(bool);
bool is_ignore_data();
void set_max_mime_mem(int);