arp_spoof = nil
--- bug: false will limit http file_data
-file_id.enable_signature = true
-
ftp_server.check_encrypted = true
detection =
arp_spoof = nil
--- bug: false will limit http file_data
-file_id.enable_signature = true
-
ftp_server.check_encrypted = true
detection =
-- 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:
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
file_identifier.h
file_lib.h
file_module.h
- file_policy.h
file_segment.h
file_service.h
)
${FILE_API_INCLUDES}
circular_buffer.cc
circular_buffer.h
+ file_api.cc
file_capture.cc
file_cache.cc
file_cache.h
file_mempool.cc
file_mempool.h
file_module.cc
- file_policy.cc
file_segment.cc
file_service.cc
file_stats.cc
--- /dev/null
+//--------------------------------------------------------------------------
+// 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;
+ }
+}
// Currently, it provides three sets of APIs: file processing, MIME processing,
// and configurations.
+#include <atomic>
#include <bitset>
#include <cstring>
#include <string>
{
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
{ 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)
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);
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);
// 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*/
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;
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);
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;
{
delete elem.second;
}
+
+ FilePolicyBase::delete_file_policy(file_policy);
}
FileContext* FileFlows::find_main_file_context(FilePosition pos, FileDirection dir, size_t index)
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();
}
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;
}
}
}
- 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);
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);
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
mod_ctor,
mod_dtor
},
- IT_PASSIVE,
+ IT_FILE,
PROTO_BIT__NONE,
nullptr,
"file",
#include "file_api.h"
#include "file_module.h"
-#include "file_policy.h"
#include <map>
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:
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;
}
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 )
{
/* 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);
{
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)
{
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)
{
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)
{
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;
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;
{
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))
{
{ 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",
{ "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" },
{ "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)" },
if (!fc)
fc = new FileConfig;
- FilePolicy& fp = fc->get_file_policy();
-
if ( v.is("type_depth") )
fc->file_type_depth = v.get_int64();
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();
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());
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();
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;
}
{
magic.clear();
}
- else if ( !strcmp(fqn, "file_id.file_policy") )
- {
- file_rule.clear();
- }
return true;
}
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;
}
void FileIdModule::load_config(FileConfig*& dst)
{
dst = fc;
-
- if (fc)
- {
- fc->get_file_policy().load();
- fc = nullptr;
- }
+ fc = nullptr;
}
void FileIdModule::show_dynamic_stats()
#include "file_config.h"
#include "file_identifier.h"
-#include "file_policy.h"
#include "main/snort_debug.h"
#include "utils/util.h"
//-------------------------------------------------------------------------
private:
FileMagicRule rule;
FileMagicData magic;
- FileRule file_rule;
FileConfig *fc = nullptr;
- bool need_active = false;
};
enum FileSid
// 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"
codec.cc
cursor.cc
data_bus.cc
+ file_policy.cc
inspector.cc
ips_option.cc
packet_constraints.cc
#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;
#include <map>
#include <vector>
-#include "file_api.h"
+#include "file_api/file_api.h"
namespace snort
{
bool signature_enabled = false;
bool capture_enabled = false;
int64_t verdict_delay = 0;
-
};
#endif
"service",
"control",
"probe",
+ "file",
};
const char* InspectApi::get_type(InspectorType type)
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
};
PegCount Module::get_global_count(const char* name) const
{
const PegInfo* infos = get_pegs();
+ assert(infos);
for ( unsigned i = 0; infos[i].name; i++ )
{
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;
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;
}
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);
}
#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"
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; }
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();
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
//-------------------------------------------------------------------------
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; }
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") )
}
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
//-------------------------------------------------------------------------
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();
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();
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") )
{
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;
}
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
//-------------------------------------------------------------------------
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);
#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"
{ 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);
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
//-------------------------------------------------------------------------
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);
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();
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;
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));
namespace snort
{
+class FilePolicyBase;
class GHash;
class IpsAction;
+class PolicySelector;
struct SnortConfig;
}
// Snort ac-split creates the nap (network analysis policy)
// Snort++ breaks the nap into network and inspection
+class FilePolicy;
+class FileRule;
+
struct NetworkPolicy
{
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; }
bool icmp_checksums()
{ return (checksum_eval & CHECKSUM_FLAG__ICMP) != 0; }
+protected:
+ FilePolicy* file_policy;
+
public:
struct TrafficPolicy* traffic_policy;
snort::DataBus dbus;
inspection(ins_pol), ips(ips_pol), network(net_pol) { }
};
+struct GlobalInspectorPolicy;
+class SingleInstanceInspectorPolicy;
+
class PolicyMap
{
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),
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;
};
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();
struct LatencyConfig;
struct MemoryConfig;
struct PayloadInjectorConfig;
-struct PHInstance;
struct Plugins;
struct PORT_RULE_MAP;
struct RateFilterConfig;
namespace snort
{
class GHash;
-class PolicySelector;
class ProtocolReference;
class ThreadConfig;
class XHash;
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;
ReloadType get_reload_type()
{ return reload_type; }
+
+ void tinit();
+ void tterm();
};
PHInstance::PHInstance(PHClass& p, SnortConfig* sc, Module* mod) : pp_class(p)
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;
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;
}
}
PHVector packet;
PHVector network;
PHVector service;
- PHVector probe;
Inspector* binder;
Inspector* wizard;
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)
packet.alloc(ilist.size());
network.alloc(ilist.size());
service.alloc(ilist.size());
- probe.alloc(ilist.size());
for ( auto* p : ilist )
{
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;
}
}
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
//-------------------------------------------------------------------------
// 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 )
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);
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
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);
}
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;
}
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)
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 )
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();
// 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();
}
}
}
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
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();
}
}
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();
}
}
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 )
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);
}
::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 )
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();
}
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 )
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;
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",
#include "framework/inspector.h"
class Binder;
+class SingleInstanceInspectorPolicy;
struct InspectorList;
struct InspectionPolicy;
struct NetworkPolicy;
struct PHInstance;
+struct GlobalInspectorPolicy;
namespace snort
{
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);
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*);
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();
}
}
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;
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);
// 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);
}
}
{
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
{
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;
std::string args;
bool retval = true;
- table_api.open_table("file_id");
while (util::get_string(data_stream, args, ","))
{
std::istringstream arg_stream(args);
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;
}
// 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;
}