From fb7714f202dd3cf685e95ac4ac1a448aefe2d185 Mon Sep 17 00:00:00 2001 From: Felipe Zimmerle Date: Wed, 14 Nov 2018 19:44:28 -0300 Subject: [PATCH] Creates class RulesSetPhases --- headers/modsecurity/rules_set.h | 80 ++++++++++++++++++++++ headers/modsecurity/rules_set_properties.h | 70 +------------------ src/parser/driver.cc | 11 +-- src/parser/driver.h | 2 + src/rules_set.cc | 24 +++---- test/optimization/optimization.cc | 4 +- 6 files changed, 102 insertions(+), 89 deletions(-) diff --git a/headers/modsecurity/rules_set.h b/headers/modsecurity/rules_set.h index 2ead9a81..bbbc5948 100644 --- a/headers/modsecurity/rules_set.h +++ b/headers/modsecurity/rules_set.h @@ -41,6 +41,85 @@ class Driver; } +class RulesSetPhases { + public: + + ~RulesSetPhases() { + /** Cleanup the rules */ + for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) { + std::vector rules = m_rules[i]; + while (rules.empty() == false) { + Rule *rule = rules.back(); + rules.pop_back(); + if (rule->refCountDecreaseAndCheck()) { + rule = NULL; + } + } + } + } + + bool insert(Rule *rule) { + if (rule->m_phase >= modsecurity::Phases::NUMBER_OF_PHASES) { + return false; + } + m_rules[rule->m_phase].push_back(rule); + return true; + } + + int append(RulesSetPhases *from, std::ostringstream *err) { + int amount_of_rules = 0; + std::vector v; + + for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) { + v.reserve(m_rules[i].size()); + for (size_t z = 0; z < m_rules[i].size(); z++) { + Rule *rule_ckc = m_rules[i].at(z); + if (rule_ckc->m_secMarker == true) { + continue; + } + v.push_back(rule_ckc->m_ruleId); + } + } + std::sort (v.begin(), v.end()); + + for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) { + for (size_t j = 0; j < from->at(i).size(); j++) { + Rule *rule = from->at(i).at(j); + if (std::binary_search(v.begin(), v.end(), rule->m_ruleId)) { + if (err != NULL) { + *err << "Rule id: " << std::to_string(rule->m_ruleId) \ + << " is duplicated" << std::endl; + } + return -1; + } + amount_of_rules++; + rule->refCountIncrease(); + m_rules[i].push_back(rule); + } + } + + return amount_of_rules; + } + + void dump() const { + for (int i = 0; i <= modsecurity::Phases::NUMBER_OF_PHASES; i++) { + std::cout << "Phase: " << std::to_string(i); + std::cout << " (" << std::to_string(m_rules[i].size()); + std::cout << " rules)" << std::endl; + for (int j = 0; j < m_rules[i].size(); j++) { + std::cout << " Rule ID: " << std::to_string(m_rules[i][j]->m_ruleId); + std::cout << "--" << m_rules[i][j] << std::endl; + } + } + } + + std::vector operator[](int index) const { return m_rules[index]; } + std::vector at(int index) const { return m_rules[index]; } + + std::vector m_rules[8]; +}; + + /** @ingroup ModSecurity_CPP_API */ class RulesSet : public RulesSetProperties { public: @@ -80,6 +159,7 @@ class RulesSet : public RulesSetProperties { int64_t unicode_codepage; + RulesSetPhases m_rulesSetPhases; private: #ifndef NO_LOGS uint8_t m_secmarker_skipped; diff --git a/headers/modsecurity/rules_set_properties.h b/headers/modsecurity/rules_set_properties.h index 252f51f3..66a09a25 100644 --- a/headers/modsecurity/rules_set_properties.h +++ b/headers/modsecurity/rules_set_properties.h @@ -202,17 +202,7 @@ class RulesSetProperties { ~RulesSetProperties() { int i = 0; - /** Cleanup the rules */ - for (i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) { - std::vector rules = m_rules[i]; - while (rules.empty() == false) { - Rule *rule = rules.back(); - rules.pop_back(); - if (rule->refCountDecreaseAndCheck()) { - rule = NULL; - } - } - } + for (i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) { std::vector *tmp = &m_defaultActions[i]; while (tmp->empty() == false) { @@ -354,12 +344,6 @@ class RulesSetProperties { static int mergeProperties(RulesSetProperties *from, RulesSetProperties *to, std::ostringstream *err) { - int amount_of_rules = 0; - - amount_of_rules = appendRules(from->m_rules, to->m_rules, err); - if (amount_of_rules < 0) { - return amount_of_rules; - } merge_ruleengine_value(to->m_secRuleEngine, from->m_secRuleEngine, PropertyNotSetRuleEngine); @@ -471,56 +455,7 @@ class RulesSetProperties { } } - return amount_of_rules; - } - - - static int appendRules( - std::vector *from, - std::vector *to, - std::ostringstream *err) { - int amount_of_rules = 0; - // TODO: std::vector could be replaced with something more efficient. - std::vector v; - for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) { - std::vector *rules_to = to+i; - v.reserve(rules_to->size()); - for (size_t z = 0; z < rules_to->size(); z++) { - Rule *rule_ckc = rules_to->at(z); - if (rule_ckc->m_secMarker == true) { - continue; - } - v.push_back(rule_ckc->m_ruleId); - } - } - std::sort (v.begin(), v.end()); - - for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) { - std::vector *rules_from = from+i; - std::vector *rules_to = to+i; - for (size_t j = 0; j < rules_from->size(); j++) { - Rule *rule = rules_from->at(j); - if (std::binary_search(v.begin(), v.end(), rule->m_ruleId)) { - if (err != NULL) { - *err << "Rule id: " << std::to_string(rule->m_ruleId) \ - << " is duplicated" << std::endl; - } - return -1; - } - amount_of_rules++; - rule->refCountIncrease(); - rules_to->push_back(rule); - } - } - return amount_of_rules; - } - - - std::vector *getRulesForPhase(int phase) { - if (phase >= modsecurity::Phases::NUMBER_OF_PHASES) { - return NULL; - } - return &m_rules[phase]; + return 1; } @@ -551,7 +486,6 @@ class RulesSetProperties { ConfigString m_secArgumentSeparator; ConfigString m_secWebAppId; std::vector m_defaultActions[modsecurity::Phases::NUMBER_OF_PHASES]; - std::vector m_rules[modsecurity::Phases::NUMBER_OF_PHASES]; ConfigUnicodeMap m_unicodeMapTable; }; diff --git a/src/parser/driver.cc b/src/parser/driver.cc index 90415255..5de8c29a 100644 --- a/src/parser/driver.cc +++ b/src/parser/driver.cc @@ -45,7 +45,7 @@ int Driver::addSecMarker(std::string marker) { for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) { Rule *rule = new Rule(marker); rule->m_phase = i; - m_rules[i].push_back(rule); + m_rulesSetPhases.insert(rule); } return 0; } @@ -58,14 +58,15 @@ int Driver::addSecAction(Rule *rule) { return false; } - m_rules[rule->m_phase].push_back(rule); + + m_rulesSetPhases.insert(rule); return true; } int Driver::addSecRuleScript(RuleScript *rule) { - m_rules[rule->m_phase].push_back(rule); + m_rulesSetPhases.insert(rule); return true; } @@ -118,7 +119,7 @@ int Driver::addSecRule(Rule *rule) { return false; } for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) { - std::vector rules = m_rules[i]; + std::vector rules = m_rulesSetPhases[i]; for (int j = 0; j < rules.size(); j++) { if (rules[j]->m_ruleId == rule->m_ruleId) { m_parserError << "Rule id: " << std::to_string(rule->m_ruleId) \ @@ -129,7 +130,7 @@ int Driver::addSecRule(Rule *rule) { } lastRule = rule; - m_rules[rule->m_phase].push_back(rule); + m_rulesSetPhases.insert(rule); return true; } diff --git a/src/parser/driver.h b/src/parser/driver.h index 9cc49ba7..72091f0a 100644 --- a/src/parser/driver.h +++ b/src/parser/driver.h @@ -90,6 +90,8 @@ class Driver : public RulesSetProperties { std::string buffer; Rule *lastRule; + + RulesSetPhases m_rulesSetPhases; }; diff --git a/src/rules_set.cc b/src/rules_set.cc index 0e4987ea..818f422b 100644 --- a/src/rules_set.cc +++ b/src/rules_set.cc @@ -110,7 +110,7 @@ int RulesSet::evaluate(int phase, Transaction *t) { return 0; } - std::vector rules = m_rules[phase]; + std::vector rules = m_rulesSetPhases[phase]; ms_dbg_a(t, 9, "This phase consists of " \ + std::to_string(rules.size()) + " rule(s)."); @@ -222,7 +222,10 @@ int RulesSet::evaluate(int phase, Transaction *t) { int RulesSet::merge(Driver *from) { int amount_of_rules = 0; - amount_of_rules = mergeProperties( + + amount_of_rules = m_rulesSetPhases.append(&from->m_rulesSetPhases, + &m_parserError); + mergeProperties( dynamic_cast(from), dynamic_cast(this), &m_parserError); @@ -233,7 +236,10 @@ int RulesSet::merge(Driver *from) { int RulesSet::merge(RulesSet *from) { int amount_of_rules = 0; - amount_of_rules = mergeProperties( + + amount_of_rules = m_rulesSetPhases.append(&from->m_rulesSetPhases, + &m_parserError); + mergeProperties( dynamic_cast(from), dynamic_cast(this), &m_parserError); @@ -252,17 +258,7 @@ void RulesSet::debug(int level, const std::string &id, void RulesSet::dump() const { - std::cout << "Rules: " << std::endl; - for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) { - std::vector rules = m_rules[i]; - std::cout << "Phase: " << std::to_string(i); - std::cout << " (" << std::to_string(rules.size()); - std::cout << " rules)" << std::endl; - for (int j = 0; j < rules.size(); j++) { - std::cout << " Rule ID: " << std::to_string(rules[j]->m_ruleId); - std::cout << "--" << rules[j] << std::endl; - } - } + m_rulesSetPhases.dump(); } diff --git a/test/optimization/optimization.cc b/test/optimization/optimization.cc index 6dd16e02..34e8a9bf 100644 --- a/test/optimization/optimization.cc +++ b/test/optimization/optimization.cc @@ -68,11 +68,11 @@ int main(int argc, char **argv) { int nphases = modsecurity::Phases::NUMBER_OF_PHASES; for (int j = 0; j < nphases; j++) { - std::vector rules = modsecRules->m_rules[i]; + std::vector rules = modsecRules->m_rulesSetPhases[j]; if (rules.size() == 0) { continue; } - std::cout << "Phase: " << std::to_string(i); + std::cout << "Phase: " << std::to_string(j); std::cout << " (" << std::to_string(rules.size()); std::cout << " rules)" << std::endl;