Refactoring in the Rule class to make it more elegant

This commit is contained in:
Felipe Zimmerle
2019-02-25 20:22:38 -03:00
parent 4c0fc7b6ff
commit a5a0f261e2
23 changed files with 191 additions and 210 deletions

View File

@@ -18,47 +18,38 @@
#include <stdio.h>
#include <algorithm>
#include <iostream>
#include <string>
#include <cstring>
#include <iostream>
#include <list>
#include <utility>
#include <memory>
#include <string>
#include <utility>
#include "modsecurity/rules_set.h"
#include "src/operators/operator.h"
#include "modsecurity/actions/action.h"
#include "modsecurity/modsecurity.h"
#include "src/actions/transformations/none.h"
#include "src/actions/tag.h"
#include "src/utils/string.h"
#include "modsecurity/rule_message.h"
#include "modsecurity/rules_set.h"
#include "modsecurity/rule_with_actions.h"
#include "src/actions/accuracy.h"
#include "src/actions/maturity.h"
#include "src/actions/block.h"
#include "src/actions/capture.h"
#include "src/actions/log_data.h"
#include "src/actions/msg.h"
#include "src/actions/maturity.h"
#include "src/actions/multi_match.h"
#include "src/actions/rev.h"
#include "src/actions/log.h"
#include "src/actions/no_log.h"
#include "src/actions/log_data.h"
#include "src/actions/rev.h"
#include "src/actions/severity.h"
#include "src/actions/capture.h"
#include "src/actions/multi_match.h"
#include "src/actions/set_var.h"
#include "src/actions/block.h"
#include "src/variables/variable.h"
#include "src/actions/severity.h"
#include "src/actions/tag.h"
#include "src/actions/transformations/transformation.h"
#include "src/actions/xmlns.h"
#include "src/utils/string.h"
namespace modsecurity {
using operators::Operator;
using actions::Action;
using variables::Variable;
using actions::transformations::None;
using actions::transformations::Transformation;
RuleWithActions::RuleWithActions(
Actions *actions,
Transformations *transformations,
@@ -74,6 +65,7 @@ RuleWithActions::RuleWithActions(
m_actionsRuntimePos(),
m_actionsSetVar(),
m_actionsTag(),
m_XmlNSs(),
m_defaultActionDisruptiveAction(nullptr),
m_defaultActionLogData(nullptr),
m_defaultActionMsg(nullptr),
@@ -215,8 +207,10 @@ void RuleWithActions::addAction(actions::Action *a) {
} else if (dynamic_cast<actions::Tag *>(a)) {
m_actionsTag.push_back(std::unique_ptr<actions::Tag>(dynamic_cast<actions::Tag *>(a)));
} else if (dynamic_cast<actions::Block *>(a)) {
m_actionsRuntimePos.push_back(std::unique_ptr<actions::Block>(dynamic_cast<actions::Block*>(a)));
m_actionsRuntimePos.push_back(std::unique_ptr<actions::Block>(dynamic_cast<actions::Block *>(a)));
m_containsStaticBlockAction = true;
} else if (dynamic_cast<actions::XmlNS *>(a)) {
m_XmlNSs.push_back(std::unique_ptr<actions::XmlNS>(dynamic_cast<actions::XmlNS *>(a)));
} else if (a->isDisruptive() == true) {
m_disruptiveAction = std::unique_ptr<Action>(a);
} else {
@@ -237,12 +231,6 @@ RuleWithActions::~RuleWithActions() { }
bool RuleWithActions::evaluate(Transaction *transaction) {
/* Rule evaluate is pure virtual.
*
* Rule::evaluate(transaction);
*/
/* Matched vars needs to be clear at every new rule execution */
transaction->m_matched.clear();
@@ -250,8 +238,7 @@ bool RuleWithActions::evaluate(Transaction *transaction) {
}
void RuleWithActions::executeActionsIndependentOfChainedRuleResult(Transaction *trans,
bool *containsBlock) {
void RuleWithActions::executeActionsIndependentOfChainedRuleResult(Transaction *trans) {
for (actions::SetVar *a : getSetVarsActionsPtr()) {
ms_dbg_a(trans, 4, "Running [independent] (non-disruptive) " \
@@ -268,7 +255,6 @@ void RuleWithActions::executeActionsIndependentOfChainedRuleResult(Transaction *
actions::Action *a = dynamic_cast<actions::Action*>(b.second.get());
if (a->isDisruptive() == true && *a->m_name.get() == "block") {
ms_dbg_a(trans, 9, "Rule contains a `block' action");
*containsBlock = true;
} else if (*a->m_name.get() == "setvar") {
ms_dbg_a(trans, 4, "Running [independent] (non-disruptive) " \
"action: " + *a->m_name.get());
@@ -278,8 +264,7 @@ void RuleWithActions::executeActionsIndependentOfChainedRuleResult(Transaction *
}
void RuleWithActions::executeActionsAfterFullMatch(Transaction *trans,
bool containsBlock) {
void RuleWithActions::executeActionsAfterFullMatch(Transaction *trans) {
bool disruptiveAlreadyExecuted = false;
#if 0
@@ -288,7 +273,8 @@ void RuleWithActions::executeActionsAfterFullMatch(Transaction *trans,
continue;
}
if (!a.get()->isDisruptive()) {
executeAction(trans, containsBlock, a.get(), true);
executeAction(trans, a.get(), true);
}
}
#endif
@@ -299,13 +285,18 @@ void RuleWithActions::executeActionsAfterFullMatch(Transaction *trans,
a->evaluate(this, trans, *trans->messageGetLast());
}
/**
*
* FIXME: SecRuleUpdateActionBy should be runtime
*
*/
for (auto &b :
trans->m_rules->m_exceptions.m_action_pos_update_target_by_id) {
if (m_ruleId != b.first) {
continue;
}
actions::Action *a = dynamic_cast<actions::Action*>(b.second.get());
executeAction(trans, containsBlock, a, false);
executeAction(trans, a, false);
disruptiveAlreadyExecuted = true;
}
@@ -325,22 +316,22 @@ void RuleWithActions::executeActionsAfterFullMatch(Transaction *trans,
if (!a->isDisruptive()
&& !(disruptiveAlreadyExecuted
&& dynamic_cast<actions::Block *>(a))) {
executeAction(trans, containsBlock, a, false);
executeAction(trans, a, false);
}
}
if (!disruptiveAlreadyExecuted && m_disruptiveAction != nullptr) {
executeAction(trans, containsBlock,
executeAction(trans,
m_disruptiveAction.get(), false);
} else if (!disruptiveAlreadyExecuted && hasBlockAction()
&& m_defaultActionDisruptiveAction != nullptr) {
executeAction(trans, containsBlock,
executeAction(trans,
m_defaultActionDisruptiveAction.get(), false);
}
}
void RuleWithActions::executeAction(Transaction *trans,
bool containsBlock,
Action *a, bool defaultContext) {
if (a->isDisruptive() == false && *a->m_name.get() != "block") {
ms_dbg_a(trans, 9, "Running " \
@@ -349,15 +340,15 @@ void RuleWithActions::executeAction(Transaction *trans,
return;
}
if (defaultContext && !containsBlock) {
if (defaultContext && !hasBlockAction()) {
ms_dbg_a(trans, 4, "Ignoring action: " + *a->m_name.get() + \
" (rule does not cotains block)");
return;
}
if (trans->getRuleEngineState() == RulesSet::EnabledRuleEngine) {
ms_dbg_a(trans, 4, "Running (disruptive) action: " + *a->m_name.get() + \
".");
ms_dbg_a(trans, 4, "Running (disruptive) action: " +
*a->m_name.get() + ".");
a->evaluate(this, trans, *trans->messageGetLast());
return;
}
@@ -372,8 +363,7 @@ inline void RuleWithActions::executeTransformation(
std::shared_ptr<std::string> *value,
Transaction *trans,
TransformationResults *ret,
std::string *path,
int *nth) const {
std::string *path) const {
std::string *oldValue = (*value).get();
std::string newValue = a->evaluate(*oldValue, trans);
@@ -382,7 +372,6 @@ inline void RuleWithActions::executeTransformation(
std::shared_ptr<std::string> u(new std::string(newValue));
if (m_containsMultiMatchAction) {
ret->push_back(std::make_pair(u, a->m_name));
(*nth)++;
}
*value = u;
}
@@ -393,16 +382,16 @@ inline void RuleWithActions::executeTransformation(
path->append("," + *a->m_name.get());
}
ms_dbg_a(trans, 9, " T (" + \
std::to_string(*nth) + ") " + \
ms_dbg_a(trans, 9, "Transformation " + \
*a->m_name.get() + ": \"" + \
utils::string::limitTo(80, newValue) +"\"");
utils::string::limitTo(80, newValue) + "\"");
}
void RuleWithActions::executeTransformations(
Transaction *trans, const std::string &in, TransformationResults &ret) {
Transaction *trans,
const std::string &in,
TransformationResults &ret) {
int none = 0;
int transformations = 0;
std::string path("");
std::shared_ptr<std::string> value =
std::shared_ptr<std::string>(new std::string(in));
@@ -422,9 +411,7 @@ void RuleWithActions::executeTransformations(
for (Transformation *a : getTransformationPtr()) {
if (none == 0) {
Transformation *t = dynamic_cast<Transformation *>(a);
executeTransformation(t, &value, trans, &ret, &path,
&transformations);
executeTransformation(a, &value, trans, &ret, &path);
}
if (a->m_isNone) {
none--;
@@ -451,9 +438,7 @@ void RuleWithActions::executeTransformations(
}
Transformation *a = dynamic_cast<Transformation*>(b.second.get());
if (none == 0) {
Transformation *t = dynamic_cast<Transformation *>(a);
executeTransformation(t, &value, trans, &ret, &path,
&transformations);
executeTransformation(a, &value, trans, &ret, &path);
}
if (a->m_isNone) {
none--;
@@ -489,42 +474,6 @@ bool RuleWithActions::containsMsg(const std::string& name, Transaction *t) {
}
std::vector<actions::Action *> RuleWithActions::getActionsByName(const std::string& name,
Transaction *trans) {
std::vector<actions::Action *> ret;
for (auto &z : getMatchActionsPtr()) {
if (*z->m_name.get() == name) {
ret.push_back(z);
}
}
for (auto &z : getTransformationPtr()) {
if (*z->m_name.get() == name) {
ret.push_back(z);
}
}
for (auto &b :
trans->m_rules->m_exceptions.m_action_pre_update_target_by_id) {
if (m_ruleId != b.first) {
continue;
}
actions::Action *z = dynamic_cast<actions::Action*>(b.second.get());
if (*z->m_name.get() == name) {
ret.push_back(z);
}
}
for (auto &b :
trans->m_rules->m_exceptions.m_action_pos_update_target_by_id) {
if (m_ruleId != b.first) {
continue;
}
actions::Action *z = dynamic_cast<actions::Action*>(b.second.get());
if (*z->m_name.get() == name) {
ret.push_back(z);
}
}
return ret;
}
std::string RuleWithActions::getLogData(Transaction *t) { return m_logData->data(t); }
std::string RuleWithActions::getMessage(Transaction *t) { return m_msg->data(t); }