actions: Compute the rule association during rules load

This commit is contained in:
Felipe Zimmerle 2020-05-18 15:08:17 -03:00
parent 9dcedd498f
commit c7a78926ee
No known key found for this signature in database
GPG Key ID: E6DFB08CE8B11277
81 changed files with 835 additions and 409 deletions

View File

@ -1,6 +1,9 @@
v3.x.y - YYYY-MMM-DD (to be released) v3.x.y - YYYY-MMM-DD (to be released)
------------------------------------- -------------------------------------
- actions: Computes Rule association while loading the rules given a
performance boost on run time.
[@zimmerle]
- Regression: Mark the test as failed in case of segfault. - Regression: Mark the test as failed in case of segfault.
[@zimmerle] [@zimmerle]
- Replaced t:lowerCase backend for a better performance. - Replaced t:lowerCase backend for a better performance.

View File

@ -24,6 +24,7 @@
#include "modsecurity/intervention.h" #include "modsecurity/intervention.h"
#include "modsecurity/rule.h" #include "modsecurity/rule.h"
#ifndef HEADERS_MODSECURITY_ACTIONS_ACTION_H_ #ifndef HEADERS_MODSECURITY_ACTIONS_ACTION_H_
#define HEADERS_MODSECURITY_ACTIONS_ACTION_H_ #define HEADERS_MODSECURITY_ACTIONS_ACTION_H_
@ -32,7 +33,7 @@
namespace modsecurity { namespace modsecurity {
class Transaction; class Transaction;
class RuleWithActions; class RuleWithActions;
class RunTimeString;
namespace actions { namespace actions {

View File

@ -29,6 +29,7 @@
#include "modsecurity/modsecurity.h" #include "modsecurity/modsecurity.h"
#include "modsecurity/variable_value.h" #include "modsecurity/variable_value.h"
#ifdef __cplusplus #ifdef __cplusplus
namespace modsecurity { namespace modsecurity {

View File

@ -70,8 +70,19 @@ class VariableValue {
} }
} }
VariableValue(const VariableValue &v) = delete; VariableValue(const VariableValue &o) :
m_collection(o.m_collection),
m_key(o.m_key),
m_keyWithCollection(o.m_keyWithCollection),
m_value(o.m_value)
{
for (auto &i : o.m_orign) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
origin->m_offset = i->m_offset;
origin->m_length = i->m_length;
m_orign.push_back(std::move(origin));
}
}
const std::string& getKey() const { const std::string& getKey() const {
return m_key; return m_key;

View File

@ -0,0 +1,87 @@
/*
* 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 "modsecurity/actions/action.h"
#include "src/run_time_string.h"
#ifndef SRC_ACTIONS_ACTION_WITH_RUN_TIME_STRING_H_
#define SRC_ACTIONS_ACTION_WITH_RUN_TIME_STRING_H_
namespace modsecurity {
namespace actions {
class ActionWithRunTimeString : public Action {
public:
ActionWithRunTimeString(
const std::string &name,
int king,
std::unique_ptr<RunTimeString> string)
: Action(name, king),
m_string(std::move(string))
{ };
ActionWithRunTimeString(const std::string &name,
std::unique_ptr<RunTimeString> string)
: Action(name),
m_string(std::move(string))
{ };
ActionWithRunTimeString(const std::string &name,
int king)
: Action(name, king),
m_string(nullptr)
{ };
ActionWithRunTimeString(const std::string &name)
: Action(name),
m_string(nullptr)
{ };
ActionWithRunTimeString(const ActionWithRunTimeString &a)
: Action(a),
m_string(a.m_string?std::unique_ptr<RunTimeString>(new RunTimeString(*a.m_string.get())):nullptr)
{ };
ActionWithRunTimeString& operator=(const ActionWithRunTimeString& a)
{
m_string = std::unique_ptr<RunTimeString>(new RunTimeString(*a.m_string.get()));
return *this;
}
virtual void populate(RuleWithActions *rule) {
if (m_string) {
m_string->populate(rule);
}
}
std::string getEvaluatedRunTimeString(Transaction *transaction) const noexcept {
return (m_string == nullptr)?"":m_string->evaluate(transaction);
}
bool hasRunTimeString() const noexcept {
return m_string != nullptr;
}
virtual ActionWithRunTimeString* clone() = 0;
private:
std::unique_ptr<RunTimeString> m_string;
};
} // namespace actions
} // namespace modsecurity
#endif // SRC_ACTIONS_ACTION_WITH_RUN_TIME_STRING_H_

View File

@ -35,7 +35,7 @@ bool Redirect::init(std::string *error) {
bool Redirect::execute(RuleWithActions *rule, Transaction *transaction) { bool Redirect::execute(RuleWithActions *rule, Transaction *transaction) {
std::string m_urlExpanded(m_string->evaluate(transaction)); std::string m_urlExpanded(getEvaluatedRunTimeString(transaction));
/* if it was changed before, lets keep it. */ /* if it was changed before, lets keep it. */
if (transaction->m_it.status == 200 if (transaction->m_it.status == 200
|| (!(transaction->m_it.status <= 307 && transaction->m_it.status >= 301))) { || (!(transaction->m_it.status <= 307 && transaction->m_it.status >= 301))) {

View File

@ -19,7 +19,7 @@
#include "modsecurity/actions/action.h" #include "modsecurity/actions/action.h"
#include "modsecurity/rule_message.h" #include "modsecurity/rule_message.h"
#include "src/run_time_string.h" #include "src/actions/action_with_run_time_string.h"
#ifndef SRC_ACTIONS_DISRUPTIVE_REDIRECT_H_ #ifndef SRC_ACTIONS_DISRUPTIVE_REDIRECT_H_
#define SRC_ACTIONS_DISRUPTIVE_REDIRECT_H_ #define SRC_ACTIONS_DISRUPTIVE_REDIRECT_H_
@ -34,25 +34,33 @@ namespace actions {
namespace disruptive { namespace disruptive {
class Redirect : public Action { class Redirect : public ActionWithRunTimeString {
public: public:
explicit Redirect(const std::string &action) explicit Redirect(std::unique_ptr<RunTimeString> runTimeString)
: Action(action, RunTimeOnlyIfMatchKind), : ActionWithRunTimeString(
m_status(0), "redirert",
m_string(nullptr) { } RunTimeOnlyIfMatchKind,
std::move(runTimeString)),
m_status(0)
{ };
explicit Redirect(std::unique_ptr<RunTimeString> z) explicit Redirect(const Redirect &action)
: Action("redirert", RunTimeOnlyIfMatchKind), : ActionWithRunTimeString(action),
m_status(0), m_status(action.m_status)
m_string(std::move(z)) { } { };
bool init(std::string *error) override;
bool execute(RuleWithActions *rule, Transaction *transaction) override; bool execute(RuleWithActions *rule, Transaction *transaction) override;
bool init(std::string *error) override;
bool isDisruptive() override { return true; } bool isDisruptive() override { return true; }
virtual ActionWithRunTimeString *clone() override {
return new Redirect(*this);
}
private: private:
int m_status; int m_status;
std::unique_ptr<RunTimeString> m_string;
}; };

View File

@ -55,7 +55,7 @@ bool InitCol::init(std::string *error) {
bool InitCol::execute(RuleWithActions *rule, Transaction *t) { bool InitCol::execute(RuleWithActions *rule, Transaction *t) {
std::string collectionName(m_string->evaluate(t)); std::string collectionName(getEvaluatedRunTimeString(t));
if (m_collection_key == "ip") { if (m_collection_key == "ip") {
t->m_collections.m_ip_collection_key = collectionName; t->m_collections.m_ip_collection_key = collectionName;

View File

@ -18,31 +18,43 @@
#include <memory> #include <memory>
#include "modsecurity/actions/action.h" #include "modsecurity/actions/action.h"
#include "src/run_time_string.h" #include "src/actions/action_with_run_time_string.h"
#ifndef SRC_ACTIONS_INIT_COL_H_ #ifndef SRC_ACTIONS_INIT_COL_H_
#define SRC_ACTIONS_INIT_COL_H_ #define SRC_ACTIONS_INIT_COL_H_
class Transaction;
namespace modsecurity { namespace modsecurity {
class Transaction; class Transaction;
namespace actions { namespace actions {
class InitCol : public Action { class InitCol : public ActionWithRunTimeString {
public: public:
explicit InitCol(const std::string &action) : Action(action) { } InitCol(
const std::string &action,
std::unique_ptr<RunTimeString> runTimeString
) : ActionWithRunTimeString(
action,
std::move(runTimeString)
)
{ };
InitCol(const std::string &action, std::unique_ptr<RunTimeString> z) InitCol(const InitCol &action)
: Action(action, RunTimeOnlyIfMatchKind), : ActionWithRunTimeString(action),
m_string(std::move(z)) { } m_collection_key(action.m_collection_key)
{ };
bool init(std::string *error) override;
bool execute(RuleWithActions *rule, Transaction *transaction) override; bool execute(RuleWithActions *rule, Transaction *transaction) override;
bool init(std::string *error) override;
virtual ActionWithRunTimeString *clone() override {
return new InitCol(*this);
}
private: private:
std::string m_collection_key; std::string m_collection_key;
std::shared_ptr<RunTimeString> m_string;
}; };

View File

@ -30,16 +30,11 @@ namespace actions {
bool LogData::execute(RuleWithActions *rule, Transaction *transaction) { bool LogData::execute(RuleWithActions *rule, Transaction *transaction) {
transaction->messageGetLast()->m_data = data(transaction); transaction->messageGetLast()->m_data = getEvaluatedRunTimeString(transaction);
return true; return true;
} }
std::string LogData::data(Transaction *transaction) {
std::string a(m_string->evaluate(transaction));
return a;
}
} // namespace actions } // namespace actions
} // namespace modsecurity } // namespace modsecurity

View File

@ -18,7 +18,7 @@
#include <utility> #include <utility>
#include "modsecurity/actions/action.h" #include "modsecurity/actions/action.h"
#include "src/run_time_string.h" #include "src/actions/action_with_run_time_string.h"
#ifndef SRC_ACTIONS_LOG_DATA_H_ #ifndef SRC_ACTIONS_LOG_DATA_H_
#define SRC_ACTIONS_LOG_DATA_H_ #define SRC_ACTIONS_LOG_DATA_H_
@ -30,20 +30,25 @@ class Transaction;
namespace actions { namespace actions {
class LogData : public Action { class LogData : public ActionWithRunTimeString {
public: public:
explicit LogData(const std::string &action) explicit LogData(std::unique_ptr<RunTimeString> runTimeString)
: Action(action, RunTimeOnlyIfMatchKind) { } : ActionWithRunTimeString(
"logdata",
RunTimeOnlyIfMatchKind,
std::move(runTimeString)
)
{ };
explicit LogData(std::unique_ptr<RunTimeString> z) explicit LogData(const LogData &data)
: Action("logdata", RunTimeOnlyIfMatchKind), : ActionWithRunTimeString(data)
m_string(std::move(z)) { } { };
bool execute(RuleWithActions *rule, Transaction *transaction) override; bool execute(RuleWithActions *rule, Transaction *transaction) override;
std::string data(Transaction *Transaction); virtual ActionWithRunTimeString *clone() override {
return new LogData(*this);
std::shared_ptr<RunTimeString> m_string; }
}; };

View File

@ -47,7 +47,7 @@ namespace actions {
bool Msg::execute(RuleWithActions *rule, Transaction *transaction) { bool Msg::execute(RuleWithActions *rule, Transaction *transaction) {
std::string msg = data(transaction); std::string msg = getEvaluatedRunTimeString(transaction);
transaction->messageGetLast()->m_message = msg; transaction->messageGetLast()->m_message = msg;
ms_dbg_a(transaction, 9, "Saving msg: " + msg); ms_dbg_a(transaction, 9, "Saving msg: " + msg);
@ -55,11 +55,5 @@ bool Msg::execute(RuleWithActions *rule, Transaction *transaction) {
} }
std::string Msg::data(Transaction *t) {
std::string a(m_string->evaluate(t));
return a;
}
} // namespace actions } // namespace actions
} // namespace modsecurity } // namespace modsecurity

View File

@ -19,7 +19,7 @@
#include "modsecurity/actions/action.h" #include "modsecurity/actions/action.h"
#include "modsecurity/rule_message.h" #include "modsecurity/rule_message.h"
#include "src/run_time_string.h" #include "src/actions/action_with_run_time_string.h"
#ifndef SRC_ACTIONS_MSG_H_ #ifndef SRC_ACTIONS_MSG_H_
#define SRC_ACTIONS_MSG_H_ #define SRC_ACTIONS_MSG_H_
@ -31,19 +31,25 @@ class Transaction;
namespace actions { namespace actions {
class Msg : public Action { class Msg : public ActionWithRunTimeString {
public: public:
explicit Msg(const std::string &action) explicit Msg(std::unique_ptr<RunTimeString> runTimeString)
: Action(action, RunTimeOnlyIfMatchKind) { } : ActionWithRunTimeString(
"msg",
RunTimeOnlyIfMatchKind,
std::move(runTimeString)
)
{ };
explicit Msg(std::unique_ptr<RunTimeString> z) explicit Msg(const Msg &action)
: Action("msg", RunTimeOnlyIfMatchKind), : ActionWithRunTimeString(action)
m_string(std::move(z)) { } { };
bool execute(RuleWithActions *rule, Transaction *transaction) override; bool execute(RuleWithActions *rule, Transaction *transaction) override;
std::string data(Transaction *Transaction); virtual ActionWithRunTimeString *clone() override {
std::shared_ptr<RunTimeString> m_string; return new Msg(*this);
}
}; };

View File

@ -28,13 +28,8 @@ namespace modsecurity {
namespace actions { namespace actions {
bool SetENV::init(std::string *error) {
return true;
}
bool SetENV::execute(RuleWithActions *rule, Transaction *t) { bool SetENV::execute(RuleWithActions *rule, Transaction *t) {
std::string colNameExpanded(m_string->evaluate(t)); std::string colNameExpanded(getEvaluatedRunTimeString(t));
ms_dbg_a(t, 8, "Setting envoriment variable: " ms_dbg_a(t, 8, "Setting envoriment variable: "
+ colNameExpanded + "."); + colNameExpanded + ".");

View File

@ -18,7 +18,7 @@
#include <memory> #include <memory>
#include "modsecurity/actions/action.h" #include "modsecurity/actions/action.h"
#include "src/run_time_string.h" #include "src/actions/action_with_run_time_string.h"
#ifndef SRC_ACTIONS_SET_ENV_H_ #ifndef SRC_ACTIONS_SET_ENV_H_
#define SRC_ACTIONS_SET_ENV_H_ #define SRC_ACTIONS_SET_ENV_H_
@ -30,20 +30,25 @@ class Transaction;
namespace actions { namespace actions {
class SetENV : public Action { class SetENV : public ActionWithRunTimeString {
public: public:
explicit SetENV(const std::string &_action) explicit SetENV(std::unique_ptr<RunTimeString> runTimeString)
: Action(_action) { } : ActionWithRunTimeString(
"setenv",
RunTimeOnlyIfMatchKind,
std::move(runTimeString)
)
{ };
explicit SetENV(std::unique_ptr<RunTimeString> z) explicit SetENV(const SetENV &action)
: Action("setenv", RunTimeOnlyIfMatchKind), : ActionWithRunTimeString(action)
m_string(std::move(z)) { } { };
bool execute(RuleWithActions *rule, Transaction *transaction) override; bool execute(RuleWithActions *rule, Transaction *transaction) override;
bool init(std::string *error) override;
private: virtual ActionWithRunTimeString *clone() override {
std::shared_ptr<RunTimeString> m_string; return new SetENV(*this);
}
}; };

View File

@ -26,13 +26,8 @@ namespace modsecurity {
namespace actions { namespace actions {
bool SetRSC::init(std::string *error) {
return true;
}
bool SetRSC::execute(RuleWithActions *rule, Transaction *t) { bool SetRSC::execute(RuleWithActions *rule, Transaction *t) {
std::string colNameExpanded(m_string->evaluate(t)); std::string colNameExpanded(getEvaluatedRunTimeString(t));
ms_dbg_a(t, 8, "RESOURCE initiated with value: \'" ms_dbg_a(t, 8, "RESOURCE initiated with value: \'"
+ colNameExpanded + "\'."); + colNameExpanded + "\'.");
@ -42,5 +37,6 @@ bool SetRSC::execute(RuleWithActions *rule, Transaction *t) {
return true; return true;
} }
} // namespace actions } // namespace actions
} // namespace modsecurity } // namespace modsecurity

View File

@ -18,7 +18,7 @@
#include <memory> #include <memory>
#include "modsecurity/actions/action.h" #include "modsecurity/actions/action.h"
#include "src/run_time_string.h" #include "src/actions/action_with_run_time_string.h"
#ifndef SRC_ACTIONS_SET_RSC_H_ #ifndef SRC_ACTIONS_SET_RSC_H_
#define SRC_ACTIONS_SET_RSC_H_ #define SRC_ACTIONS_SET_RSC_H_
@ -30,20 +30,25 @@ class Transaction;
namespace actions { namespace actions {
class SetRSC : public Action { class SetRSC : public ActionWithRunTimeString {
public: public:
explicit SetRSC(const std::string &_action) explicit SetRSC(std::unique_ptr<RunTimeString> runTimeString)
: Action(_action) { } : ActionWithRunTimeString(
"setsrc",
RunTimeOnlyIfMatchKind,
std::move(runTimeString)
)
{ };
explicit SetRSC(std::unique_ptr<RunTimeString> z) explicit SetRSC(const SetRSC &action)
: Action("setsrc", RunTimeOnlyIfMatchKind), : ActionWithRunTimeString(action)
m_string(std::move(z)) { } { };
bool execute(RuleWithActions *rule, Transaction *transaction) override; bool execute(RuleWithActions *rule, Transaction *transaction) override;
bool init(std::string *error) override;
private: virtual ActionWithRunTimeString *clone() override {
std::shared_ptr<RunTimeString> m_string; return new SetRSC(*this);
}
}; };

View File

@ -26,13 +26,8 @@ namespace modsecurity {
namespace actions { namespace actions {
bool SetSID::init(std::string *error) {
return true;
}
bool SetSID::execute(RuleWithActions *rule, Transaction *t) { bool SetSID::execute(RuleWithActions *rule, Transaction *t) {
std::string colNameExpanded(m_string->evaluate(t)); std::string colNameExpanded(getEvaluatedRunTimeString(t));
ms_dbg_a(t, 8, "Session ID initiated with value: \'" ms_dbg_a(t, 8, "Session ID initiated with value: \'"
+ colNameExpanded + "\'."); + colNameExpanded + "\'.");
@ -42,5 +37,6 @@ bool SetSID::execute(RuleWithActions *rule, Transaction *t) {
return true; return true;
} }
} // namespace actions } // namespace actions
} // namespace modsecurity } // namespace modsecurity

View File

@ -18,7 +18,7 @@
#include <memory> #include <memory>
#include "modsecurity/actions/action.h" #include "modsecurity/actions/action.h"
#include "src/run_time_string.h" #include "src/actions/action_with_run_time_string.h"
#ifndef SRC_ACTIONS_SET_SID_H_ #ifndef SRC_ACTIONS_SET_SID_H_
#define SRC_ACTIONS_SET_SID_H_ #define SRC_ACTIONS_SET_SID_H_
@ -30,20 +30,25 @@ class Transaction;
namespace actions { namespace actions {
class SetSID : public Action { class SetSID : public ActionWithRunTimeString {
public: public:
explicit SetSID(const std::string &_action) explicit SetSID(std::unique_ptr<RunTimeString> runTimeString)
: Action(_action) { } : ActionWithRunTimeString(
"setsid",
RunTimeOnlyIfMatchKind,
std::move(runTimeString)
)
{ };
explicit SetSID(std::unique_ptr<RunTimeString> z) SetSID(const SetSID &action)
: Action("setsid", RunTimeOnlyIfMatchKind), : ActionWithRunTimeString(action)
m_string(std::move(z)) { } { };
bool execute(RuleWithActions *rule, Transaction *transaction) override; bool execute(RuleWithActions *rule, Transaction *transaction) override;
bool init(std::string *error) override;
private: virtual ActionWithRunTimeString *clone() override {
std::shared_ptr<RunTimeString> m_string; return new SetSID(*this);
}
}; };

View File

@ -26,13 +26,8 @@ namespace modsecurity {
namespace actions { namespace actions {
bool SetUID::init(std::string *error) {
return true;
}
bool SetUID::execute(RuleWithActions *rule, Transaction *t) { bool SetUID::execute(RuleWithActions *rule, Transaction *t) {
std::string colNameExpanded(m_string->evaluate(t)); std::string colNameExpanded(getEvaluatedRunTimeString(t));
ms_dbg_a(t, 8, "User collection initiated with value: \'" ms_dbg_a(t, 8, "User collection initiated with value: \'"
+ colNameExpanded + "\'."); + colNameExpanded + "\'.");
@ -42,5 +37,6 @@ bool SetUID::execute(RuleWithActions *rule, Transaction *t) {
return true; return true;
} }
} // namespace actions } // namespace actions
} // namespace modsecurity } // namespace modsecurity

View File

@ -18,7 +18,7 @@
#include <utility> #include <utility>
#include "modsecurity/actions/action.h" #include "modsecurity/actions/action.h"
#include "src/run_time_string.h" #include "src/actions/action_with_run_time_string.h"
#ifndef SRC_ACTIONS_SET_UID_H_ #ifndef SRC_ACTIONS_SET_UID_H_
#define SRC_ACTIONS_SET_UID_H_ #define SRC_ACTIONS_SET_UID_H_
@ -30,20 +30,26 @@ class Transaction;
namespace actions { namespace actions {
class SetUID : public Action { class SetUID : public ActionWithRunTimeString {
public: public:
explicit SetUID(const std::string &_action) explicit SetUID(std::unique_ptr<RunTimeString> runTimeString)
: Action(_action) { } : ActionWithRunTimeString(
"setuid",
RunTimeOnlyIfMatchKind,
std::move(runTimeString)
)
{ };
explicit SetUID(std::unique_ptr<RunTimeString> z) explicit SetUID(const SetUID &action)
: Action("setuid", RunTimeOnlyIfMatchKind), : ActionWithRunTimeString(action)
m_string(std::move(z)) { } { };
bool execute(RuleWithActions *rule, Transaction *transaction) override; bool execute(RuleWithActions *rule, Transaction *transaction) override;
bool init(std::string *error) override;
private: virtual ActionWithRunTimeString *clone() override {
std::shared_ptr<RunTimeString> m_string; return new SetUID(*this);
}
}; };

View File

@ -46,8 +46,8 @@ bool SetVar::execute(RuleWithActions *rule, Transaction *t) {
std::string targetValue; std::string targetValue;
std::string resolvedPre; std::string resolvedPre;
if (m_string) { if (hasRunTimeString()) {
resolvedPre = m_string->evaluate(t, rule); resolvedPre = getEvaluatedRunTimeString(t);
} }
std::string m_variableNameExpanded; std::string m_variableNameExpanded;
@ -66,17 +66,17 @@ bool SetVar::execute(RuleWithActions *rule, Transaction *t) {
variables::User_DynamicElement *user = dynamic_cast< variables::User_DynamicElement *user = dynamic_cast<
variables::User_DynamicElement *> (v); variables::User_DynamicElement *> (v);
if (tx) { if (tx) {
m_variableNameExpanded = tx->m_string->evaluate(t, rule); m_variableNameExpanded = tx->evaluateRunTimeString(t);
} else if (session) { } else if (session) {
m_variableNameExpanded = session->m_string->evaluate(t, rule); m_variableNameExpanded = session->evaluateRunTimeString(t);
} else if (ip) { } else if (ip) {
m_variableNameExpanded = ip->m_string->evaluate(t, rule); m_variableNameExpanded = ip->evaluateRunTimeString(t);
} else if (resource) { } else if (resource) {
m_variableNameExpanded = resource->m_string->evaluate(t, rule); m_variableNameExpanded = resource->evaluateRunTimeString(t);
} else if (global) { } else if (global) {
m_variableNameExpanded = global->m_string->evaluate(t, rule); m_variableNameExpanded = global->evaluateRunTimeString(t);
} else if (user) { } else if (user) {
m_variableNameExpanded = user->m_string->evaluate(t, rule); m_variableNameExpanded = user->evaluateRunTimeString(t);
} else { } else {
m_variableNameExpanded = m_variable->m_name; m_variableNameExpanded = m_variable->m_name;
} }
@ -114,8 +114,7 @@ bool SetVar::execute(RuleWithActions *rule, Transaction *t) {
try { try {
std::vector<const VariableValue *> l; std::vector<const VariableValue *> l;
RuleWithOperator *rr = dynamic_cast<RuleWithOperator *>(rule); m_variable->evaluate(t, &l);
m_variable->evaluate(t, rr, &l);
if (l.size() == 0) { if (l.size() == 0) {
value = 0; value = 0;
} else { } else {

View File

@ -18,7 +18,8 @@
#include <utility> #include <utility>
#include "modsecurity/actions/action.h" #include "modsecurity/actions/action.h"
#include "src/run_time_string.h" #include "src/actions/action_with_run_time_string.h"
#include "src/variables/variable_with_runtime_string.h"
#ifndef SRC_ACTIONS_SET_VAR_H_ #ifndef SRC_ACTIONS_SET_VAR_H_
#define SRC_ACTIONS_SET_VAR_H_ #define SRC_ACTIONS_SET_VAR_H_
@ -42,29 +43,63 @@ enum SetVarOperation {
unsetOperation, unsetOperation,
}; };
class SetVar : public Action { class SetVar : public ActionWithRunTimeString {
public: public:
SetVar(SetVarOperation operation, SetVar(SetVarOperation operation,
std::unique_ptr<modsecurity::variables::Variable> variable, std::unique_ptr<modsecurity::variables::Variable> variable,
std::unique_ptr<RunTimeString> predicate) std::unique_ptr<RunTimeString> predicate)
: Action("setvar"), : ActionWithRunTimeString("setvar", std::move(predicate)),
m_operation(operation), m_operation(operation),
m_variable(std::move(variable)), m_variable(std::move(variable))
m_string(std::move(predicate)) { } { };
SetVar(SetVarOperation operation, SetVar(SetVarOperation operation,
std::unique_ptr<modsecurity::variables::Variable> variable) std::unique_ptr<modsecurity::variables::Variable> variable)
: Action("setvar"), : ActionWithRunTimeString("setvar"),
m_operation(operation), m_operation(operation),
m_variable(std::move(variable)) { } m_variable(std::move(variable))
{ };
SetVar(const SetVar &var)
: ActionWithRunTimeString(var),
m_operation(var.m_operation),
m_variable(var.m_variable)
{
variables::RuleVariable *rv = dynamic_cast<variables::RuleVariable *>(m_variable.get());
if (rv != nullptr) {
auto nrv = rv->clone();
rv = dynamic_cast<variables::RuleVariable *>(nrv);
rv->populate(nullptr);
m_variable = std::unique_ptr<variables::Variable>(nrv);
}
};
bool execute(RuleWithActions *rule, Transaction *transaction) override; bool execute(RuleWithActions *rule, Transaction *transaction) override;
bool init(std::string *error) override; bool init(std::string *error) override;
void populate(RuleWithActions *rule) override {
ActionWithRunTimeString::populate(rule);
variables::RuleVariable *rulev = dynamic_cast<variables::RuleVariable *>(m_variable.get());
if (rulev != nullptr) {
rulev->populate(rule);
}
variables::VariableWithRunTimeString *rulev2 = dynamic_cast<variables::VariableWithRunTimeString *>(m_variable.get());
if (rulev2 != nullptr) {
rulev2->populate(rule);
}
}
virtual ActionWithRunTimeString *clone() override {
return new SetVar(*this);
}
private: private:
SetVarOperation m_operation; SetVarOperation m_operation;
std::shared_ptr<modsecurity::variables::Variable> m_variable; std::shared_ptr<modsecurity::variables::Variable> m_variable;
std::shared_ptr<RunTimeString> m_string;
}; };
} // namespace actions } // namespace actions

View File

@ -50,14 +50,8 @@ namespace modsecurity {
namespace actions { namespace actions {
std::string Tag::getName(Transaction *transaction) {
std::string tag(m_string->evaluate(transaction));
return tag;
}
bool Tag::execute(RuleWithActions *rule, Transaction *transaction) { bool Tag::execute(RuleWithActions *rule, Transaction *transaction) {
std::string tag = getName(transaction); std::string tag = getTagName(transaction);
ms_dbg_a(transaction, 9, "Rule tag: " + tag); ms_dbg_a(transaction, 9, "Rule tag: " + tag);
transaction->messageGetLast()->m_tags.push_back(tag); transaction->messageGetLast()->m_tags.push_back(tag);

View File

@ -18,7 +18,7 @@
#include <utility> #include <utility>
#include "modsecurity/actions/action.h" #include "modsecurity/actions/action.h"
#include "src/run_time_string.h" #include "src/actions/action_with_run_time_string.h"
#ifndef SRC_ACTIONS_TAG_H_ #ifndef SRC_ACTIONS_TAG_H_
#define SRC_ACTIONS_TAG_H_ #define SRC_ACTIONS_TAG_H_
@ -30,18 +30,29 @@ class Transaction;
namespace actions { namespace actions {
class Tag : public Action { class Tag : public ActionWithRunTimeString {
public: public:
explicit Tag(std::unique_ptr<RunTimeString> z) explicit Tag(std::unique_ptr<RunTimeString> runTimeString)
: Action("tag", RunTimeOnlyIfMatchKind), : ActionWithRunTimeString(
m_string(std::move(z)) { } "tag",
RunTimeOnlyIfMatchKind,
std::move(runTimeString)
)
{ };
std::string getName(Transaction *transaction); explicit Tag(const Tag &action)
: ActionWithRunTimeString(action)
{ };
bool execute(RuleWithActions *rule, Transaction *transaction) override; bool execute(RuleWithActions *rule, Transaction *transaction) override;
protected: inline std::string getTagName(Transaction *transaction) const {
std::shared_ptr<RunTimeString> m_string; return getEvaluatedRunTimeString(transaction);
}
virtual ActionWithRunTimeString *clone() override {
return new Tag(*this);
}
}; };

View File

@ -29,7 +29,18 @@ namespace actions {
class XmlNS : public Action { class XmlNS : public Action {
public: public:
explicit XmlNS(const std::string &action) : Action(action) { } explicit XmlNS(const std::string &action)
: Action(action),
m_scope(""),
m_href("")
{ };
XmlNS(const XmlNS &o)
: Action(o),
m_scope(o.m_scope),
m_href(o.m_href)
{ };
bool execute(RuleWithActions *rule, Transaction *transaction) override { bool execute(RuleWithActions *rule, Transaction *transaction) override {
return true; return true;
@ -37,6 +48,15 @@ class XmlNS : public Action {
bool init(std::string *error) override; bool init(std::string *error) override;
std::string getScope() const {
return m_scope;
}
std::string getHref() const {
return m_href;
}
private:
std::string m_scope; std::string m_scope;
std::string m_href; std::string m_href;
}; };

View File

@ -212,6 +212,7 @@ void ModSecurity::serverLog(void *data, RuleMessage *rm) {
m_logCb(data, a); m_logCb(data, a);
return; return;
} }
m_logCb(data, a); m_logCb(data, a);
return; return;
} }

View File

@ -54,7 +54,7 @@ bool InspectFile::evaluate(Transaction *transaction,
const bpstd::string_view &str, const bpstd::string_view &str,
RuleMessage *ruleMessage) { RuleMessage *ruleMessage) {
if (m_isScript) { if (m_isScript) {
return m_lua.run(transaction, str.c_str()); return m_lua.run(transaction, str.to_string());
} else { } else {
FILE *in; FILE *in;
char buff[512]; char buff[512];
@ -64,7 +64,7 @@ bool InspectFile::evaluate(Transaction *transaction,
openstr.append(m_param); openstr.append(m_param);
openstr.append(" "); openstr.append(" ");
openstr.append(str.c_str()); openstr.append(str.to_string());
if (!(in = popen(openstr.c_str(), "r"))) { if (!(in = popen(openstr.c_str(), "r"))) {
return false; return false;
} }

View File

@ -30,7 +30,7 @@ namespace operators {
bool Rx::init(const std::string &file, std::string *error) { bool Rx::init(const std::string &file, std::string *error) {
if (m_string->m_containsMacro == false) { if (m_string->containsMacro() == false) {
m_re = new Regex(m_param); m_re = new Regex(m_param);
} }
@ -44,11 +44,11 @@ bool Rx::evaluate(Transaction *transaction,
RuleMessage *ruleMessage) { RuleMessage *ruleMessage) {
Regex *re; Regex *re;
if (m_param.empty() && !m_string->m_containsMacro) { if (m_param.empty() && !m_string->containsMacro()) {
return true; return true;
} }
if (m_string->m_containsMacro) { if (m_string->containsMacro()) {
std::string eparam(m_string->evaluate(transaction)); std::string eparam(m_string->evaluate(transaction));
re = new Regex(eparam); re = new Regex(eparam);
} else { } else {
@ -73,12 +73,12 @@ bool Rx::evaluate(Transaction *transaction,
logOffset(ruleMessage, capture.m_offset, capture.m_length); logOffset(ruleMessage, capture.m_offset, capture.m_length);
} }
if (!captures.empty()) { if (m_string->containsMacro()) {
return true; delete re;
} }
if (m_string->m_containsMacro) { if (!captures.empty()) {
delete re; return true;
} }
return false; return false;

View File

@ -43,7 +43,7 @@ class Rx : public Operator {
} }
~Rx() { ~Rx() {
if (m_string->m_containsMacro == false && m_re != NULL) { if (m_string->containsMacro() == false && m_re != NULL) {
delete m_re; delete m_re;
m_re = NULL; m_re = NULL;
} }

View File

@ -3800,7 +3800,7 @@ namespace yy {
case 216: case 216:
#line 2089 "seclang-parser.yy" #line 2089 "seclang-parser.yy"
{ {
VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::XML("XML:" + yystack_[0].value.as < std::string > ())); VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::XML_WithNSPath(yystack_[0].value.as < std::string > ()));
} }
#line 3806 "seclang-parser.cc" #line 3806 "seclang-parser.cc"
break; break;
@ -3808,7 +3808,7 @@ namespace yy {
case 217: case 217:
#line 2093 "seclang-parser.yy" #line 2093 "seclang-parser.yy"
{ {
VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::XML("XML:" + yystack_[0].value.as < std::string > ())); VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::XML_WithNSPath(yystack_[0].value.as < std::string > ()));
} }
#line 3814 "seclang-parser.cc" #line 3814 "seclang-parser.cc"
break; break;
@ -3816,7 +3816,7 @@ namespace yy {
case 218: case 218:
#line 2097 "seclang-parser.yy" #line 2097 "seclang-parser.yy"
{ {
VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::XML_NoDictElement()); VARIABLE_CONTAINER(yylhs.value.as < std::unique_ptr<Variable> > (), new variables::XML_WithoutNSPath());
} }
#line 3822 "seclang-parser.cc" #line 3822 "seclang-parser.cc"
break; break;

View File

@ -2087,15 +2087,15 @@ var:
} }
| RUN_TIME_VAR_XML DICT_ELEMENT | RUN_TIME_VAR_XML DICT_ELEMENT
{ {
VARIABLE_CONTAINER($$, new variables::XML("XML:" + $2)); VARIABLE_CONTAINER($$, new variables::XML_WithNSPath($2));
} }
| RUN_TIME_VAR_XML DICT_ELEMENT_REGEXP | RUN_TIME_VAR_XML DICT_ELEMENT_REGEXP
{ {
VARIABLE_CONTAINER($$, new variables::XML("XML:" + $2)); VARIABLE_CONTAINER($$, new variables::XML_WithNSPath($2));
} }
| RUN_TIME_VAR_XML | RUN_TIME_VAR_XML
{ {
VARIABLE_CONTAINER($$, new variables::XML_NoDictElement()); VARIABLE_CONTAINER($$, new variables::XML_WithoutNSPath());
} }
| VARIABLE_FILES_TMP_NAMES DICT_ELEMENT | VARIABLE_FILES_TMP_NAMES DICT_ELEMENT
{ {

View File

@ -46,6 +46,7 @@
#include "src/actions/transformations/transformation.h" #include "src/actions/transformations/transformation.h"
#include "src/actions/xmlns.h" #include "src/actions/xmlns.h"
#include "src/utils/string.h" #include "src/utils/string.h"
#include "src/actions/action_with_run_time_string.h"
namespace modsecurity { namespace modsecurity {
@ -104,6 +105,14 @@ RuleWithActions::RuleWithActions(
} }
void RuleWithActions::addDefaultAction(std::shared_ptr<actions::Action> a) { void RuleWithActions::addDefaultAction(std::shared_ptr<actions::Action> a) {
actions::ActionWithRunTimeString *arts = dynamic_cast<actions::ActionWithRunTimeString *>(a.get());
if (arts != nullptr) {
a = std::unique_ptr<actions::Action>(arts->clone());
arts = dynamic_cast<actions::ActionWithRunTimeString *>(a.get());
arts->populate(this);
}
if (a->m_actionKind == Action::ConfigurationKind) { if (a->m_actionKind == Action::ConfigurationKind) {
if (dynamic_cast<actions::Accuracy *>(a.get())) { if (dynamic_cast<actions::Accuracy *>(a.get())) {
actions::Accuracy *accuracy = dynamic_cast<actions::Accuracy *>(a.get()); actions::Accuracy *accuracy = dynamic_cast<actions::Accuracy *>(a.get());
@ -133,7 +142,8 @@ void RuleWithActions::addDefaultAction(std::shared_ptr<actions::Action> a) {
} else if (dynamic_cast<actions::Msg *>(a.get())) { } else if (dynamic_cast<actions::Msg *>(a.get())) {
m_defaultActionMsg = std::static_pointer_cast<actions::Msg>(a); m_defaultActionMsg = std::static_pointer_cast<actions::Msg>(a);
} else if (dynamic_cast<actions::SetVar *>(a.get())) { } else if (dynamic_cast<actions::SetVar *>(a.get())) {
m_defaultActionActionsSetVar.push_back(std::static_pointer_cast<actions::SetVar>(a)); actions::SetVar *var = dynamic_cast<actions::SetVar *>(a.get());
m_actionsSetVar.push_back(std::unique_ptr<actions::SetVar>(var));
} else if (dynamic_cast<actions::Tag *>(a.get())) { } else if (dynamic_cast<actions::Tag *>(a.get())) {
m_defaultActionActionsTag.push_back(std::static_pointer_cast<actions::Tag>(a)); m_defaultActionActionsTag.push_back(std::static_pointer_cast<actions::Tag>(a));
} else if (dynamic_cast<actions::Log *>(a.get())) { } else if (dynamic_cast<actions::Log *>(a.get())) {
@ -158,6 +168,13 @@ void RuleWithActions::addDefaultAction(std::shared_ptr<actions::Action> a) {
} }
void RuleWithActions::addAction(actions::Action *a) { void RuleWithActions::addAction(actions::Action *a) {
actions::ActionWithRunTimeString *arts = dynamic_cast<actions::ActionWithRunTimeString *>(a);
if (arts != nullptr) {
a = arts->clone();
arts = dynamic_cast<actions::ActionWithRunTimeString *>(a);
arts->populate(this);
}
if (a->m_actionKind == Action::ConfigurationKind) { if (a->m_actionKind == Action::ConfigurationKind) {
if (dynamic_cast<actions::Accuracy *>(a)) { if (dynamic_cast<actions::Accuracy *>(a)) {
actions::Accuracy *accuracy = dynamic_cast<actions::Accuracy *>(a); actions::Accuracy *accuracy = dynamic_cast<actions::Accuracy *>(a);
@ -188,7 +205,8 @@ void RuleWithActions::addAction(actions::Action *a) {
} else if (dynamic_cast<actions::Msg *>(a)) { } else if (dynamic_cast<actions::Msg *>(a)) {
m_msg = std::unique_ptr<actions::Msg>(dynamic_cast<actions::Msg*>(a)); m_msg = std::unique_ptr<actions::Msg>(dynamic_cast<actions::Msg*>(a));
} else if (dynamic_cast<actions::SetVar *>(a)) { } else if (dynamic_cast<actions::SetVar *>(a)) {
m_actionsSetVar.push_back(std::unique_ptr<actions::SetVar>(dynamic_cast<actions::SetVar *>(a))); actions::SetVar *var = dynamic_cast<actions::SetVar *>(a);
m_actionsSetVar.push_back(std::unique_ptr<actions::SetVar>(var));
} else if (dynamic_cast<actions::Maturity *>(a)) { } else if (dynamic_cast<actions::Maturity *>(a)) {
actions::Maturity *maturity = dynamic_cast<actions::Maturity *>(a); actions::Maturity *maturity = dynamic_cast<actions::Maturity *>(a);
m_maturity = maturity->getMaturity(); m_maturity = maturity->getMaturity();
@ -460,7 +478,7 @@ void RuleWithActions::executeTransformation(
bool RuleWithActions::containsTag(const std::string& name, Transaction *t) const { bool RuleWithActions::containsTag(const std::string& name, Transaction *t) const {
for (auto &tag : getTagsAction()) { for (auto &tag : getTagsAction()) {
if (tag != NULL && tag->getName(t) == name) { if (tag != NULL && tag->getTagName(t) == name) {
return true; return true;
} }
} }
@ -469,13 +487,12 @@ bool RuleWithActions::containsTag(const std::string& name, Transaction *t) const
bool RuleWithActions::containsMsg(const std::string& name, Transaction *t) { bool RuleWithActions::containsMsg(const std::string& name, Transaction *t) {
return m_msg && m_msg->data(t) == name; return m_msg && m_msg->getEvaluatedRunTimeString(t) == name;
} }
std::string RuleWithActions::getLogData(Transaction *t) { return m_logData->data(t); } std::string RuleWithActions::getLogData(Transaction *t) const { return m_logData->getEvaluatedRunTimeString(t); }
std::string RuleWithActions::getMessage(Transaction *t) { return m_msg->data(t); } std::string RuleWithActions::getMessage(Transaction *t) const { return m_msg->getEvaluatedRunTimeString(t); }
} // namespace modsecurity } // namespace modsecurity

View File

@ -155,7 +155,9 @@ class RuleWithActions : public Rule {
m_defaultContainsNoLogAction(r.m_defaultContainsNoLogAction), m_defaultContainsNoLogAction(r.m_defaultContainsNoLogAction),
m_defaultContainsMultiMatchAction(r.m_defaultContainsMultiMatchAction), m_defaultContainsMultiMatchAction(r.m_defaultContainsMultiMatchAction),
m_defaultContainsStaticBlockAction(r.m_defaultContainsStaticBlockAction), m_defaultContainsStaticBlockAction(r.m_defaultContainsStaticBlockAction),
m_isChained(r.m_isChained) { }; m_isChained(r.m_isChained) {
// TODO: Verify if it is necessary to process any other copy.
};
RuleWithActions &operator=(const RuleWithActions& r) { RuleWithActions &operator=(const RuleWithActions& r) {
Rule::operator = (r); Rule::operator = (r);
@ -199,6 +201,7 @@ class RuleWithActions : public Rule {
m_defaultContainsStaticBlockAction = r.m_defaultContainsStaticBlockAction; m_defaultContainsStaticBlockAction = r.m_defaultContainsStaticBlockAction;
m_isChained = r.m_isChained; m_isChained = r.m_isChained;
return *this; return *this;
// TODO: Verify if it is necessary to process any other copy.
} }
@ -358,13 +361,13 @@ class RuleWithActions : public Rule {
inline bool hasLogDataAction() const { return m_logData != nullptr || m_defaultActionLogData != nullptr; } inline bool hasLogDataAction() const { return m_logData != nullptr || m_defaultActionLogData != nullptr; }
inline std::shared_ptr<actions::LogData> getLogDataAction() const { return m_logData; } inline std::shared_ptr<actions::LogData> getLogDataAction() const { return m_logData; }
std::string getLogData(/*const */Transaction *t); std::string getLogData(/*const */Transaction *t) const;
inline void setLogDataAction(const std::shared_ptr<actions::LogData> &data) { m_logData = data; } inline void setLogDataAction(const std::shared_ptr<actions::LogData> &data) { m_logData = data; }
inline bool hasMessageAction() const { return m_msg != nullptr || m_defaultActionMsg != nullptr; } inline bool hasMessageAction() const { return m_msg != nullptr || m_defaultActionMsg != nullptr; }
inline std::shared_ptr<actions::Msg> getMessageAction() const { return m_msg; } inline std::shared_ptr<actions::Msg> getMessageAction() const { return m_msg; }
inline void setMessageAction(const std::shared_ptr<actions::Msg> &msg) { m_msg = msg; } inline void setMessageAction(const std::shared_ptr<actions::Msg> &msg) { m_msg = msg; }
std::string getMessage(/*const */Transaction *t); std::string getMessage(/*const */Transaction *t) const;
inline bool hasSeverityAction() const { return m_severity != SEVERITY_NOT_SET || m_defaultSeverity != SEVERITY_NOT_SET; } inline bool hasSeverityAction() const { return m_severity != SEVERITY_NOT_SET || m_defaultSeverity != SEVERITY_NOT_SET; }
@ -373,19 +376,19 @@ class RuleWithActions : public Rule {
inline void setSeverity(unsigned int severity) { m_severity = severity; } inline void setSeverity(unsigned int severity) { m_severity = severity; }
inline bool hasRevisionAction() const { return m_revision != ""; } inline bool hasRevisionAction() const { return m_revision != ""; }
inline std::string getRevision() const { return m_revision; }; inline const std::string getRevision() const { return m_revision; };
inline void setRevision(const std::string &revision) { m_revision.assign(revision); } inline void setRevision(const std::string &revision) { m_revision.assign(revision); }
inline bool hasVersionAction() const { return m_version != ""; } inline bool hasVersionAction() const { return m_version != ""; }
inline std::string getVersion() const { return m_version; }; inline const std::string getVersion() const { return m_version; };
inline void setVersion(const std::string &version) { m_version.assign(version); } inline void setVersion(const std::string &version) { m_version.assign(version); }
inline bool hasAccuracyAction() const { return m_accuracy != ACCURACY_NOT_SET || m_defaultAccuracy != ACCURACY_NOT_SET; } inline bool hasAccuracyAction() const { return m_accuracy != ACCURACY_NOT_SET || m_defaultAccuracy != ACCURACY_NOT_SET; }
inline int getAccuracy() const { return m_accuracy; } inline const int getAccuracy() const { return m_accuracy; }
inline void setAccuracy(unsigned int accuracy) { m_accuracy = accuracy; } inline void setAccuracy(unsigned int accuracy) { m_accuracy = accuracy; }
inline bool hasMaturityAction() const { return m_maturity != MATURITY_NOT_SET || m_defaultMaturity != MATURITY_NOT_SET; } inline bool hasMaturityAction() const { return m_maturity != MATURITY_NOT_SET || m_defaultMaturity != MATURITY_NOT_SET; }
inline int getMaturity() const { return m_maturity; } inline const int getMaturity() const { return m_maturity; }
inline void setDefaultActionMaturity(unsigned int maturity) { m_defaultMaturity = maturity; } inline void setDefaultActionMaturity(unsigned int maturity) { m_defaultMaturity = maturity; }
inline void setMaturity(unsigned int maturity) { m_maturity = maturity; } inline void setMaturity(unsigned int maturity) { m_maturity = maturity; }
@ -441,6 +444,14 @@ class RuleWithActions : public Rule {
return m_chainedRuleParent; return m_chainedRuleParent;
} }
XmlNSs getXmlNSs() const {
XmlNSs dst;
for (auto &a : m_XmlNSs) {
dst.push_back(a);
}
return dst;
}
XmlNSsPtr getXmlNSsPtr() const { XmlNSsPtr getXmlNSsPtr() const {
/** /**
* FIXME: this is not conteplating SecRuleUpdateActionBy* yet. * FIXME: this is not conteplating SecRuleUpdateActionBy* yet.

View File

@ -0,0 +1,15 @@
--- src/rule_with_actions.h
+++ src/rule_with_actions.h
@@ -520,11 +528,10 @@ class RuleWithActions : public Rule {
for (auto &a : m_XmlNSs) {
dst.push_back(a.get());
}
-
+
return dst;
}
-
virtual void dump(std::stringstream &out) const override {
out << "RuleWithActions" << std::endl;
}

View File

@ -40,10 +40,12 @@
#include "src/actions/set_var.h" #include "src/actions/set_var.h"
#include "src/actions/block.h" #include "src/actions/block.h"
#include "src/variables/variable.h" #include "src/variables/variable.h"
#include "src/variables/rule.h"
#include "src/rule_with_operator.h" #include "src/rule_with_operator.h"
#include "modsecurity/string_view.hpp" #include "modsecurity/string_view.hpp"
namespace modsecurity { namespace modsecurity {
using operators::Operator; using operators::Operator;
@ -60,7 +62,14 @@ RuleWithOperator::RuleWithOperator(Operator *op,
int lineNumber) int lineNumber)
: RuleWithActions(actions, transformations, std::move(fileName), lineNumber), : RuleWithActions(actions, transformations, std::move(fileName), lineNumber),
m_variables(std::unique_ptr<variables::Variables>(_variables)), m_variables(std::unique_ptr<variables::Variables>(_variables)),
m_operator(std::unique_ptr<Operator>(op)) { /* */ } m_operator(std::unique_ptr<Operator>(op)) {
for (auto &a : *m_variables.get()) {
variables::RuleVariable *vrule = dynamic_cast<variables::RuleVariable *>(a);
if (vrule != nullptr) {
vrule->populate(this);
}
}
}
@ -247,8 +256,7 @@ bool RuleWithOperator::evaluate(Transaction *trans) {
+ " against " \ + " against " \
+ variables + "."); + variables + ".");
} else { } else {
ms_dbg_a(trans, 4, "(Rule: " + std::to_string(getId() ms_dbg_a(trans, 4, "(Rule: " + std::to_string(getId()) \
) \
+ ") Executing operator \"" + getOperatorName() \ + ") Executing operator \"" + getOperatorName() \
+ " against " \ + " against " \
+ variables + "."); + variables + ".");
@ -262,7 +270,7 @@ bool RuleWithOperator::evaluate(Transaction *trans) {
if (!var) { if (!var) {
continue; continue;
} }
var->evaluate(trans, this, &e); var->evaluate(trans, &e);
for (const VariableValue *v : e) { for (const VariableValue *v : e) {
TransformationsResults transformationsResults; TransformationsResults transformationsResults;
const std::string &value = v->getValue(); const std::string &value = v->getValue();

View File

@ -51,7 +51,15 @@ class RuleWithOperator : public RuleWithActions {
RuleWithOperator(const RuleWithOperator &op) RuleWithOperator(const RuleWithOperator &op)
: RuleWithActions(op), : RuleWithActions(op),
m_variables(op.m_variables), m_variables(op.m_variables),
m_operator(op.m_operator) { }; m_operator(op.m_operator)
{
for (auto &a : *m_variables.get()) {
variables::RuleVariable *vrule = dynamic_cast<variables::RuleVariable *>(a);
if (vrule != nullptr) {
vrule->populate(this);
}
}
};
RuleWithOperator &operator=(const RuleWithOperator& r) { RuleWithOperator &operator=(const RuleWithOperator& r) {
RuleWithActions::operator = (r); RuleWithActions::operator = (r);

View File

@ -41,36 +41,30 @@ void RunTimeString::appendText(const std::string &text) {
void RunTimeString::appendVar( void RunTimeString::appendVar(
std::unique_ptr<modsecurity::variables::Variable> var) { std::unique_ptr<modsecurity::variables::Variable> var) {
std::unique_ptr<RunTimeElementHolder> r(new RunTimeElementHolder); std::unique_ptr<RunTimeElementHolder> r(new RunTimeElementHolder);
r->m_var = std::move(var); r->m_variable = std::move(var);
m_elements.push_back(std::move(r)); m_elements.push_back(std::move(r));
m_containsMacro = true; m_containsMacro = true;
} }
std::string RunTimeString::evaluate(Transaction *t) { std::string RunTimeString::evaluate(Transaction *transaction) {
return evaluate(t, NULL); std::string retString;
} // FIXME: Educated guess the size of retString based on the size of the elements.
for (auto &element : m_elements) {
if (element->m_string.size() > 0) {
std::string RunTimeString::evaluate(Transaction *t, Rule *r) { retString.append(element->m_string);
std::string s; } else if (element->m_variable != nullptr && transaction != nullptr) {
for (auto &z : m_elements) {
if (z->m_string.size() > 0) {
s.append(z->m_string);
} else if (z->m_var != NULL && t != NULL) {
std::vector<const VariableValue *> l; std::vector<const VariableValue *> l;
// FIXME: This cast should be removed. element->m_variable->evaluate(transaction, &l);
RuleWithOperator *rr = dynamic_cast<RuleWithOperator *>(r); if (!l.empty()) {
z->m_var->evaluate(t, rr, &l); retString.append(l[0]->getValue());
if (l.size() > 0) {
s.append(l[0]->getValue());
} }
for (auto &i : l) { for (auto &i : l) {
delete i; delete i;
} }
} }
} }
return s; return retString;
} }
} // namespace modsecurity } // namespace modsecurity

View File

@ -25,6 +25,7 @@
#include "modsecurity/modsecurity.h" #include "modsecurity/modsecurity.h"
#include "modsecurity/transaction.h" #include "modsecurity/transaction.h"
#include "src/variables/variable.h" #include "src/variables/variable.h"
#include "src/variables/rule_variable.h"
#ifndef SRC_RUN_TIME_STRING_H_ #ifndef SRC_RUN_TIME_STRING_H_
@ -34,29 +35,72 @@ namespace modsecurity {
class RunTimeElementHolder { class RunTimeElementHolder {
public: public:
RunTimeElementHolder() : RunTimeElementHolder()
m_string("") { : m_string(""),
m_var.reset(NULL); m_variable(nullptr)
} { };
std::unique_ptr<modsecurity::variables::Variable> m_var;
RunTimeElementHolder(const RunTimeElementHolder &other)
: m_string(other.m_string),
m_variable(other.m_variable) {
variables::RuleVariable *rv = dynamic_cast<variables::RuleVariable *>(m_variable.get());
if (rv != nullptr) {
auto nrv = rv->clone();
rv = dynamic_cast<variables::RuleVariable *>(nrv);
rv->populate(nullptr);
m_variable = std::unique_ptr<variables::Variable>(nrv);
}
};
/* protected: */
std::string m_string; std::string m_string;
std::shared_ptr<variables::Variable> m_variable;
}; };
class RunTimeString { class RunTimeString {
public: public:
RunTimeString() : RunTimeString()
m_containsMacro(false) { } : m_containsMacro(false),
m_elements()
{ };
RunTimeString(const RunTimeString &other)
: m_containsMacro(other.m_containsMacro),
m_elements()
{
for (auto &m : other.m_elements) {
m_elements.push_back(std::unique_ptr<RunTimeElementHolder>(new RunTimeElementHolder(*m.get())));
}
};
void appendText(const std::string &text); void appendText(const std::string &text);
void appendVar(std::unique_ptr<modsecurity::variables::Variable> var); void appendVar(std::unique_ptr<modsecurity::variables::Variable> var);
std::string evaluate(Transaction *t); std::string evaluate(Transaction *t);
std::string evaluate(Transaction *t, Rule *r);
std::string evaluate() { inline std::string evaluate() {
return evaluate(NULL); return evaluate(NULL);
} }
inline bool containsMacro() const { return m_containsMacro; }
bool m_containsMacro;
protected:
inline bool containsMacro() const { return m_containsMacro; }
void populate(RuleWithActions *rule) {
for (auto &a : m_elements) {
modsecurity::variables::RuleVariable *vrule = dynamic_cast<variables::RuleVariable *>(a->m_variable.get());
if (vrule != nullptr) {
vrule->populate(rule);
}
}
}
private:
bool m_containsMacro;
std::list<std::unique_ptr<RunTimeElementHolder>> m_elements; std::list<std::unique_ptr<RunTimeElementHolder>> m_elements;
}; };

View File

@ -344,7 +344,6 @@ int Transaction::processConnection(const char *client, int cPort,
ms_dbg(4, "Transaction context created."); ms_dbg(4, "Transaction context created.");
ms_dbg(4, "Starting phase CONNECTION. (SecRules 0)"); ms_dbg(4, "Starting phase CONNECTION. (SecRules 0)");
m_variableRemoteHost.set(*m_clientIpAddress.get(), m_variableOffset); m_variableRemoteHost.set(*m_clientIpAddress.get(), m_variableOffset);
m_variableUniqueID.set(*m_id.get(), m_variableOffset); m_variableUniqueID.set(*m_id.get(), m_variableOffset);
m_variableRemoteAddr.set(*m_clientIpAddress.get(), m_variableOffset); m_variableRemoteAddr.set(*m_clientIpAddress.get(), m_variableOffset);
@ -1495,7 +1494,7 @@ std::string Transaction::toOldAuditLogFormatIndex(const std::string &filename,
/** TODO: Check variable */ /** TODO: Check variable */
variables::RemoteUser *r = new variables::RemoteUser("REMOTE_USER"); variables::RemoteUser *r = new variables::RemoteUser("REMOTE_USER");
std::vector<const VariableValue *> l; std::vector<const VariableValue *> l;
r->evaluate(this, NULL, &l); r->evaluate(this, &l);
delete r; delete r;
ss << utils::string::dash_if_empty( ss << utils::string::dash_if_empty(

View File

@ -28,7 +28,6 @@ namespace modsecurity {
namespace variables { namespace variables {
void Duration::evaluate(Transaction *transaction, void Duration::evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
double e = utils::cpu_seconds() - transaction->m_creationTimeStamp; double e = utils::cpu_seconds() - transaction->m_creationTimeStamp;

View File

@ -35,7 +35,6 @@ class Duration : public Variable {
m_retName("DURATION") { } m_retName("DURATION") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override; std::vector<const VariableValue *> *l) override;
std::string m_retName; std::string m_retName;
}; };

View File

@ -33,7 +33,6 @@ namespace modsecurity {
namespace variables { namespace variables {
void Env::evaluate(Transaction *transaction, void Env::evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
for (char **current = environ; *current; current++) { for (char **current = environ; *current; current++) {
std::string env = std::string(*current); std::string env = std::string(*current);

View File

@ -34,7 +34,6 @@ class Env : public Variable {
: Variable(_name) { } : Variable(_name) { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override; std::vector<const VariableValue *> *l) override;
}; };

View File

@ -25,6 +25,7 @@
#include "src/variables/variable.h" #include "src/variables/variable.h"
#include "src/run_time_string.h" #include "src/run_time_string.h"
#include "src/variables/variable_with_runtime_string.h"
namespace modsecurity { namespace modsecurity {
@ -39,7 +40,6 @@ class Global_DictElement : public Variable {
m_dictElement("GLOBAL:" + dictElement) { } m_dictElement("GLOBAL:" + dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
t->m_collections.m_global_collection->resolveMultiMatches( t->m_collections.m_global_collection->resolveMultiMatches(
m_name, t->m_collections.m_global_collection_key, m_name, t->m_collections.m_global_collection_key,
@ -56,7 +56,6 @@ class Global_NoDictElement : public Variable {
: Variable("GLOBAL") { } : Variable("GLOBAL") { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
t->m_collections.m_global_collection->resolveMultiMatches("", t->m_collections.m_global_collection->resolveMultiMatches("",
t->m_collections.m_global_collection_key, t->m_collections.m_global_collection_key,
@ -72,7 +71,6 @@ class Global_DictElementRegexp : public VariableRegex {
m_dictElement(dictElement) { } m_dictElement(dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
t->m_collections.m_global_collection->resolveRegularExpression( t->m_collections.m_global_collection->resolveRegularExpression(
m_dictElement, m_dictElement,
@ -84,14 +82,16 @@ class Global_DictElementRegexp : public VariableRegex {
}; };
class Global_DynamicElement : public Variable { class Global_DynamicElement : public VariableWithRunTimeString {
public: public:
explicit Global_DynamicElement(std::unique_ptr<RunTimeString> dictElement) explicit Global_DynamicElement(std::unique_ptr<RunTimeString> dictElement)
: Variable("GLOBAL:dynamic"), : VariableWithRunTimeString(
m_string(std::move(dictElement)) { } "GLOBAL:dynamic",
std::move(dictElement)
)
{ };
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
std::string string = m_string->evaluate(t); std::string string = m_string->evaluate(t);
t->m_collections.m_global_collection->resolveMultiMatches( t->m_collections.m_global_collection->resolveMultiMatches(
@ -113,8 +113,6 @@ class Global_DynamicElement : public Variable {
t->m_rules->m_secWebAppId.m_value, t->m_rules->m_secWebAppId.m_value,
value); value);
} }
std::unique_ptr<RunTimeString> m_string;
}; };

View File

@ -27,7 +27,6 @@ namespace modsecurity {
namespace variables { namespace variables {
void HighestSeverity::evaluate(Transaction *transaction, void HighestSeverity::evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
transaction->m_variableHighestSeverityAction.assign( transaction->m_variableHighestSeverityAction.assign(
std::to_string(transaction->m_highestSeverityAction)); std::to_string(transaction->m_highestSeverityAction));

View File

@ -35,7 +35,6 @@ class HighestSeverity : public Variable {
{ } { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override; std::vector<const VariableValue *> *l) override;
}; };

View File

@ -25,6 +25,7 @@
#include "src/variables/variable.h" #include "src/variables/variable.h"
#include "src/run_time_string.h" #include "src/run_time_string.h"
#include "src/variables/variable_with_runtime_string.h"
namespace modsecurity { namespace modsecurity {
@ -39,7 +40,6 @@ class Ip_DictElement : public Variable {
m_dictElement("IP:" + dictElement) { } m_dictElement("IP:" + dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
t->m_collections.m_ip_collection->resolveMultiMatches( t->m_collections.m_ip_collection->resolveMultiMatches(
m_name, t->m_collections.m_ip_collection_key, m_name, t->m_collections.m_ip_collection_key,
@ -56,7 +56,6 @@ class Ip_NoDictElement : public Variable {
: Variable("IP") { } : Variable("IP") { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
t->m_collections.m_ip_collection->resolveMultiMatches("", t->m_collections.m_ip_collection->resolveMultiMatches("",
t->m_collections.m_ip_collection_key, t->m_collections.m_ip_collection_key,
@ -72,7 +71,6 @@ class Ip_DictElementRegexp : public VariableRegex {
m_dictElement(dictElement) { } m_dictElement(dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
t->m_collections.m_ip_collection->resolveRegularExpression( t->m_collections.m_ip_collection->resolveRegularExpression(
m_dictElement, t->m_collections.m_ip_collection_key, m_dictElement, t->m_collections.m_ip_collection_key,
@ -83,14 +81,16 @@ class Ip_DictElementRegexp : public VariableRegex {
}; };
class Ip_DynamicElement : public Variable { class Ip_DynamicElement : public VariableWithRunTimeString {
public: public:
explicit Ip_DynamicElement(std::unique_ptr<RunTimeString> dictElement) explicit Ip_DynamicElement(std::unique_ptr<RunTimeString> dictElement)
: Variable("IP:dynamic"), : VariableWithRunTimeString(
m_string(std::move(dictElement)) { } "IP:dynamic",
std::move(dictElement)
)
{ }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
std::string string = m_string->evaluate(t); std::string string = m_string->evaluate(t);
t->m_collections.m_ip_collection->resolveMultiMatches( t->m_collections.m_ip_collection->resolveMultiMatches(
@ -112,8 +112,6 @@ class Ip_DynamicElement : public Variable {
t->m_rules->m_secWebAppId.m_value, t->m_rules->m_secWebAppId.m_value,
value); value);
} }
std::unique_ptr<RunTimeString> m_string;
}; };

View File

@ -25,7 +25,6 @@ namespace modsecurity {
namespace variables { namespace variables {
void ModsecBuild::evaluate(Transaction *transaction, void ModsecBuild::evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
l->push_back(new VariableValue(&m_retName, &m_build)); l->push_back(new VariableValue(&m_retName, &m_build));

View File

@ -44,7 +44,6 @@ class ModsecBuild : public Variable {
} }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override; std::vector<const VariableValue *> *l) override;
std::string m_build; std::string m_build;

View File

@ -37,7 +37,6 @@ namespace variables {
void RemoteUser::evaluate(Transaction *transaction, void RemoteUser::evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
size_t pos; size_t pos;
std::string base64; std::string base64;

View File

@ -37,7 +37,6 @@ class RemoteUser : public Variable {
m_retName("REMOTE_USER") { } m_retName("REMOTE_USER") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override; std::vector<const VariableValue *> *l) override;
std::string m_retName; std::string m_retName;
}; };

View File

@ -25,6 +25,7 @@
#include "src/variables/variable.h" #include "src/variables/variable.h"
#include "src/run_time_string.h" #include "src/run_time_string.h"
#include "src/variables/variable_with_runtime_string.h"
namespace modsecurity { namespace modsecurity {
@ -39,7 +40,6 @@ class Resource_DictElement : public Variable {
m_dictElement("RESOURCE:" + dictElement) { } m_dictElement("RESOURCE:" + dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
t->m_collections.m_resource_collection->resolveMultiMatches( t->m_collections.m_resource_collection->resolveMultiMatches(
m_name, t->m_collections.m_resource_collection_key, m_name, t->m_collections.m_resource_collection_key,
@ -56,7 +56,6 @@ class Resource_NoDictElement : public Variable {
: Variable("RESOURCE") { } : Variable("RESOURCE") { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
t->m_collections.m_resource_collection->resolveMultiMatches(m_name, t->m_collections.m_resource_collection->resolveMultiMatches(m_name,
t->m_collections.m_resource_collection_key, t->m_collections.m_resource_collection_key,
@ -72,7 +71,6 @@ class Resource_DictElementRegexp : public VariableRegex {
m_dictElement(dictElement) { } m_dictElement(dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
t->m_collections.m_resource_collection->resolveRegularExpression( t->m_collections.m_resource_collection->resolveRegularExpression(
m_dictElement, t->m_collections.m_resource_collection_key, m_dictElement, t->m_collections.m_resource_collection_key,
@ -83,14 +81,16 @@ class Resource_DictElementRegexp : public VariableRegex {
}; };
class Resource_DynamicElement : public Variable { class Resource_DynamicElement : public VariableWithRunTimeString {
public: public:
explicit Resource_DynamicElement(std::unique_ptr<RunTimeString> dictElement) explicit Resource_DynamicElement(std::unique_ptr<RunTimeString> dictElement)
: Variable("RESOURCE:dynamic"), : VariableWithRunTimeString(
m_string(std::move(dictElement)) { } "RESOURCE:dynamic",
std::move(dictElement)
)
{ }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
std::string string = m_string->evaluate(t); std::string string = m_string->evaluate(t);
t->m_collections.m_resource_collection->resolveMultiMatches( t->m_collections.m_resource_collection->resolveMultiMatches(
@ -111,8 +111,6 @@ class Resource_DynamicElement : public Variable {
var, t->m_collections.m_resource_collection_key, var, t->m_collections.m_resource_collection_key,
t->m_rules->m_secWebAppId.m_value, value); t->m_rules->m_secWebAppId.m_value, value);
} }
std::unique_ptr<RunTimeString> m_string;
}; };

View File

@ -33,21 +33,32 @@ class Transaction;
namespace variables { namespace variables {
class Rule_DictElement : public VariableDictElement { \ class Rule_DictElement : public RuleVariable, public VariableDictElement {
public: public:
explicit Rule_DictElement(const std::string &dictElement) explicit Rule_DictElement(const std::string &dictElement)
: VariableDictElement(std::string("RULE"), dictElement) { } : RuleVariable(),
VariableDictElement(
std::string("RULE"),
dictElement
)
{ };
Rule_DictElement(const Rule_DictElement &r)
: RuleVariable(),
VariableDictElement(r)
{ };
virtual Variable *clone() override {
return new Rule_DictElement(*this);
};
static void id(Transaction *t, static void id(Transaction *t,
RuleWithActions *rule, const RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
RuleWithActions *r = rule;
if (!r || r->getId() == 0) {
return;
}
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
std::string *a = new std::string(std::to_string(r->getId())); std::string *a = new std::string(std::to_string(rule->getId()));
VariableValue *var = new VariableValue(&m_rule, &m_rule_id, VariableValue *var = new VariableValue(&m_rule, &m_rule_id,
a a
); );
@ -59,18 +70,14 @@ class Rule_DictElement : public VariableDictElement { \
} }
static void rev(Transaction *t, static void rev(Transaction *t,
RuleWithActions *rule, const RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
RuleWithActions *r = rule;
if (!r) { if (rule->hasRevisionAction()) {
return;
}
if (r->hasRevisionAction()) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
std::string *a = new std::string(r->getRevision()); std::string *a = new std::string(rule->getRevision());
VariableValue *var = new VariableValue(&m_rule, &m_rule_rev, VariableValue *var = new VariableValue(&m_rule, &m_rule_rev,
a a
); );
@ -84,17 +91,12 @@ class Rule_DictElement : public VariableDictElement { \
static void severity(Transaction *t, static void severity(Transaction *t,
RuleWithActions *rule, const RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
RuleWithActions *r = rule;
if (!r) { if (rule->hasSeverityAction()) {
return;
}
if (r->hasSeverityAction()) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
std::string *a = new std::string(std::to_string(r->getSeverity())); std::string *a = new std::string(std::to_string(rule->getSeverity()));
VariableValue *var = new VariableValue(&m_rule, &m_rule_severity, VariableValue *var = new VariableValue(&m_rule, &m_rule_severity,
a a
); );
@ -104,21 +106,16 @@ class Rule_DictElement : public VariableDictElement { \
var->addOrigin(std::move(origin)); var->addOrigin(std::move(origin));
l->push_back(var); l->push_back(var);
} }
} }
static void logData(Transaction *t, static void logData(Transaction *t,
RuleWithActions *rule, const RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
RuleWithActions *r = rule;
if (!r) { if (rule->hasLogDataAction()) {
return;
}
if (r->hasLogDataAction()) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
std::string *a = new std::string(r->getLogData(t)); std::string *a = new std::string(rule->getLogData(t));
VariableValue *var = new VariableValue(&m_rule, &m_rule_logdata, VariableValue *var = new VariableValue(&m_rule, &m_rule_logdata,
a a
); );
@ -131,17 +128,12 @@ class Rule_DictElement : public VariableDictElement { \
} }
static void msg(Transaction *t, static void msg(Transaction *t,
RuleWithActions *rule, const RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
RuleWithActions *r = rule;
if (!r) { if (rule->hasMessageAction()) {
return;
}
if (r->hasMessageAction()) {
std::unique_ptr<VariableOrigin> origin(new VariableOrigin()); std::unique_ptr<VariableOrigin> origin(new VariableOrigin());
std::string *a = new std::string(r->getMessage(t)); std::string *a = new std::string(rule->getMessage(t));
VariableValue *var = new VariableValue(&m_rule, &m_rule_msg, VariableValue *var = new VariableValue(&m_rule, &m_rule_msg,
a a
); );
@ -154,26 +146,26 @@ class Rule_DictElement : public VariableDictElement { \
} }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
if (m_dictElement == "id") { if (m_dictElement == "id") {
id(t, rule, l); id(t, getRule(), l);
return; return;
} }
if (m_dictElement == "rev") { if (m_dictElement == "rev") {
rev(t, rule, l); rev(t, getRule(), l);
return; return;
} }
if (m_dictElement == "severity") { if (m_dictElement == "severity") {
severity(t, rule, l); severity(t, getRule(), l);
return; return;
} }
if (m_dictElement == "logdata") { if (m_dictElement == "logdata") {
logData(t, rule, l); logData(t, getRule(), l);
return; return;
} }
if (m_dictElement == "msg") { if (m_dictElement == "msg") {
msg(t, rule, l); msg(t, getRule(), l);
return; return;
} }
} }
@ -187,52 +179,77 @@ class Rule_DictElement : public VariableDictElement { \
}; };
class Rule_DictElementRegexp : public VariableRegex { class Rule_DictElementRegexp : public RuleVariable, public VariableRegex {
public: public:
explicit Rule_DictElementRegexp(const std::string &regex) explicit Rule_DictElementRegexp(const std::string &regex)
: VariableRegex("RULE", regex) { } : RuleVariable(),
VariableRegex("RULE", regex)
{ };
Rule_DictElementRegexp(const Rule_DictElementRegexp &r)
: RuleVariable(),
VariableRegex(r)
{ };
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
if (Utils::regex_search("id", m_r) > 0) { if (Utils::regex_search("id", m_r) > 0) {
Rule_DictElement::id(t, rule, l); Rule_DictElement::id(t, getRule(), l);
return; return;
} }
if (Utils::regex_search("rev", m_r) > 0) { if (Utils::regex_search("rev", m_r) > 0) {
Rule_DictElement::rev(t, rule, l); Rule_DictElement::rev(t, getRule(), l);
return; return;
} }
if (Utils::regex_search("severity", m_r) > 0) { if (Utils::regex_search("severity", m_r) > 0) {
Rule_DictElement::severity(t, rule, l); Rule_DictElement::severity(t, getRule(), l);
return; return;
} }
if (Utils::regex_search("logdata", m_r) > 0) { if (Utils::regex_search("logdata", m_r) > 0) {
Rule_DictElement::logData(t, rule, l); Rule_DictElement::logData(t, getRule(), l);
return; return;
} }
if (Utils::regex_search("msg", m_r) > 0) { if (Utils::regex_search("msg", m_r) > 0) {
Rule_DictElement::msg(t, rule, l); Rule_DictElement::msg(t, getRule(), l);
return; return;
} }
} }
virtual Variable *clone() override {
return new Rule_DictElementRegexp(*this);
};
}; };
class Rule_NoDictElement : public Variable { class Rule_NoDictElement : public RuleVariable, public Variable {
public: public:
explicit Rule_NoDictElement() Rule_NoDictElement()
: Variable("RULE") { } : RuleVariable(),
Variable("RULE")
{ };
explicit Rule_NoDictElement(const Rule_DictElementRegexp &r)
: RuleVariable(),
Variable(r)
{ };
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
Rule_DictElement::id(t, rule, l); Rule_DictElement::id(t, getRule(), l);
Rule_DictElement::rev(t, rule, l); Rule_DictElement::rev(t, getRule(), l);
Rule_DictElement::severity(t, rule, l); Rule_DictElement::severity(t, getRule(), l);
Rule_DictElement::logData(t, rule, l); Rule_DictElement::logData(t, getRule(), l);
Rule_DictElement::msg(t, rule, l); Rule_DictElement::msg(t, getRule(), l);
} }
virtual Variable *clone() override {
return new Rule_NoDictElement(*this);
};
}; };
// DEFINE_VARIABLE_DICT(Rule, RULE, m_variableRule) // DEFINE_VARIABLE_DICT(Rule, RULE, m_variableRule)

View File

@ -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 <string>
#include <vector>
#include <list>
#ifndef SRC_VARIABLES_RULE_VARIABLE_H_
#define SRC_VARIABLES_RULE_VARIABLE_H_
#include "src/rule_with_actions.h"
namespace modsecurity {
class Transaction;
namespace variables {
class RuleVariable {
public:
RuleVariable()
: m_rule(nullptr)
{ };
RuleVariable(const RuleVariable &a)
: m_rule(a.m_rule)
{ };
void populate(const RuleWithActions *rule) {
m_rule = rule;
}
const RuleWithActions *getRule() const noexcept {
return m_rule;
}
virtual Variable* clone() = 0;
private:
const RuleWithActions *m_rule;
};
} // namespace variables
} // namespace modsecurity
#endif // SRC_VARIABLES_RULE_VARIABLE_H_

View File

@ -39,7 +39,6 @@ class Session_DictElement : public Variable {
m_dictElement("SESSION:" + dictElement) { } m_dictElement("SESSION:" + dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
t->m_collections.m_session_collection->resolveMultiMatches( t->m_collections.m_session_collection->resolveMultiMatches(
m_name, t->m_collections.m_session_collection_key, m_name, t->m_collections.m_session_collection_key,
@ -56,7 +55,6 @@ class Session_NoDictElement : public Variable {
: Variable("SESSION") { } : Variable("SESSION") { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
t->m_collections.m_session_collection->resolveMultiMatches("", t->m_collections.m_session_collection->resolveMultiMatches("",
t->m_collections.m_session_collection_key, t->m_collections.m_session_collection_key,
@ -72,7 +70,6 @@ class Session_DictElementRegexp : public VariableRegex {
m_dictElement(dictElement) { } m_dictElement(dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
t->m_collections.m_session_collection->resolveRegularExpression( t->m_collections.m_session_collection->resolveRegularExpression(
m_dictElement, t->m_collections.m_session_collection_key, m_dictElement, t->m_collections.m_session_collection_key,
@ -83,14 +80,16 @@ class Session_DictElementRegexp : public VariableRegex {
}; };
class Session_DynamicElement : public Variable { class Session_DynamicElement : public VariableWithRunTimeString {
public: public:
explicit Session_DynamicElement(std::unique_ptr<RunTimeString> dictElement) explicit Session_DynamicElement(std::unique_ptr<RunTimeString> dictElement)
: Variable("SESSION:dynamic"), : VariableWithRunTimeString(
m_string(std::move(dictElement)) { } "SESSION:dynamic",
std::move(dictElement)
)
{ }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
std::string string = m_string->evaluate(t); std::string string = m_string->evaluate(t);
t->m_collections.m_session_collection->resolveMultiMatches( t->m_collections.m_session_collection->resolveMultiMatches(
@ -112,8 +111,6 @@ class Session_DynamicElement : public Variable {
t->m_rules->m_secWebAppId.m_value, t->m_rules->m_secWebAppId.m_value,
value); value);
} }
std::unique_ptr<RunTimeString> m_string;
}; };

View File

@ -34,7 +34,6 @@ namespace modsecurity {
namespace variables { namespace variables {
void Time::evaluate(Transaction *transaction, void Time::evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
char tstr[200]; char tstr[200];

View File

@ -36,7 +36,6 @@ class Time : public Variable {
m_retName("TIME") { } m_retName("TIME") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override; std::vector<const VariableValue *> *l) override;
std::string m_retName; std::string m_retName;
}; };

View File

@ -34,7 +34,6 @@ namespace modsecurity {
namespace variables { namespace variables {
void TimeDay::evaluate(Transaction *transaction, void TimeDay::evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
char tstr[200]; char tstr[200];
struct tm timeinfo; struct tm timeinfo;

View File

@ -35,7 +35,6 @@ class TimeDay : public Variable {
m_retName("TIME_DAY") { } m_retName("TIME_DAY") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override; std::vector<const VariableValue *> *l) override;
std::string m_retName; std::string m_retName;
}; };

View File

@ -34,7 +34,6 @@ namespace modsecurity {
namespace variables { namespace variables {
void TimeEpoch::evaluate(Transaction *transaction, void TimeEpoch::evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
transaction->m_variableTimeEpoch.assign( transaction->m_variableTimeEpoch.assign(
std::to_string(std::time(nullptr))); std::to_string(std::time(nullptr)));

View File

@ -35,7 +35,6 @@ class TimeEpoch : public Variable {
m_retName("TIME_EPOCH") { } m_retName("TIME_EPOCH") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override; std::vector<const VariableValue *> *l) override;
std::string m_retName; std::string m_retName;
}; };

View File

@ -34,7 +34,6 @@ namespace modsecurity {
namespace variables { namespace variables {
void TimeHour::evaluate(Transaction *transaction, void TimeHour::evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
char tstr[200]; char tstr[200];
struct tm timeinfo; struct tm timeinfo;

View File

@ -35,7 +35,6 @@ class TimeHour : public Variable {
m_retName("TIME_HOUR") { } m_retName("TIME_HOUR") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override; std::vector<const VariableValue *> *l) override;
std::string m_retName; std::string m_retName;
}; };

View File

@ -34,7 +34,6 @@ namespace modsecurity {
namespace variables { namespace variables {
void TimeMin::evaluate(Transaction *transaction, void TimeMin::evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
char tstr[200]; char tstr[200];
struct tm timeinfo; struct tm timeinfo;

View File

@ -35,7 +35,6 @@ class TimeMin : public Variable {
m_retName("TIME_MIN") { } m_retName("TIME_MIN") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override; std::vector<const VariableValue *> *l) override;
std::string m_retName; std::string m_retName;
}; };

View File

@ -34,7 +34,6 @@ namespace modsecurity {
namespace variables { namespace variables {
void TimeMon::evaluate(Transaction *transaction, void TimeMon::evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
char tstr[200]; char tstr[200];
struct tm timeinfo; struct tm timeinfo;

View File

@ -35,7 +35,6 @@ class TimeMon : public Variable {
m_retName("TIME_MON") { } m_retName("TIME_MON") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override; std::vector<const VariableValue *> *l) override;
std::string m_retName; std::string m_retName;
}; };

View File

@ -34,7 +34,6 @@ namespace modsecurity {
namespace variables { namespace variables {
void TimeSec::evaluate(Transaction *transaction, void TimeSec::evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
char tstr[200]; char tstr[200];
struct tm timeinfo; struct tm timeinfo;

View File

@ -35,7 +35,6 @@ class TimeSec : public Variable {
m_retName("TIME_SEC") { } m_retName("TIME_SEC") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override; std::vector<const VariableValue *> *l) override;
std::string m_retName; std::string m_retName;
}; };

View File

@ -34,7 +34,6 @@ namespace modsecurity {
namespace variables { namespace variables {
void TimeWDay::evaluate(Transaction *transaction, void TimeWDay::evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
char tstr[200]; char tstr[200];
struct tm timeinfo; struct tm timeinfo;

View File

@ -35,7 +35,6 @@ class TimeWDay : public Variable {
m_retName("TIME_WDAY") { } m_retName("TIME_WDAY") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override; std::vector<const VariableValue *> *l) override;
std::string m_retName; std::string m_retName;
}; };

View File

@ -34,7 +34,6 @@ namespace modsecurity {
namespace variables { namespace variables {
void TimeYear::evaluate(Transaction *transaction, void TimeYear::evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
char tstr[200]; char tstr[200];
struct tm timeinfo; struct tm timeinfo;

View File

@ -35,7 +35,6 @@ class TimeYear : public Variable {
m_retName("TIME_YEAR") { } m_retName("TIME_YEAR") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override; std::vector<const VariableValue *> *l) override;
std::string m_retName; std::string m_retName;
}; };

View File

@ -25,6 +25,7 @@
#include "src/variables/variable.h" #include "src/variables/variable.h"
#include "src/run_time_string.h" #include "src/run_time_string.h"
#include "src/variables/variable_with_runtime_string.h"
namespace modsecurity { namespace modsecurity {
@ -39,7 +40,6 @@ class Tx_DictElement : public Variable {
m_dictElement("TX:" + dictElement) { } m_dictElement("TX:" + dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
t->m_collections.m_tx_collection->resolveMultiMatches( t->m_collections.m_tx_collection->resolveMultiMatches(
m_name, l, m_keyExclusion); m_name, l, m_keyExclusion);
@ -55,7 +55,6 @@ class Tx_NoDictElement : public Variable {
: Variable("TX") { } : Variable("TX") { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
t->m_collections.m_tx_collection->resolveMultiMatches("", l, t->m_collections.m_tx_collection->resolveMultiMatches("", l,
m_keyExclusion); m_keyExclusion);
@ -70,7 +69,6 @@ class Tx_DictElementRegexp : public VariableRegex {
m_dictElement(dictElement) { } m_dictElement(dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
t->m_collections.m_tx_collection->resolveRegularExpression( t->m_collections.m_tx_collection->resolveRegularExpression(
m_dictElement, l, m_keyExclusion); m_dictElement, l, m_keyExclusion);
@ -80,14 +78,16 @@ class Tx_DictElementRegexp : public VariableRegex {
}; };
class Tx_DynamicElement : public Variable { class Tx_DynamicElement : public VariableWithRunTimeString {
public: public:
explicit Tx_DynamicElement(std::unique_ptr<RunTimeString> dictElement) explicit Tx_DynamicElement(std::unique_ptr<RunTimeString> dictElement)
: Variable("TX:dynamic"), : VariableWithRunTimeString(
m_string(std::move(dictElement)) { } "TX:dynamic",
std::move(dictElement)
)
{ }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
std::string string = m_string->evaluate(t); std::string string = m_string->evaluate(t);
t->m_collections.m_tx_collection->resolveMultiMatches(string, l, t->m_collections.m_tx_collection->resolveMultiMatches(string, l,
@ -102,8 +102,6 @@ class Tx_DynamicElement : public Variable {
std::string value) { std::string value) {
t->m_collections.m_tx_collection->storeOrUpdateFirst(var, value); t->m_collections.m_tx_collection->storeOrUpdateFirst(var, value);
} }
std::unique_ptr<RunTimeString> m_string;
}; };

View File

@ -25,6 +25,7 @@
#include "src/variables/variable.h" #include "src/variables/variable.h"
#include "src/run_time_string.h" #include "src/run_time_string.h"
#include "src/variables/variable_with_runtime_string.h"
namespace modsecurity { namespace modsecurity {
@ -39,7 +40,6 @@ class User_DictElement : public Variable {
m_dictElement("USER:" + dictElement) { } m_dictElement("USER:" + dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
t->m_collections.m_user_collection->resolveMultiMatches( t->m_collections.m_user_collection->resolveMultiMatches(
m_name, t->m_collections.m_user_collection_key, m_name, t->m_collections.m_user_collection_key,
@ -56,7 +56,6 @@ class User_NoDictElement : public Variable {
: Variable("USER") { } : Variable("USER") { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
t->m_collections.m_user_collection->resolveMultiMatches(m_name, t->m_collections.m_user_collection->resolveMultiMatches(m_name,
t->m_collections.m_user_collection_key, t->m_collections.m_user_collection_key,
@ -72,7 +71,6 @@ class User_DictElementRegexp : public VariableRegex {
m_dictElement(dictElement) { } m_dictElement(dictElement) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
t->m_collections.m_user_collection->resolveRegularExpression( t->m_collections.m_user_collection->resolveRegularExpression(
m_dictElement, t->m_collections.m_user_collection_key, m_dictElement, t->m_collections.m_user_collection_key,
@ -83,14 +81,16 @@ class User_DictElementRegexp : public VariableRegex {
}; };
class User_DynamicElement : public Variable { class User_DynamicElement : public VariableWithRunTimeString {
public: public:
explicit User_DynamicElement(std::unique_ptr<RunTimeString> dictElement) explicit User_DynamicElement(std::unique_ptr<RunTimeString> dictElement)
: Variable("USER:dynamic"), : VariableWithRunTimeString(
m_string(std::move(dictElement)) { } "USER:dynamic",
std::move(dictElement)
)
{ }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
std::string string = m_string->evaluate(t); std::string string = m_string->evaluate(t);
t->m_collections.m_user_collection->resolveMultiMatches( t->m_collections.m_user_collection->resolveMultiMatches(
@ -112,8 +112,6 @@ class User_DynamicElement : public Variable {
t->m_rules->m_secWebAppId.m_value, t->m_rules->m_secWebAppId.m_value,
value); value);
} }
std::unique_ptr<RunTimeString> m_string;
}; };

View File

@ -23,7 +23,6 @@
#include "modsecurity/rules_set.h" #include "modsecurity/rules_set.h"
#include "modsecurity/transaction.h" #include "modsecurity/transaction.h"
#include "modsecurity/rule.h"
#include "src/utils/string.h" #include "src/utils/string.h"
#include "src/utils/regex.h" #include "src/utils/regex.h"
@ -49,7 +48,6 @@ class n ## _DictElementRegexp : public VariableRegex { \
: VariableRegex(#N, regex) { } \ : VariableRegex(#N, regex) { } \
\ \
void evaluate(Transaction *transaction, \ void evaluate(Transaction *transaction, \
RuleWithActions *rule, \
std::vector<const VariableValue *> *l) override { \ std::vector<const VariableValue *> *l) override { \
transaction-> e .resolveRegularExpression(&m_r, l, \ transaction-> e .resolveRegularExpression(&m_r, l, \
m_keyExclusion); \ m_keyExclusion); \
@ -64,7 +62,6 @@ class n ## _DictElement : public VariableDictElement { \
: VariableDictElement(#N, dictElement) { } \ : VariableDictElement(#N, dictElement) { } \
\ \
void evaluate(Transaction *transaction, \ void evaluate(Transaction *transaction, \
RuleWithActions *rule, \
std::vector<const VariableValue *> *l) override { \ std::vector<const VariableValue *> *l) override { \
transaction-> e .resolve(m_dictElement, l); \ transaction-> e .resolve(m_dictElement, l); \
} \ } \
@ -78,7 +75,6 @@ class n ## _NoDictElement : public Variable { \
: Variable(#N) { } \ : Variable(#N) { } \
\ \
void evaluate(Transaction *transaction, \ void evaluate(Transaction *transaction, \
RuleWithActions *rule, \
std::vector<const VariableValue *> *l) override { \ std::vector<const VariableValue *> *l) override { \
transaction-> e .resolve(l, m_keyExclusion); \ transaction-> e .resolve(l, m_keyExclusion); \
} \ } \
@ -92,13 +88,14 @@ class n : public Variable { \
: Variable(#N) { } \ : Variable(#N) { } \
\ \
void evaluate(Transaction *transaction, \ void evaluate(Transaction *transaction, \
RuleWithActions *rule, \
std::vector<const VariableValue *> *l) override { \ std::vector<const VariableValue *> *l) override { \
transaction-> e .evaluate(l); \ transaction-> e .evaluate(l); \
} \ } \
}; };
// FIXME: Copy methods for variables modificators needs to be done.
namespace modsecurity { namespace modsecurity {
class Transaction; class Transaction;
@ -151,8 +148,19 @@ class KeyExclusionString : public KeyExclusion {
class KeyExclusions : public std::deque<std::unique_ptr<KeyExclusion>> { class KeyExclusions : public std::deque<std::unique_ptr<KeyExclusion>> {
public: public:
KeyExclusions() {
} KeyExclusions()
: std::deque<std::unique_ptr<KeyExclusion>>()
{ };
KeyExclusions(const KeyExclusions &k)
: std::deque<std::unique_ptr<KeyExclusion>>()
{
//for (auto &a : k) {
//}
};
bool toOmit(std::string a) { bool toOmit(std::string a) {
for (auto &z : *this) { for (auto &z : *this) {
@ -545,12 +553,20 @@ class VariableMonkeyResolution {
class Variable : public VariableMonkeyResolution { class Variable : public VariableMonkeyResolution {
public: public:
explicit Variable(const std::string &name); explicit Variable(const std::string &name);
explicit Variable(Variable *_name); explicit Variable(Variable *_name);
Variable(const Variable &v)
: m_name(v.m_name),
m_collectionName(v.m_collectionName),
m_fullName(v.m_fullName),
m_keyExclusion(v.m_keyExclusion)
{ };
virtual ~Variable() { } virtual ~Variable() { }
virtual void evaluate(Transaction *t, virtual void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) = 0; std::vector<const VariableValue *> *l) = 0;
@ -586,7 +602,14 @@ class Variable : public VariableMonkeyResolution {
class VariableDictElement : public Variable { class VariableDictElement : public Variable {
public: public:
VariableDictElement(const std::string &name, const std::string &dict_element) VariableDictElement(const std::string &name, const std::string &dict_element)
: m_dictElement(dict_element), Variable(name + ":" + dict_element) { } : m_dictElement(dict_element), Variable(name + ":" + dict_element)
{ };
VariableDictElement(const VariableDictElement &v)
: m_dictElement(v.m_dictElement),
Variable(v)
{ };
std::string m_dictElement; std::string m_dictElement;
}; };
@ -597,7 +620,15 @@ class VariableRegex : public Variable {
VariableRegex(const std::string &name, const std::string &regex) VariableRegex(const std::string &name, const std::string &regex)
: m_r(regex), : m_r(regex),
m_regex(regex), m_regex(regex),
Variable(name + ":" + "regex(" + regex + ")") { } Variable(name + ":" + "regex(" + regex + ")")
{ }
VariableRegex(const VariableRegex &v)
: m_r(v.m_regex),
m_regex(v.m_regex),
Variable(v)
{ };
Utils::Regex m_r; Utils::Regex m_r;
// FIXME: no need for that. // FIXME: no need for that.
@ -644,9 +675,8 @@ class VariableModificatorExclusion : public Variable {
m_base(std::move(var)) { } m_base(std::move(var)) { }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
m_base->evaluate(t, rule, l); m_base->evaluate(t, l);
} }
std::unique_ptr<Variable> m_base; std::unique_ptr<Variable> m_base;
@ -662,13 +692,12 @@ class VariableModificatorCount : public Variable {
} }
void evaluate(Transaction *t, void evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
std::vector<const VariableValue *> reslIn; std::vector<const VariableValue *> reslIn;
VariableValue *val = NULL; VariableValue *val = NULL;
int count = 0; int count = 0;
m_base->evaluate(t, rule, &reslIn); m_base->evaluate(t, &reslIn);
for (const VariableValue *a : reslIn) { for (const VariableValue *a : reslIn) {
count++; count++;

View File

@ -0,0 +1,61 @@
/*
* 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 "src/variables/variable.h"
#include "src/run_time_string.h"
#ifndef SRC_VARIABLES_VARIABLE_WITH_RUN_TIME_STRING_H_
#define SRC_VARIABLES_VARIABLE_WITH_RUN_TIME_STRING_H_
namespace modsecurity {
namespace variables {
class VariableWithRunTimeString : public Variable {
public:
VariableWithRunTimeString(const std::string &name, std::unique_ptr<RunTimeString> string)
: Variable(name),
m_string(std::move(string))
{ };
VariableWithRunTimeString(const VariableWithRunTimeString &v)
: Variable(v),
m_string(std::unique_ptr<RunTimeString>(new RunTimeString(*v.m_string.get())))
{ };
VariableWithRunTimeString& operator=(const VariableWithRunTimeString& v)
{
m_string = std::unique_ptr<RunTimeString>(new RunTimeString(*v.m_string.get()));
return *this;
}
virtual void populate(RuleWithActions *rule) {
if (m_string) {
m_string->populate(rule);
}
}
std::string evaluateRunTimeString(Transaction *t) {
return m_string->evaluate(t);
}
protected:
std::unique_ptr<RunTimeString> m_string;
};
} // namespace variables
} // namespace modsecurity
#endif // SRC_VARIABLES_VARIABLE_WITH_RUN_TIME_STRING_H_

View File

@ -36,7 +36,6 @@ class WebAppId : public Variable {
: Variable("WEBAPPID") { } : Variable("WEBAPPID") { }
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
const std::string rname = transaction->m_rules->m_secWebAppId.m_value; const std::string rname = transaction->m_rules->m_secWebAppId.m_value;
l->push_back(new VariableValue(&m_name, &rname)); l->push_back(new VariableValue(&m_name, &rname));

View File

@ -49,13 +49,11 @@ namespace modsecurity {
namespace variables { namespace variables {
#ifndef WITH_LIBXML2 #ifndef WITH_LIBXML2
void XML::evaluate(Transaction *t, void XML_WithNSPath::evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) { } std::vector<const VariableValue *> *l) { }
#else #else
void XML::evaluate(Transaction *t, void XML_WithNSPath::evaluate(Transaction *t,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) { std::vector<const VariableValue *> *l) {
xmlXPathContextPtr xpathCtx; xmlXPathContextPtr xpathCtx;
xmlXPathObjectPtr xpathObj; xmlXPathObjectPtr xpathObj;
@ -88,20 +86,20 @@ void XML::evaluate(Transaction *t,
return; return;
} }
if (rule == NULL) { if (getRule() == NULL) {
ms_dbg_a(t, 2, "XML: Can't look for xmlns, internal error."); ms_dbg_a(t, 2, "XML: Can't look for xmlns, internal error.");
} else { } else {
std::vector<actions::XmlNS *> acts = rule->getXmlNSsPtr(); XmlNSsPtr acts = getRule()->getXmlNSsPtr();
for (auto &z : acts) { for (auto &z : acts) {
if (xmlXPathRegisterNs(xpathCtx, (const xmlChar*)z->m_scope.c_str(), if (xmlXPathRegisterNs(xpathCtx, (const xmlChar*)z->getScope().c_str(),
(const xmlChar*)z->m_href.c_str()) != 0) { (const xmlChar*)z->getHref().c_str()) != 0) {
ms_dbg_a(t, 1, "Failed to register XML namespace href \"" + \ ms_dbg_a(t, 1, "Failed to register XML namespace href \"" + \
z->m_href + "\" prefix \"" + z->m_scope + "\"."); z->getHref() + "\" prefix \"" + z->getScope() + "\".");
return; return;
} }
ms_dbg_a(t, 4, "Registered XML namespace href \"" + z->m_href + \ ms_dbg_a(t, 4, "Registered XML namespace href \"" + z->getHref() + \
"\" prefix \"" + z->m_scope + "\""); "\" prefix \"" + z->getScope() + "\"");
} }
} }

View File

@ -24,43 +24,63 @@
#include "src/variables/variable.h" #include "src/variables/variable.h"
#include "src/variables/xml.h" #include "src/variables/xml.h"
#include "src/variables/rule_variable.h"
namespace modsecurity { namespace modsecurity {
class Transaction; class Transaction;
namespace variables { namespace variables {
/* Invocation without an XPath expression makes sense /* Invocation without an XPath expression makes sense
* with functions that manipulate the document tree. * with functions that manipulate the document tree.
*/ */
class XML_NoDictElement : public Variable { class XML_WithoutNSPath : public RuleVariable, public Variable {
public: public:
XML_NoDictElement() XML_WithoutNSPath()
: Variable("XML"), : RuleVariable(),
Variable("XML"),
m_plain("[XML document tree]"), m_plain("[XML document tree]"),
m_var(&m_name, &m_plain) { m_var(&m_name, &m_plain)
} { };
XML_WithoutNSPath(const XML_WithoutNSPath &r)
: RuleVariable(r),
Variable(r),
m_plain(r.m_plain),
m_var(r.m_var)
{ };
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override { std::vector<const VariableValue *> *l) override {
l->push_back(new VariableValue(&m_var)); l->push_back(new VariableValue(&m_var));
} }
virtual variables::Variable *clone() override {
return new XML_WithoutNSPath(*this);
};
std::string m_plain; std::string m_plain;
VariableValue m_var; VariableValue m_var;
}; };
class XML_WithNSPath : public RuleVariable, public VariableDictElement {
class XML : public Variable {
public: public:
explicit XML(const std::string &_name) explicit XML_WithNSPath(const std::string &nsPath)
: Variable(_name) { } : RuleVariable(),
VariableDictElement("XML", nsPath)
{ };
XML_WithNSPath(const XML_WithNSPath &r)
: RuleVariable(),
VariableDictElement(r)
{ };
void evaluate(Transaction *transaction, void evaluate(Transaction *transaction,
RuleWithActions *rule,
std::vector<const VariableValue *> *l) override; std::vector<const VariableValue *> *l) override;
virtual Variable *clone() override {
return new XML_WithNSPath(*this);
};
}; };