From 6367e6d5e92556af7fa835341c76b0f430995235 Mon Sep 17 00:00:00 2001 From: Felipe Zimmerle Date: Mon, 19 Nov 2018 13:57:47 -0300 Subject: [PATCH] Having a class Rules --- headers/modsecurity/rules.h | 32 +++++++- headers/modsecurity/rules_set.h | 88 ++------------------- headers/modsecurity/rules_set_phases.h | 60 ++++++++++++++ src/Makefile.am | 2 + src/actions/audit_log.cc | 2 +- src/parser/driver.cc | 6 +- src/rules_set.cc | 10 +-- src/rules_set_phases.cc | 103 +++++++++++++++++++++++++ test/optimization/optimization.cc | 10 +-- 9 files changed, 216 insertions(+), 97 deletions(-) create mode 100644 headers/modsecurity/rules_set_phases.h create mode 100644 src/rules_set_phases.cc diff --git a/headers/modsecurity/rules.h b/headers/modsecurity/rules.h index 685e7c60..36f481a7 100644 --- a/headers/modsecurity/rules.h +++ b/headers/modsecurity/rules.h @@ -13,5 +13,35 @@ * */ -#include + +#include +#include + +#ifdef __cplusplus +#include +#include +#include +#include +#include +#endif + + +#ifndef HEADERS_MODSECURITY_RULES_H_ +#define HEADERS_MODSECURITY_RULES_H_ + + +#ifdef __cplusplus +namespace modsecurity { +class Rule; + +class Rules : public std::vector { + public: +}; + + +} // namespace modsecurity +#endif + + +#endif // HEADERS_MODSECURITY_RULES_H_ diff --git a/headers/modsecurity/rules_set.h b/headers/modsecurity/rules_set.h index bbbc5948..66d9eecd 100644 --- a/headers/modsecurity/rules_set.h +++ b/headers/modsecurity/rules_set.h @@ -1,6 +1,6 @@ /* * ModSecurity, http://www.modsecurity.org/ - * Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * Copyright (c) 2015 - 2020 Trustwave Holdings, Inc. (http://www.trustwave.com/) * * You may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -25,12 +25,14 @@ #endif -#ifndef HEADERS_MODSECURITY_RULES_H_ -#define HEADERS_MODSECURITY_RULES_H_ +#ifndef HEADERS_MODSECURITY_RULES_SET_H_ +#define HEADERS_MODSECURITY_RULES_SET_H_ #include "modsecurity/rules_set_properties.h" #include "modsecurity/modsecurity.h" #include "modsecurity/transaction.h" +#include "modsecurity/rule.h" +#include "modsecurity/rules_set_phases.h" #ifdef __cplusplus @@ -41,84 +43,6 @@ 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 { @@ -186,4 +110,4 @@ int msc_rules_cleanup(RulesSet *rules); } // namespace modsecurity #endif -#endif // HEADERS_MODSECURITY_RULES_H_ +#endif // HEADERS_MODSECURITY_RULES_SET_H_ diff --git a/headers/modsecurity/rules_set_phases.h b/headers/modsecurity/rules_set_phases.h new file mode 100644 index 00000000..35a77985 --- /dev/null +++ b/headers/modsecurity/rules_set_phases.h @@ -0,0 +1,60 @@ + +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2015 - 2020 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + +#include +#include + +#ifdef __cplusplus +#include +#include +#include +#include +#include +#endif + + +#ifndef HEADERS_MODSECURITY_RULES_SET_PHASES_H_ +#define HEADERS_MODSECURITY_RULES_SET_PHASES_H_ + +#include "modsecurity/rules.h" + +#ifdef __cplusplus + +namespace modsecurity { +class Rule; + +/** @ingroup ModSecurity_CPP_API */ +class RulesSetPhases { + public: + + ~RulesSetPhases(); + + bool insert(Rule *rule); + + int append(RulesSetPhases *from, std::ostringstream *err); + void dump() const; + + Rules *operator[](int index) { return &m_rules[index]; } + Rules *at(int index) { return &m_rules[index]; } + + Rules m_rules[8]; +}; + + +} // namespace modsecurity +#endif + +#endif // HEADERS_MODSECURITY_RULES_SET_PHASES_H_ \ No newline at end of file diff --git a/src/Makefile.am b/src/Makefile.am index a437bbfc..4961ea5c 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -42,6 +42,7 @@ pkginclude_HEADERS = \ ../headers/modsecurity/intervention.h \ ../headers/modsecurity/modsecurity.h \ ../headers/modsecurity/rule.h \ + ../headers/modsecurity/rules.h \ ../headers/modsecurity/rule_message.h \ ../headers/modsecurity/rules.h \ ../headers/modsecurity/rules_set.h \ @@ -275,6 +276,7 @@ libmodsecurity_la_SOURCES = \ audit_log/writer/parallel.cc \ modsecurity.cc \ rules_set.cc \ + rules_set_phases.cc \ rules_set_properties.cc \ debug_log/debug_log.cc \ debug_log/debug_log_writer.cc \ diff --git a/src/actions/audit_log.cc b/src/actions/audit_log.cc index 0047eb69..6be014e0 100644 --- a/src/actions/audit_log.cc +++ b/src/actions/audit_log.cc @@ -21,7 +21,7 @@ #include "modsecurity/transaction.h" #include "modsecurity/rule_message.h" -#include "modsecurity/rules.h" +#include "modsecurity/rules_set.h" namespace modsecurity { namespace actions { diff --git a/src/parser/driver.cc b/src/parser/driver.cc index 5de8c29a..3cfa100b 100644 --- a/src/parser/driver.cc +++ b/src/parser/driver.cc @@ -119,9 +119,9 @@ int Driver::addSecRule(Rule *rule) { return false; } for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) { - std::vector rules = m_rulesSetPhases[i]; - for (int j = 0; j < rules.size(); j++) { - if (rules[j]->m_ruleId == rule->m_ruleId) { + Rules *rules = m_rulesSetPhases[i]; + for (int j = 0; j < rules->size(); j++) { + if (rules->at(j)->m_ruleId == rule->m_ruleId) { m_parserError << "Rule id: " << std::to_string(rule->m_ruleId) \ << " is duplicated" << std::endl; return false; diff --git a/src/rules_set.cc b/src/rules_set.cc index 818f422b..e03d478f 100644 --- a/src/rules_set.cc +++ b/src/rules_set.cc @@ -24,6 +24,7 @@ #include "modsecurity/transaction.h" #include "src/parser/driver.h" #include "src/utils/https_client.h" +#include "modsecurity/rules.h" using modsecurity::Parser::Driver; using modsecurity::Utils::HttpsClient; @@ -110,10 +111,10 @@ int RulesSet::evaluate(int phase, Transaction *t) { return 0; } - std::vector rules = m_rulesSetPhases[phase]; + std::vector *rules = m_rulesSetPhases[phase]; ms_dbg_a(t, 9, "This phase consists of " \ - + std::to_string(rules.size()) + " rule(s)."); + + std::to_string(rules->size()) + " rule(s)."); if (t->m_allowType == actions::disruptive::FromNowOnAllowType && phase != modsecurity::Phases::LoggingPhase) { @@ -131,8 +132,8 @@ int RulesSet::evaluate(int phase, Transaction *t) { t->m_allowType = actions::disruptive::NoneAllowType; //} - for (int i = 0; i < rules.size(); i++) { - Rule *rule = rules[i]; + for (int i = 0; i < rules->size(); i++) { + Rule *rule = rules->at(i); if (t->m_marker.empty() == false) { ms_dbg_a(t, 9, "Skipped rule id '" + std::to_string(rule->m_ruleId) \ + "' due to a SecMarker: " + t->m_marker); @@ -256,7 +257,6 @@ void RulesSet::debug(int level, const std::string &id, } - void RulesSet::dump() const { m_rulesSetPhases.dump(); } diff --git a/src/rules_set_phases.cc b/src/rules_set_phases.cc new file mode 100644 index 00000000..efc07505 --- /dev/null +++ b/src/rules_set_phases.cc @@ -0,0 +1,103 @@ +/* + * ModSecurity, http://www.modsecurity.org/ + * Copyright (c) 2015 - 2020 Trustwave Holdings, Inc. (http://www.trustwave.com/) + * + * You may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * If any of the files related to licensing are missing or if you have any + * other questions related to licensing please contact Trustwave Holdings, Inc. + * directly using the email address security@modsecurity.org. + * + */ + +#include +#include +#include +#include +#include + +#include "modsecurity/rules_set_phases.h" +#include "modsecurity/rule.h" +#include "modsecurity/rules.h" +#include "modsecurity/modsecurity.h" + + + +namespace modsecurity { + +RulesSetPhases::~RulesSetPhases() { + /** Cleanup the rules */ + for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) { + Rules *rules = &m_rules[i]; + while (rules->empty() == false) { + Rule *rule = rules->back(); + rules->pop_back(); + if (rule->refCountDecreaseAndCheck()) { + rule = NULL; + } + } + } +} + +bool RulesSetPhases::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 RulesSetPhases::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 RulesSetPhases::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; + } + } +} + + +} // namespace modsecurity + diff --git a/test/optimization/optimization.cc b/test/optimization/optimization.cc index 34e8a9bf..e10365ed 100644 --- a/test/optimization/optimization.cc +++ b/test/optimization/optimization.cc @@ -68,18 +68,18 @@ 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_rulesSetPhases[j]; - if (rules.size() == 0) { + std::vector *rules = modsecRules->m_rulesSetPhases[j]; + if (rules->size() == 0) { continue; } std::cout << "Phase: " << std::to_string(j); - std::cout << " (" << std::to_string(rules.size()); + std::cout << " (" << std::to_string(rules->size()); std::cout << " rules)" << std::endl; std::unordered_map operators; std::unordered_map variables; std::unordered_map op2var; - for (auto &z : rules) { + for (auto &z : *rules) { std::string key; if (z == NULL) { continue; @@ -138,7 +138,7 @@ int main(int argc, char **argv) { std::cout << std::endl; } - total += rules.size(); + total += rules->size(); } std::cout << std::endl;