From: Bhagya Tholpady (bbantwal) Date: Thu, 4 Mar 2021 23:18:44 +0000 (+0000) Subject: Merge pull request #2759 in SNORT/snort3 from ~OSHUMEIK/snort3:cvars to master X-Git-Tag: 3.1.2.0~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ca86897057eb3e67d2b5107f47489ae5e46681fd;p=thirdparty%2Fsnort3.git Merge pull request #2759 in SNORT/snort3 from ~OSHUMEIK/snort3:cvars to master Squashed commit of the following: commit 5a87d044fb559592ece9f0d340f79d1f330b3095 Author: Oleksii Shumeiko Date: Tue Feb 16 17:09:05 2021 +0200 detection: use IP and port variables from the targeted policy Port lists are updated for every duped RTN if its ports have been changed. --- diff --git a/src/detection/rules.cc b/src/detection/rules.cc index 4690a8c41..e1bd6c368 100644 --- a/src/detection/rules.cc +++ b/src/detection/rules.cc @@ -32,6 +32,9 @@ #include "main/snort_config.h" #include "parser/parse_conf.h" #include "parser/parser.h" +#include "parser/parse_rule.h" +#include "ports/port_object.h" +#include "ports/port_var_table.h" #include "sfip/sf_ipvar.h" #include "sfip/sf_vartable.h" @@ -86,30 +89,58 @@ void RuleStateMap::apply( SnortConfig* sc, OptTreeNode* otn, unsigned ips_num, const RuleState& s) { IpsPolicy* policy = nullptr; - RuleTreeNode* rtn = getRtnFromOtn(otn, ips_num); + RuleTreeNode* b_rtn = getRtnFromOtn(otn, ips_num); - if ( !rtn ) - if ( ips_num and (rtn = getRtnFromOtn(otn, 0)) ) - policy = sc->policy_map->get_ips_policy(ips_num); + if ( !b_rtn and ips_num and (b_rtn = getRtnFromOtn(otn, 0)) ) + policy = sc->policy_map->get_ips_policy(ips_num); - if ( !rtn ) + if ( !b_rtn ) return; if ( policy ) policy->rules_shared++; - rtn = dup_rtn(rtn); - update_rtn(rtn, s); - addRtnToOtn(sc, otn, rtn, ips_num); + RuleTreeNode* t_rtn = dup_rtn(b_rtn, policy); + update_rtn(t_rtn, s); + + auto bspo = b_rtn->src_portobject; + auto bdpo = b_rtn->dst_portobject; + auto tspo = t_rtn->src_portobject; + auto tdpo = t_rtn->dst_portobject; + + if ( (bspo and tspo and !PortObjectEqual(bspo, tspo)) or + (bdpo and tdpo and !PortObjectEqual(bdpo, tdpo)) ) + parse_rule_finish_portlist(sc, t_rtn, otn); + + addRtnToOtn(sc, otn, t_rtn, ips_num); } -RuleTreeNode* RuleStateMap::dup_rtn(RuleTreeNode* rtn) +RuleTreeNode* RuleStateMap::dup_rtn(RuleTreeNode* rtn, IpsPolicy* policy) { RuleTreeNode* ret = new RuleTreeNode(*rtn); + auto ipvt = policy ? policy->ip_vartable : nullptr; + auto povt = policy ? policy->portVarTable : nullptr; + + auto sip = sfvt_lookup_var(ipvt, rtn->sip->name); + auto dip = sfvt_lookup_var(ipvt, rtn->dip->name); + auto spo = rtn->src_portobject + ? PortVarTableFind(povt, rtn->src_portobject->name, false) : nullptr; + auto dpo = rtn->dst_portobject + ? PortVarTableFind(povt, rtn->dst_portobject->name, false) : nullptr; + + ret->sip = sip + ? sfvar_create_alias(sip, sip->name) + : sfvar_deep_copy(rtn->sip); + + ret->dip = dip + ? sfvar_create_alias(dip, dip->name) + : sfvar_deep_copy(rtn->dip); + + ret->src_portobject = spo ? spo : ret->src_portobject; + ret->dst_portobject = dpo ? dpo : ret->dst_portobject; + ret->otnRefCount = 0; - ret->sip = sfvar_deep_copy(rtn->sip); - ret->dip = sfvar_deep_copy(rtn->dip); RuleFpList* from = rtn->rule_func; diff --git a/src/detection/rules.h b/src/detection/rules.h index 8ff47e270..b5bd75b23 100644 --- a/src/detection/rules.h +++ b/src/detection/rules.h @@ -96,7 +96,7 @@ public: void apply(snort::SnortConfig*); private: - RuleTreeNode* dup_rtn(RuleTreeNode*); + RuleTreeNode* dup_rtn(RuleTreeNode*, IpsPolicy*); void update_rtn(RuleTreeNode*, const RuleState&); void apply(snort::SnortConfig*, OptTreeNode*, unsigned ips_num, const RuleState&); diff --git a/src/main/snort_config.cc b/src/main/snort_config.cc index e0a32ff6e..6cba980bd 100644 --- a/src/main/snort_config.cc +++ b/src/main/snort_config.cc @@ -300,6 +300,7 @@ void SnortConfig::setup() rule_states = nullptr; } + ParseRulesFinish(this); ShowPolicyStats(this); /* Need to do this after dynamic detection stuff is initialized, too */ diff --git a/src/parser/parse_rule.cc b/src/parser/parse_rule.cc index b769eda01..804128f81 100644 --- a/src/parser/parse_rule.cc +++ b/src/parser/parse_rule.cc @@ -1382,9 +1382,7 @@ void parse_rule_close(SnortConfig* sc, RuleTreeNode& rtn, OptTreeNode* otn) validate_services(sc, otn); OtnLookupAdd(sc->otn_map, otn); - - if ( FinishPortListRule(sc->port_tables, new_rtn, otn, sc->fast_pattern_config) ) - ParseError("Failed to finish a port list rule."); + parse_rule_finish_portlist(sc, new_rtn, otn); if ( s_capture ) { @@ -1395,3 +1393,9 @@ void parse_rule_close(SnortConfig* sc, RuleTreeNode& rtn, OptTreeNode* otn) ClearIpsOptionsVars(); } +void parse_rule_finish_portlist(SnortConfig* sc, RuleTreeNode* rtn, OptTreeNode* otn) +{ + if ( FinishPortListRule(sc->port_tables, rtn, otn, sc->fast_pattern_config) ) + ParseError("%u:%u rule failed to finish a port list.", + otn->sigInfo.gid, otn->sigInfo.sid); +} diff --git a/src/parser/parse_rule.h b/src/parser/parse_rule.h index 917845b3e..9ddd00665 100644 --- a/src/parser/parse_rule.h +++ b/src/parser/parse_rule.h @@ -49,6 +49,7 @@ void parse_rule_opt_end(snort::SnortConfig*, const char* key, OptTreeNode*); OptTreeNode* parse_rule_open(snort::SnortConfig*, RuleTreeNode&, bool stub = false); void parse_rule_close(snort::SnortConfig*, RuleTreeNode&, OptTreeNode*); +void parse_rule_finish_portlist(snort::SnortConfig*, RuleTreeNode*, OptTreeNode*); #endif diff --git a/src/parser/parser.cc b/src/parser/parser.cc index 1e51dd90b..315a43fea 100644 --- a/src/parser/parser.cc +++ b/src/parser/parser.cc @@ -463,12 +463,14 @@ void ParseRules(SnortConfig* sc) p->rules_loaded = get_policy_loaded_rule_count(); p->rules_shared = get_policy_shared_rule_count(); } +} +void ParseRulesFinish(SnortConfig* sc) +{ set_ips_policy(sc, 0); /* Compile/Finish and Print the PortList Tables */ PortTablesFinish(sc->port_tables, sc->fast_pattern_config); - parse_rule_print(); } diff --git a/src/parser/parser.h b/src/parser/parser.h index ec6ef76a3..5b4821c91 100644 --- a/src/parser/parser.h +++ b/src/parser/parser.h @@ -45,6 +45,7 @@ void inc_parse_position(); snort::SnortConfig* ParseSnortConf(const snort::SnortConfig*, const char* fname = nullptr, bool is_fatal = true); void ParseRules(snort::SnortConfig*); +void ParseRulesFinish(snort::SnortConfig*); void ShowPolicyStats(const snort::SnortConfig*); char* ProcessFileOption(snort::SnortConfig*, const char*);