diff --git a/headers/modsecurity/collection/variable.h b/headers/modsecurity/collection/variable.h index 10454450..91ddc536 100644 --- a/headers/modsecurity/collection/variable.h +++ b/headers/modsecurity/collection/variable.h @@ -33,11 +33,20 @@ namespace collection { class Variable { public: - Variable(const std::string& key, const std::string& value) : + Variable(const std::string *key, const std::string *value) : m_key(key), - m_value(value) { } - std::string m_key; - std::string m_value; + m_value(value), + m_dynamic_value(false) { } + + ~Variable() { + if (m_dynamic_value) { + delete m_value; + } + } + + const std::string *m_key; + const std::string *m_value; + bool m_dynamic_value; }; } // namespace collection diff --git a/headers/modsecurity/rule.h b/headers/modsecurity/rule.h index a2a2c0f3..6e5f5091 100644 --- a/headers/modsecurity/rule.h +++ b/headers/modsecurity/rule.h @@ -56,7 +56,7 @@ class Rule { void executeActionsAfterFullMatch(Transaction *trasn, bool containsDisruptive, RuleMessage *ruleMessage); std::vector executeSecDefaultActionTransofrmations( - Transaction *trasn, std::string &value, bool multiMatch); + Transaction *trasn, const std::string &value, bool multiMatch); bool executeOperatorAt(Transaction *trasn, std::string key, std::string value); void executeActionsIndependentOfChainedRuleResult(Transaction *trasn, diff --git a/headers/modsecurity/transaction.h b/headers/modsecurity/transaction.h index 63b23683..f25ee16f 100644 --- a/headers/modsecurity/transaction.h +++ b/headers/modsecurity/transaction.h @@ -361,6 +361,19 @@ class Transaction { RequestBodyProcessor::XML *m_xml; RequestBodyProcessor::JSON *m_json; + std::string m_variableDuration; + std::map m_variableEnvs; + std::string m_variableHighestSeverityAction; + std::string m_variableRemoteUser; + std::string m_variableTime; + std::string m_variableTimeDay; + std::string m_variableTimeEpoch; + std::string m_variableTimeHour; + std::string m_variableTimeMin; + std::string m_variableTimeSec; + std::string m_variableTimeWDay; + std::string m_variableTimeYear; + private: std::string *m_ARGScombinedSizeStr; std::string *m_namesArgs; diff --git a/src/collection/backend/in_memory-per_process.cc b/src/collection/backend/in_memory-per_process.cc index e1a8054d..9b302385 100644 --- a/src/collection/backend/in_memory-per_process.cc +++ b/src/collection/backend/in_memory-per_process.cc @@ -77,7 +77,7 @@ void InMemoryPerProcess::resolveSingleMatch(const std::string& var, auto range = this->equal_range(var); for (auto it = range.first; it != range.second; ++it) { - l->push_back(new Variable(var, it->second)); + l->push_back(new Variable(&it->first, &it->second)); } } @@ -90,7 +90,7 @@ void InMemoryPerProcess::resolveMultiMatches(const std::string& var, auto range = this->equal_range(var); for (auto it = range.first; it != range.second; ++it) { - l->insert(l->begin(), new Variable(var, it->second)); + l->insert(l->begin(), new Variable(&var, &it->second)); } for (const auto& x : *this) { @@ -113,7 +113,7 @@ void InMemoryPerProcess::resolveMultiMatches(const std::string& var, continue; } - l->insert(l->begin(), new Variable(x.first, x.second)); + l->insert(l->begin(), new Variable(&x.first, &x.second)); } } @@ -150,7 +150,7 @@ void InMemoryPerProcess::resolveRegularExpression(const std::string& var, continue; } - l->insert(l->begin(), new Variable(x.first, x.second)); + l->insert(l->begin(), new Variable(&x.first, &x.second)); } } diff --git a/src/rule.cc b/src/rule.cc index 0d863906..440c22a7 100644 --- a/src/rule.cc +++ b/src/rule.cc @@ -282,10 +282,11 @@ bool Rule::executeOperatorAt(Transaction *trasn, std::string key, // FIXME: this should be a list instead of a vector, keeping the but // of v2 alive. std::vector Rule::executeSecDefaultActionTransofrmations( - Transaction *trasn, std::string &value, bool multiMatch) { + Transaction *trasn, const std::string &value2, bool multiMatch) { int none = 0; int transformations = 0; std::vector ret; + std::string value = std::string(value2); if (multiMatch == true) { ret.push_back(value); @@ -305,7 +306,7 @@ std::vector Rule::executeSecDefaultActionTransofrmations( for (Action *a : trasn->m_rules->defaultActions[this->phase]) { if (a->action_kind \ == actions::Action::RunTimeBeforeMatchAttemptKind) { - std::string oldValue = value; + std::string oldValue = std::string(value); if (multiMatch) { oldValue = ret.back(); } @@ -330,7 +331,7 @@ std::vector Rule::executeSecDefaultActionTransofrmations( for (Action *a : this->m_actionsRuntimePre) { if (none == 0) { - std::string oldValue = value; + std::string oldValue = std::string(value); if (multiMatch) { oldValue = ret.back(); } @@ -373,7 +374,7 @@ std::vector Rule::executeSecDefaultActionTransofrmations( std::vector Rule::getFinalVars( Transaction *trasn) { - std::list exclusions; + std::list exclusions; std::vector *variables = this->variables; std::vector finalVars; @@ -386,7 +387,7 @@ std::vector Rule::getFinalVars( exclusions.push_back(y->m_key); delete y; } - exclusions.push_back(variable->m_name); + exclusions.push_back(&variable->m_name); } } @@ -401,10 +402,13 @@ std::vector Rule::getFinalVars( variable->evaluateInternal(trasn, this, &e); for (const collection::Variable *v : e) { - if (std::find(exclusions.begin(), exclusions.end(), - v->m_key) != exclusions.end()) { + const std::string *key = v->m_key; + + if (std::find_if(exclusions.begin(), exclusions.end(), + [key](const std::string *m) -> bool { return *key == *m; }) + != exclusions.end()) { #ifndef NO_LOGS - trasn->debug(9, "Variable: " + v->m_key + + trasn->debug(9, "Variable: " + *key + " is part of the exclusion list, skipping..."); #endif continue; @@ -416,8 +420,8 @@ std::vector Rule::getFinalVars( if (containsTag(tag, trasn) == false) { continue; } - if (args == v->m_key) { - trasn->debug(9, "Variable: " + v->m_key + + if (args == *key) { + trasn->debug(9, "Variable: " + *key + " was excluded by ruleRemoteTargetByTag..."); ignoreVariable = true; break; @@ -433,8 +437,8 @@ std::vector Rule::getFinalVars( if (rule_id != id) { continue; } - if (args == v->m_key) { - trasn->debug(9, "Variable: " + v->m_key + + if (args == *key) { + trasn->debug(9, "Variable: " + *key + " was excluded by ruleRemoteTargetById..."); ignoreVariable = true; break; @@ -564,7 +568,9 @@ bool Rule::evaluate(Transaction *trasn) { finalVars = getFinalVars(trasn); for (const collection::Variable *v : finalVars) { - std::string value = v->m_value; + const std::string value = *(v->m_value); + const std::string key = *(v->m_key); + std::vector values; bool multiMatch = getActionsByName("multimatch").size() > 0; @@ -573,10 +579,11 @@ bool Rule::evaluate(Transaction *trasn) { for (const std::string &valueTemp : values) { bool ret; - ret = executeOperatorAt(trasn, v->m_key, valueTemp); + + ret = executeOperatorAt(trasn, key, valueTemp); if (ret == true) { - ruleMessage.m_match = resolveMatchMessage(v->m_key, value); - updateMatchedVars(trasn, v->m_key, value); + ruleMessage.m_match = resolveMatchMessage(key, value); + updateMatchedVars(trasn, key, value); executeActionsIndependentOfChainedRuleResult(trasn, &containsDisruptive, &ruleMessage); globalRet = true; diff --git a/src/rules.cc b/src/rules.cc index 50335497..bc04bf94 100644 --- a/src/rules.cc +++ b/src/rules.cc @@ -80,6 +80,9 @@ void Rules::decrementReferenceCount(void) { Rules::~Rules() { int i = 0; + free(unicode_map_table); + unicode_map_table = NULL; + /** Cleanup the rules */ for (int i = 0; i < modsecurity::Phases::NUMBER_OF_PHASES; i++) { std::vector rules = this->rules[i]; @@ -97,9 +100,6 @@ Rules::~Rules() { tmp->pop_back(); } } - - - free(unicode_map_table); } diff --git a/src/transaction.cc b/src/transaction.cc index 3a4a5ace..19a60486 100644 --- a/src/transaction.cc +++ b/src/transaction.cc @@ -768,8 +768,8 @@ int Transaction::processRequestBody() { m_collections.resolveMultiMatches("REQUEST_HEADERS", &l); for (auto &a : l) { fullRequest = fullRequest + \ - std::string(a->m_key, 16, a->m_key.length() - 16) + ": " \ - + a->m_value + "\n"; + std::string(*a->m_key, 16, a->m_key->length() - 16) + ": " \ + + *a->m_value + "\n"; } while (l.empty() == false) { @@ -1387,8 +1387,8 @@ std::string Transaction::toOldAuditLogFormat(int parts, m_collections.m_transient->resolveMultiMatches("REQUEST_HEADERS", &l); for (auto h : l) { size_t pos = strlen("REQUEST_HEADERS:"); - audit_log << h->m_key.c_str() + pos << ": "; - audit_log << h->m_value.c_str() << std::endl; + audit_log << h->m_key->c_str() + pos << ": "; + audit_log << h->m_value->c_str() << std::endl; delete h; } audit_log << std::endl; @@ -1419,8 +1419,8 @@ std::string Transaction::toOldAuditLogFormat(int parts, m_collections.m_transient->resolveMultiMatches("RESPONSE_HEADERS", &l); for (auto h : l) { size_t pos = strlen("RESPONSE_HEADERS:"); - audit_log << h->m_key.c_str() + pos << ": "; - audit_log << h->m_value.c_str() << std::endl; + audit_log << h->m_key->c_str() + pos << ": "; + audit_log << h->m_value->c_str() << std::endl; delete h; } } @@ -1516,7 +1516,7 @@ std::string Transaction::toJSON(int parts) { m_collections.m_transient->resolveMultiMatches("REQUEST_HEADERS", &l); for (auto h : l) { size_t pos = strlen("REQUEST_HEADERS:"); - LOGFY_ADD(h->m_key.c_str() + pos, h->m_value.c_str()); + LOGFY_ADD(h->m_key->c_str() + pos, h->m_value->c_str()); delete h; } @@ -1547,7 +1547,7 @@ std::string Transaction::toJSON(int parts) { m_collections.m_transient->resolveMultiMatches("RESPONSE_HEADERS", &l); for (auto h : l) { size_t pos = strlen("RESPONSE_HEADERS:"); - LOGFY_ADD(h->m_key.c_str() + pos, h->m_value.c_str()); + LOGFY_ADD(h->m_key->c_str() + pos, h->m_value->c_str()); delete h; } diff --git a/src/variables/duration.cc b/src/variables/duration.cc index eb7028ab..04eca088 100644 --- a/src/variables/duration.cc +++ b/src/variables/duration.cc @@ -29,13 +29,12 @@ namespace Variables { void Duration::evaluateInternal(Transaction *transaction, std::vector *l) { - std::string res; - double e = utils::cpu_seconds() - transaction->m_creationTimeStamp; - res = std::to_string(e); + transaction->m_variableDuration.assign(std::to_string(e)); - l->push_back(new collection::Variable("DURATION", std::string(res))); + l->push_back(new collection::Variable(&m_retName, + &transaction->m_variableDuration)); } diff --git a/src/variables/duration.h b/src/variables/duration.h index 59b2468d..c3193b24 100644 --- a/src/variables/duration.h +++ b/src/variables/duration.h @@ -31,10 +31,12 @@ namespace Variables { class Duration : public Variable { public: explicit Duration(std::string _name) - : Variable(_name) { } + : Variable(_name), + m_retName("DURATION") { } void evaluateInternal(Transaction *transaction, std::vector *l) override; + std::string m_retName; }; diff --git a/src/variables/env.cc b/src/variables/env.cc index 7d92466a..7860d697 100644 --- a/src/variables/env.cc +++ b/src/variables/env.cc @@ -34,7 +34,6 @@ namespace Variables { void Env::evaluateInternal(Transaction *transaction, std::vector *l) { - std::map envs; for (char **current = environ; *current; current++) { std::string env = std::string(*current); size_t pos = env.find_first_of("="); @@ -43,20 +42,16 @@ void Env::evaluateInternal(Transaction *transaction, } std::string key = std::string(env, 0, pos); std::string value = std::string(env, pos+1, env.length() - (pos + 1)); - - envs.insert(std::pair("ENV:" + key, value)); - if ("env:" + key == m_name) { - l->push_back(new collection::Variable(m_name, value)); - return; - } + std::pair a("ENV:" + key, value); + transaction->m_variableEnvs.insert(a); } - for (auto& x : envs) { + for (auto& x : transaction->m_variableEnvs) { if ((x.first.substr(0, m_name.size() + 1).compare(m_name + ":") != 0) && (x.first != m_name)) { continue; } - l->push_back(new collection::Variable(x.first, x.second)); + l->push_back(new collection::Variable(&x.first, &x.second)); } } diff --git a/src/variables/highest_severity.cc b/src/variables/highest_severity.cc index 362b3405..203d9b2d 100644 --- a/src/variables/highest_severity.cc +++ b/src/variables/highest_severity.cc @@ -28,8 +28,10 @@ namespace Variables { void HighestSeverity::evaluateInternal(Transaction *transaction, std::vector *l) { - l->push_back(new collection::Variable("HIGHEST_SEVERITY", - std::to_string(transaction->m_highestSeverityAction))); + transaction->m_variableHighestSeverityAction.assign( + std::to_string(transaction->m_highestSeverityAction)); + l->push_back(new collection::Variable(&m_retName, + &transaction->m_variableHighestSeverityAction)); } diff --git a/src/variables/highest_severity.h b/src/variables/highest_severity.h index bec51989..7e72f608 100644 --- a/src/variables/highest_severity.h +++ b/src/variables/highest_severity.h @@ -31,10 +31,12 @@ namespace Variables { class HighestSeverity : public Variable { public: explicit HighestSeverity(std::string _name) - : Variable(_name) { } + : Variable(_name), + m_retName("HIGHEST_SEVERITY") { } void evaluateInternal(Transaction *transaction, std::vector *l) override; + std::string m_retName; }; diff --git a/src/variables/modsec_build.cc b/src/variables/modsec_build.cc index 63fde669..34aa6b1f 100644 --- a/src/variables/modsec_build.cc +++ b/src/variables/modsec_build.cc @@ -15,27 +15,19 @@ #include "src/variables/modsec_build.h" -#include -#include #include #include #include #include "modsecurity/transaction.h" -#include "modsecurity/modsecurity.h" namespace modsecurity { namespace Variables { void ModsecBuild::evaluateInternal(Transaction *transaction, std::vector *l) { - std::ostringstream ss; - ss << std::setw(2) << std::setfill('0') << MODSECURITY_MAJOR; - ss << std::setw(2) << std::setfill('0') << MODSECURITY_MINOR; - ss << std::setw(2) << std::setfill('0') << MODSECURITY_PATCHLEVEL; - ss << std::setw(2) << std::setfill('0') << MODSECURITY_TAG_NUM; - l->push_back(new collection::Variable("MODSEC_BUILD", ss.str())); + l->push_back(new collection::Variable(&m_retName, &m_build)); } diff --git a/src/variables/modsec_build.h b/src/variables/modsec_build.h index 8ad1afa5..200de99e 100644 --- a/src/variables/modsec_build.h +++ b/src/variables/modsec_build.h @@ -17,11 +17,13 @@ #include #include #include +#include #ifndef SRC_VARIABLES_MODSEC_BUILD_H_ #define SRC_VARIABLES_MODSEC_BUILD_H_ #include "src/variables/variable.h" +#include "modsecurity/modsecurity.h" namespace modsecurity { @@ -31,10 +33,21 @@ namespace Variables { class ModsecBuild : public Variable { public: explicit ModsecBuild(std::string _name) - : Variable(_name) { } + : Variable(_name), + m_retName("MODSEC_BUILD") { + std::ostringstream ss; + ss << std::setw(2) << std::setfill('0') << MODSECURITY_MAJOR; + ss << std::setw(2) << std::setfill('0') << MODSECURITY_MINOR; + ss << std::setw(2) << std::setfill('0') << MODSECURITY_PATCHLEVEL; + ss << std::setw(2) << std::setfill('0') << MODSECURITY_TAG_NUM; + m_build = ss.str(); + } void evaluateInternal(Transaction *transaction, std::vector *l) override; + + std::string m_build; + std::string m_retName; }; diff --git a/src/variables/remote_user.cc b/src/variables/remote_user.cc index 97bd2fc3..f60b7953 100644 --- a/src/variables/remote_user.cc +++ b/src/variables/remote_user.cc @@ -57,9 +57,10 @@ void RemoteUser::evaluateInternal(Transaction *transaction, if (pos == std::string::npos) { return; } - base64 = std::string(base64, 0, pos); + transaction->m_variableRemoteUser.assign(std::string(base64, 0, pos)); - l->push_back(new collection::Variable("REMOTE_USER", base64)); + l->push_back(new collection::Variable(&m_retName, + &transaction->m_variableRemoteUser)); } diff --git a/src/variables/remote_user.h b/src/variables/remote_user.h index 3e179e25..7f1b5441 100644 --- a/src/variables/remote_user.h +++ b/src/variables/remote_user.h @@ -33,10 +33,12 @@ namespace Variables { class RemoteUser : public Variable { public: explicit RemoteUser(std::string _name) - : Variable(_name) { } + : Variable(_name), + m_retName("REMOTE_USER") { } void evaluateInternal(Transaction *transaction, std::vector *l) override; + std::string m_retName; }; diff --git a/src/variables/time.cc b/src/variables/time.cc index 9fdba0a6..fc639dc8 100644 --- a/src/variables/time.cc +++ b/src/variables/time.cc @@ -46,7 +46,9 @@ void Time::evaluateInternal(Transaction *transaction, localtime_r(&timer, &timeinfo); strftime(tstr, 200, "%H:%M:%S", &timeinfo); - l->push_back(new collection::Variable("TIME", std::string(tstr))); + transaction->m_variableTime.assign(tstr); + l->push_back(new collection::Variable(&m_retName, + &transaction->m_variableTime)); } diff --git a/src/variables/time.h b/src/variables/time.h index 57418e08..c5a1e4e1 100644 --- a/src/variables/time.h +++ b/src/variables/time.h @@ -32,10 +32,12 @@ namespace Variables { class Time : public Variable { public: explicit Time(std::string _name) - : Variable(_name) { } + : Variable(_name), + m_retName("TIME") { } void evaluateInternal(Transaction *transaction, std::vector *l) override; + std::string m_retName; }; } // namespace Variables diff --git a/src/variables/time_day.cc b/src/variables/time_day.cc index faa0ed94..f69333d4 100644 --- a/src/variables/time_day.cc +++ b/src/variables/time_day.cc @@ -45,7 +45,10 @@ void TimeDay::evaluateInternal(Transaction *transaction, localtime_r(&timer, &timeinfo); strftime(tstr, 200, "%d", &timeinfo); - l->push_back(new collection::Variable("TIME_DAY", std::string(tstr))); + transaction->m_variableTimeDay.assign(tstr); + + l->push_back(new collection::Variable(&m_retName, + &transaction->m_variableTimeDay)); } diff --git a/src/variables/time_day.h b/src/variables/time_day.h index 599acbb5..ce3a3479 100644 --- a/src/variables/time_day.h +++ b/src/variables/time_day.h @@ -31,10 +31,12 @@ namespace Variables { class TimeDay : public Variable { public: explicit TimeDay(std::string _name) - : Variable(_name) { } + : Variable(_name), + m_retName("TIME_DAY") { } void evaluateInternal(Transaction *transaction, std::vector *l) override; + std::string m_retName; }; } // namespace Variables diff --git a/src/variables/time_epoch.cc b/src/variables/time_epoch.cc index 752b339d..c4ea71d0 100644 --- a/src/variables/time_epoch.cc +++ b/src/variables/time_epoch.cc @@ -35,8 +35,10 @@ namespace Variables { void TimeEpoch::evaluateInternal(Transaction *transaction, std::vector *l) { - l->push_back(new collection::Variable("TIME_EPOCH", - std::to_string(std::time(nullptr)))); + transaction->m_variableTimeEpoch.assign( + std::to_string(std::time(nullptr))); + l->push_back(new collection::Variable(&m_retName, + &transaction->m_variableTimeEpoch)); } diff --git a/src/variables/time_epoch.h b/src/variables/time_epoch.h index a99f30c4..68234f83 100644 --- a/src/variables/time_epoch.h +++ b/src/variables/time_epoch.h @@ -31,10 +31,12 @@ namespace Variables { class TimeEpoch : public Variable { public: explicit TimeEpoch(std::string _name) - : Variable(_name) { } + : Variable(_name), + m_retName("TIME_EPOCH") { } void evaluateInternal(Transaction *transaction, std::vector *l) override; + std::string m_retName; }; } // namespace Variables diff --git a/src/variables/time_hour.cc b/src/variables/time_hour.cc index c1d9467f..8d2fc1e2 100644 --- a/src/variables/time_hour.cc +++ b/src/variables/time_hour.cc @@ -45,7 +45,10 @@ void TimeHour::evaluateInternal(Transaction *transaction, localtime_r(&timer, &timeinfo); strftime(tstr, 200, "%H", &timeinfo); - l->push_back(new collection::Variable("TIME_HOUR", std::string(tstr))); + transaction->m_variableTimeHour.assign(tstr); + + l->push_back(new collection::Variable(&m_retName, + &transaction->m_variableTimeHour)); } diff --git a/src/variables/time_hour.h b/src/variables/time_hour.h index d9e02fe7..9fa3434e 100644 --- a/src/variables/time_hour.h +++ b/src/variables/time_hour.h @@ -31,10 +31,12 @@ namespace Variables { class TimeHour : public Variable { public: explicit TimeHour(std::string _name) - : Variable(_name) { } + : Variable(_name), + m_retName("TIME_HOUR") { } void evaluateInternal(Transaction *transaction, std::vector *l) override; + std::string m_retName; }; } // namespace Variables diff --git a/src/variables/time_min.cc b/src/variables/time_min.cc index 921e232e..7027c1b2 100644 --- a/src/variables/time_min.cc +++ b/src/variables/time_min.cc @@ -45,7 +45,10 @@ void TimeMin::evaluateInternal(Transaction *transaction, localtime_r(&timer, &timeinfo); strftime(tstr, 200, "%M", &timeinfo); - l->push_back(new collection::Variable("TIME_MIN", std::string(tstr))); + transaction->m_variableTimeMin.assign(tstr); + + l->push_back(new collection::Variable(&m_retName, + &transaction->m_variableTimeMin)); } diff --git a/src/variables/time_min.h b/src/variables/time_min.h index fd9a1881..4ec7b9bc 100644 --- a/src/variables/time_min.h +++ b/src/variables/time_min.h @@ -31,10 +31,12 @@ namespace Variables { class TimeMin : public Variable { public: explicit TimeMin(std::string _name) - : Variable(_name) { } + : Variable(_name), + m_retName("TIME_MIN") { } void evaluateInternal(Transaction *transaction, std::vector *l) override; + std::string m_retName; }; } // namespace Variables diff --git a/src/variables/time_mon.cc b/src/variables/time_mon.cc index 79f177a0..fc9a9ab5 100644 --- a/src/variables/time_mon.cc +++ b/src/variables/time_mon.cc @@ -47,7 +47,10 @@ void TimeMon::evaluateInternal(Transaction *transaction, int a = atoi(tstr); a--; - l->push_back(new collection::Variable("TIME_MON", std::to_string(a))); + transaction->m_variableTimeMin.assign(std::to_string(a)); + + l->push_back(new collection::Variable(&m_retName, + &transaction->m_variableTimeMin)); } diff --git a/src/variables/time_mon.h b/src/variables/time_mon.h index 673c377b..aa4f50df 100644 --- a/src/variables/time_mon.h +++ b/src/variables/time_mon.h @@ -31,10 +31,12 @@ namespace Variables { class TimeMon : public Variable { public: explicit TimeMon(std::string _name) - : Variable(_name) { } + : Variable(_name), + m_retName("TIME_MON") { } void evaluateInternal(Transaction *transaction, std::vector *l) override; + std::string m_retName; }; } // namespace Variables diff --git a/src/variables/time_sec.cc b/src/variables/time_sec.cc index 87658427..38e8f518 100644 --- a/src/variables/time_sec.cc +++ b/src/variables/time_sec.cc @@ -45,7 +45,10 @@ void TimeSec::evaluateInternal(Transaction *transaction, localtime_r(&timer, &timeinfo); strftime(tstr, 200, "%S", &timeinfo); - l->push_back(new collection::Variable("TIME_SEC", std::string(tstr))); + transaction->m_variableTimeSec.assign(tstr); + + l->push_back(new collection::Variable(&m_retName, + &transaction->m_variableTimeSec)); } diff --git a/src/variables/time_sec.h b/src/variables/time_sec.h index 0cd1da7f..d925019d 100644 --- a/src/variables/time_sec.h +++ b/src/variables/time_sec.h @@ -31,10 +31,12 @@ namespace Variables { class TimeSec : public Variable { public: explicit TimeSec(std::string _name) - : Variable(_name) { } + : Variable(_name), + m_retName("TIME_SEC") { } void evaluateInternal(Transaction *transaction, std::vector *l) override; + std::string m_retName; }; } // namespace Variables diff --git a/src/variables/time_wday.cc b/src/variables/time_wday.cc index 52f95389..22566a93 100644 --- a/src/variables/time_wday.cc +++ b/src/variables/time_wday.cc @@ -47,7 +47,10 @@ void TimeWDay::evaluateInternal(Transaction *transaction, int a = atoi(tstr); a--; - l->push_back(new collection::Variable("TIME_WDAY", std::to_string(a))); + transaction->m_variableTimeWDay.assign(tstr); + + l->push_back(new collection::Variable(&m_retName, + &transaction->m_variableTimeWDay)); } diff --git a/src/variables/time_wday.h b/src/variables/time_wday.h index 2bd63892..92fd4960 100644 --- a/src/variables/time_wday.h +++ b/src/variables/time_wday.h @@ -31,10 +31,12 @@ namespace Variables { class TimeWDay : public Variable { public: explicit TimeWDay(std::string _name) - : Variable(_name) { } + : Variable(_name), + m_retName("TIME_WDAY") { } void evaluateInternal(Transaction *transaction, std::vector *l) override; + std::string m_retName; }; } // namespace Variables diff --git a/src/variables/time_year.cc b/src/variables/time_year.cc index 2f789f39..e92b32f4 100644 --- a/src/variables/time_year.cc +++ b/src/variables/time_year.cc @@ -45,7 +45,10 @@ void TimeYear::evaluateInternal(Transaction *transaction, localtime_r(&timer, &timeinfo); strftime(tstr, 200, "%Y", &timeinfo); - l->push_back(new collection::Variable("TIME_YEAR", std::string(tstr))); + transaction->m_variableTimeYear.assign(tstr); + + l->push_back(new collection::Variable(&m_retName, + &transaction->m_variableTimeYear)); } diff --git a/src/variables/time_year.h b/src/variables/time_year.h index 7db5c7c6..a606de63 100644 --- a/src/variables/time_year.h +++ b/src/variables/time_year.h @@ -31,10 +31,12 @@ namespace Variables { class TimeYear : public Variable { public: explicit TimeYear(std::string _name) - : Variable(_name) { } + : Variable(_name), + m_retName("TIME_YEAR") { } void evaluateInternal(Transaction *transaction, std::vector *l) override; + std::string m_retName; }; } // namespace Variables diff --git a/src/variables/variations/count.cc b/src/variables/variations/count.cc index a755b0fa..e11880e1 100644 --- a/src/variables/variations/count.cc +++ b/src/variables/variations/count.cc @@ -46,10 +46,13 @@ void Count::evaluateInternal(Transaction *transaction, } delete reslIn; - std::string res = std::to_string(count); + std::string *res = new std::string(std::to_string(count)); - l->push_back(new collection::Variable(std::string(var->m_name), - std::string(res))); + collection::Variable *val = new collection::Variable(&var->m_name, + res); + val->m_dynamic_value = true; + + l->push_back(val); } diff --git a/src/variables/xml.cc b/src/variables/xml.cc index 19f21c88..dce6de46 100644 --- a/src/variables/xml.cc +++ b/src/variables/xml.cc @@ -73,8 +73,7 @@ void XML::evaluateInternal(Transaction *t, /* Invocation without an XPath expression makes sense * with functions that manipulate the document tree. */ - l->push_back(new collection::Variable("XML", - std::string("[XML document tree]" + param))); + l->push_back(new collection::Variable(&m_name, &m_plain)); return; } @@ -124,8 +123,9 @@ void XML::evaluateInternal(Transaction *t, content = reinterpret_cast( xmlNodeGetContent(nodes->nodeTab[i])); if (content != NULL) { - l->push_back(new collection::Variable(m_name, - std::string(content))); + // FIXME: Memory leak + l->push_back(new collection::Variable(&m_name, + new std::string(content))); xmlFree(content); } } diff --git a/src/variables/xml.h b/src/variables/xml.h index a8b81f14..afee419f 100644 --- a/src/variables/xml.h +++ b/src/variables/xml.h @@ -33,11 +33,13 @@ namespace Variables { class XML : public Variable { public: explicit XML(std::string _name) - : Variable(_name) { } + : Variable(_name), + m_plain("[XML document tree]") { } void evaluateInternal(Transaction *transaction, Rule *rule, std::vector *l) override; + std::string m_plain; }; } // namespace Variables diff --git a/test/test-cases/regression/variable-RULE.json b/test/test-cases/regression/variable-RULE.json index d79f2e87..2e787b20 100644 --- a/test/test-cases/regression/variable-RULE.json +++ b/test/test-cases/regression/variable-RULE.json @@ -256,7 +256,7 @@ ] }, "expected":{ - "debug_log":" Target value: \"message123\" \\(Variable: rule:msg\\)" + "debug_log":" Target value: \"message123\" \\(Variable: RULE:msg\\)" }, "rules":[ "SecRuleEngine On",