Handles better the memory utilization

- Added reference counts to Rule and AuditLog;
- Some memory leaks were removed, including GeoLookup;
- Deal better with parser errors;
- Overriding the AutlogLogWritter destructor.
This commit is contained in:
Felipe Zimmerle 2015-07-26 22:40:51 -03:00
parent 0e7c13e3c0
commit e016b72a8e
31 changed files with 385 additions and 169 deletions

View File

@ -157,7 +157,7 @@ class Assay {
int processLogging(int status_code); int processLogging(int status_code);
ModSecurityIntervention *intervention(); bool intervention(ModSecurityIntervention *it);
void cleanup(); void cleanup();
@ -281,7 +281,7 @@ int msc_get_response_body_length(Assay *assay);
void msc_assay_cleanup(Assay *assay); void msc_assay_cleanup(Assay *assay);
/** @ingroup ModSecurity_C_API */ /** @ingroup ModSecurity_C_API */
ModSecurityIntervention *msc_intervention(Assay *assay); int msc_intervention(Assay *assay, ModSecurityIntervention *it);
/** @ingroup ModSecurity_C_API */ /** @ingroup ModSecurity_C_API */
int msc_process_logging(Assay *assay, int code); int msc_process_logging(Assay *assay, int code);

View File

@ -42,7 +42,8 @@ class DebugLog : public std::ofstream {
*/ */
DebugLog() DebugLog()
: m_is_configured(false), : m_is_configured(false),
m_debug_level(0) { } m_debug_level(0),
m_referenceCount(0) { }
bool setOutputFile(const std::string& file); bool setOutputFile(const std::string& file);
virtual bool write_log(int level, const std::string& data); virtual bool write_log(int level, const std::string& data);
@ -53,6 +54,9 @@ class DebugLog : public std::ofstream {
virtual DebugLog *new_instance(); virtual DebugLog *new_instance();
void refCountDecreaseAndCheck(void);
void refCountIncrease(void);
private: private:
/* /*
ModSecurityDebugLog(ModSecurityDebugLog const&); ModSecurityDebugLog(ModSecurityDebugLog const&);
@ -60,6 +64,7 @@ class DebugLog : public std::ofstream {
*/ */
int m_debug_level; int m_debug_level;
bool m_is_configured; bool m_is_configured;
int m_referenceCount;
}; };
} // namespace ModSecurity } // namespace ModSecurity

View File

@ -49,7 +49,7 @@ class Rules : public RulesProperties {
Rules() Rules()
: RulesProperties(NULL) { } : RulesProperties(NULL) { }
Rules(DebugLog *customLog) explicit Rules(DebugLog *customLog)
: RulesProperties(customLog) { } : RulesProperties(customLog) { }
~Rules(); ~Rules();
@ -75,6 +75,7 @@ class Rules : public RulesProperties {
std::ostringstream parserError; std::ostringstream parserError;
DebugLog *debugLog; DebugLog *debugLog;
private: private:
int m_referenceCount; int m_referenceCount;
}; };

View File

@ -27,7 +27,6 @@
#include "modsecurity/modsecurity.h" #include "modsecurity/modsecurity.h"
#include "modsecurity/assay.h" #include "modsecurity/assay.h"
#include "modsecurity/assay.h"
#ifdef __cplusplus #ifdef __cplusplus
@ -61,7 +60,7 @@ class RulesProperties {
responseBodyLimitAction(ProcessPartialBodyLimitAction), responseBodyLimitAction(ProcessPartialBodyLimitAction),
secRuleEngine(DetectionOnlyRuleEngine) { } secRuleEngine(DetectionOnlyRuleEngine) { }
~RulesProperties() { }; ~RulesProperties() { }
std::vector<Rule *> rules[7]; // ModSecurity::Phases::NUMBER_OF_PHASES std::vector<Rule *> rules[7]; // ModSecurity::Phases::NUMBER_OF_PHASES
@ -174,10 +173,7 @@ class RulesProperties {
AuditLog *audit_log; AuditLog *audit_log;
OnFailedRemoteRulesAction remoteRulesActionOnFailed; OnFailedRemoteRulesAction remoteRulesActionOnFailed;
}; };
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -55,7 +55,7 @@ bool Action::evaluate(Rule *rule) {
void Action::fill_intervention(ModSecurityIntervention *i) { void Action::fill_intervention(ModSecurityIntervention *i) {
} }
Action *Action::instantiate(std::string name) { Action *Action::instantiate(const std::string& name) {
std::string status("status:"); std::string status("status:");
std::string redirect("redirect:"); std::string redirect("redirect:");
std::string block("block"); std::string block("block");

View File

@ -14,6 +14,7 @@
*/ */
#include <string> #include <string>
#include <iostream>
#include "modsecurity/intervention.h" #include "modsecurity/intervention.h"
@ -31,13 +32,16 @@ namespace actions {
class Action { class Action {
public: public:
explicit Action(std::string _action) explicit Action(const std::string& _action)
: action_kind(2), : action_kind(2),
action(_action) { } action(_action),
explicit Action(std::string _action, int kind) temporaryAction(false) { }
explicit Action(const std::string& _action, int kind)
: action_kind(kind), : action_kind(kind),
action(_action) { } action(_action),
temporaryAction(false) { }
virtual ~Action() { }
/** /**
* *
* Define the action kind regarding to the execution time. * Define the action kind regarding to the execution time.
@ -79,9 +83,10 @@ class Action {
virtual bool evaluate(Assay *assay); virtual bool evaluate(Assay *assay);
virtual bool evaluate(Rule *rule); virtual bool evaluate(Rule *rule);
static Action *instantiate(std::string action); static Action *instantiate(const std::string& name);
virtual void fill_intervention(ModSecurityIntervention *intervention); virtual void fill_intervention(ModSecurityIntervention *intervention);
bool temporaryAction;
}; };

View File

@ -23,12 +23,13 @@
namespace ModSecurity { namespace ModSecurity {
namespace actions { namespace actions {
Redirect::Redirect(std::string action) Redirect::~Redirect() {
: Action(action) { }
this->url = action;
this->url.erase(0, 9); Redirect::Redirect(const std::string& action)
this->action = action; : Action(action, RunTimeOnlyIfMatchKind),
this->action_kind = 2; url(action) {
this->url = this->url.erase(0, 9);
this->status = 302; this->status = 302;
} }

View File

@ -30,7 +30,8 @@ namespace actions {
class Redirect : public Action { class Redirect : public Action {
public: public:
explicit Redirect(std::string action); explicit Redirect(const std::string &action);
~Redirect() override;
bool evaluate(Assay *assay) override; bool evaluate(Assay *assay) override;
int status; int status;

View File

@ -128,6 +128,12 @@ Assay::Assay(ModSecurity *ms, Rules *rules)
Assay::~Assay() { Assay::~Assay() {
m_responseBody.str(std::string());
m_responseBody.clear();
m_requestBody.str(std::string());
m_requestBody.clear();
m_rules->decrementReferenceCount(); m_rules->decrementReferenceCount();
} }
@ -637,6 +643,7 @@ int Assay::appendRequestBody(const unsigned char *buf, size_t len) {
debug(5, "Request body limit is marked to reject the " \ debug(5, "Request body limit is marked to reject the " \
"request"); "request");
Action *a = new actions::Block("block"); Action *a = new actions::Block("block");
a->temporaryAction = true;
actions.push_back(a); actions.push_back(a);
} }
return true; return true;
@ -833,6 +840,7 @@ int Assay::appendResponseBody(const unsigned char *buf, size_t len) {
debug(5, "Response body limit is marked to reject the " \ debug(5, "Response body limit is marked to reject the " \
"request"); "request");
Action *a = new actions::Block("block"); Action *a = new actions::Block("block");
a->temporaryAction = true;
actions.push_back(a); actions.push_back(a);
} }
return true; return true;
@ -930,12 +938,6 @@ int Assay::processLogging(int returned_code) {
* *
*/ */
void Assay::cleanup() { void Assay::cleanup() {
m_responseBody.str("");
m_responseBody.clear();
m_requestBody.str("");
m_requestBody.clear();
delete this; delete this;
} }
@ -946,32 +948,25 @@ void Assay::cleanup() {
* *
* Intervention can generate a log event and/or perform a disruptive action. * Intervention can generate a log event and/or perform a disruptive action.
* *
* @return Pointer to ModSecurityIntervention structure * @param Pointer ModSecurityIntervention structure
* @retval >0 A intervention should be made. * @retval true A intervention should be made.
* @retval NULL Nothing to be done. * @retval false Nothing to be done.
* *
*/ */
ModSecurityIntervention *Assay::intervention() { bool Assay::intervention(ModSecurityIntervention *it) {
ModSecurityIntervention *ret = NULL; bool ret = false;
/**
* FIXME: Implement this.
*
*/
if (actions.size() > 0) { if (actions.size() > 0) {
for (Action *a : actions) { for (Action *a : actions) {
if (a->action_kind == Action::Kind::RunTimeOnlyIfMatchKind) { if (a->action_kind == Action::Kind::RunTimeOnlyIfMatchKind) {
if (ret == NULL) { a->fill_intervention(it);
ret = static_cast<ModSecurityIntervention *>(calloc( \ }
1, sizeof(struct ModSecurityIntervention_t))); if (a->temporaryAction) {
ret->status = 200; delete a;
}
a->fill_intervention(ret);
} }
} }
actions.clear(); actions.clear();
ret = true;
} }
return ret; return ret;
} }
@ -1684,8 +1679,8 @@ extern "C" void msc_assay_cleanup(Assay *assay) {
* @retval NULL Nothing to be done. * @retval NULL Nothing to be done.
* *
*/ */
extern "C" ModSecurityIntervention *msc_intervention(Assay *assay) { extern "C" int msc_intervention(Assay *assay, ModSecurityIntervention *it) {
return assay->intervention(); return assay->intervention(it);
} }

View File

@ -112,6 +112,7 @@ bool AuditLog::init() {
if (m_type == SerialAuditLogType) { if (m_type == SerialAuditLogType) {
m_writer = new AuditLogWriterSerial(this); m_writer = new AuditLogWriterSerial(this);
} }
m_writer->refCountIncrease();
if (m_writer == NULL || m_writer->init() == false) { if (m_writer == NULL || m_writer->init() == false) {
std::cout << "not able to open the log for write." << std::endl; std::cout << "not able to open the log for write." << std::endl;

View File

@ -44,7 +44,7 @@ class AuditLog {
m_relevant(""), m_relevant(""),
filePermission(0600), filePermission(0600),
directoryPermission(0600), directoryPermission(0600),
m_refereceCount(1) m_refereceCount(0)
{ } { }
~AuditLog(); ~AuditLog();

View File

@ -33,9 +33,9 @@ class AuditLogWriter {
public: public:
explicit AuditLogWriter(AuditLog *audit) explicit AuditLogWriter(AuditLog *audit)
: m_audit(audit), : m_audit(audit),
m_refereceCount(1) { } m_refereceCount(0) { }
~AuditLogWriter() { } virtual ~AuditLogWriter() { }
virtual void refCountIncrease() = 0; virtual void refCountIncrease() = 0;
virtual void refCountDecreaseAndCheck() = 0; virtual void refCountDecreaseAndCheck() = 0;

View File

@ -31,7 +31,7 @@ class AuditLogWriterParallel : public AuditLogWriter {
explicit AuditLogWriterParallel(AuditLog *audit) explicit AuditLogWriterParallel(AuditLog *audit)
: AuditLogWriter(audit) { } : AuditLogWriter(audit) { }
~AuditLogWriterParallel(); ~AuditLogWriterParallel() override;
bool init() override; bool init() override;
bool write(Assay *assay, int parts) override; bool write(Assay *assay, int parts) override;

View File

@ -37,7 +37,7 @@ class AuditLogWriterSerial : public AuditLogWriter {
explicit AuditLogWriterSerial(AuditLog *audit) explicit AuditLogWriterSerial(AuditLog *audit)
: AuditLogWriter(audit) { } : AuditLogWriter(audit) { }
~AuditLogWriterSerial(); ~AuditLogWriterSerial() override;
void refCountIncrease() override { void refCountIncrease() override {
m_refereceCount++; m_refereceCount++;

View File

@ -123,4 +123,17 @@ bool DebugLog::isConfigured() {
} }
void DebugLog::refCountDecreaseAndCheck(void) {
this->m_referenceCount--;
if (this->m_referenceCount == 0) {
delete this;
}
}
void DebugLog::refCountIncrease(void) {
this->m_referenceCount++;
}
} // namespace ModSecurity } // namespace ModSecurity

View File

@ -24,6 +24,8 @@
#include <curl/curl.h> #include <curl/curl.h>
#endif #endif
#include "utils/geo_lookup.h"
namespace ModSecurity { namespace ModSecurity {
/** /**
@ -52,6 +54,10 @@ ModSecurity::ModSecurity()
ModSecurity::~ModSecurity() { ModSecurity::~ModSecurity() {
#ifdef MSC_WITH_CURL
curl_global_cleanup();
#endif
Utils::GeoLookup::getInstance().cleanUp();
} }

View File

@ -32,6 +32,7 @@ Driver::Driver()
Driver::~Driver() { Driver::~Driver() {
delete loc.back();
} }
@ -70,7 +71,7 @@ int Driver::addSecRule(Rule *rule) {
int Driver::parse(const std::string &f, const std::string &ref) { int Driver::parse(const std::string &f, const std::string &ref) {
loc.push_back(*(new yy::location())); loc.push_back(new yy::location());
if (ref.empty()) { if (ref.empty()) {
this->ref.push_back("<<reference missing or not informed>>"); this->ref.push_back("<<reference missing or not informed>>");
} else { } else {

View File

@ -75,7 +75,7 @@ class Driver : public RulesProperties {
void error(const yy::location& l, const std::string& m, void error(const yy::location& l, const std::string& m,
const std::string& c); const std::string& c);
std::list<yy::location> loc; std::list<yy::location *> loc;
std::list<std::string> ref; std::list<std::string> ref;
std::string buffer; std::string buffer;

View File

@ -58,6 +58,21 @@ using ModSecurity::Variables::TimeWDay;
using ModSecurity::Variables::TimeYear; using ModSecurity::Variables::TimeYear;
using ModSecurity::Variables::Variable; using ModSecurity::Variables::Variable;
/**
* %destructor { code } THING
*
* %destructor is not working as expected. Apparently it was fixed on a most recent,
* version of Bison. We are not interested to limit the usage to this newest version,
* thus, we have to deal with memory leak when rules failed to load. Not that big
* problem, as we don't really continue when it fails (only for SecRemoteRules).
*
* Information about destructor:
* http://www.gnu.org/software/bison/manual/html_node/Destructor-Decl.html
*
* Patch:
* https://www.mail-archive.com/search?l=bug-bison@gnu.org&q=subject:%22Destructor+miscompilation+with+C%2B%2B+variants%3F%22&o=newest&f=1
*/
} }
// The parsing context. // The parsing context.
%param { ModSecurity::Parser::Driver& driver } %param { ModSecurity::Parser::Driver& driver }
@ -154,6 +169,7 @@ using ModSecurity::Variables::Variable;
%type <std::vector<Action *> *> actions %type <std::vector<Action *> *> actions
%type <std::vector<Variable *> *> variables %type <std::vector<Variable *> *> variables
%printer { yyoutput << $$; } <*>; %printer { yyoutput << $$; } <*>;
%% %%
%start secrule; %start secrule;

View File

@ -112,96 +112,98 @@ FREE_TEXT_NEW_LINE [^\"|\n]+
%{ %{
// Code run each time a pattern is matched. // Code run each time a pattern is matched.
# define YY_USER_ACTION driver.loc.back().columns (yyleng); # define YY_USER_ACTION driver.loc.back()->columns (yyleng);
%} %}
%% %%
%{ %{
// Code run each time yylex is called. // Code run each time yylex is called.
driver.loc.back().step(); driver.loc.back()->step();
%} %}
{DIRECTIVE} { return yy::seclang_parser::make_DIRECTIVE(yytext, driver.loc.back()); } {DIRECTIVE} { return yy::seclang_parser::make_DIRECTIVE(yytext, *driver.loc.back()); }
{TRANSFORMATION} { return yy::seclang_parser::make_TRANSFORMATION(yytext, driver.loc.back()); } {TRANSFORMATION} { return yy::seclang_parser::make_TRANSFORMATION(yytext, *driver.loc.back()); }
{CONFIG_DIR_RULE_ENG} { return yy::seclang_parser::make_CONFIG_DIR_RULE_ENG(yytext, driver.loc.back()); } {CONFIG_DIR_RULE_ENG} { return yy::seclang_parser::make_CONFIG_DIR_RULE_ENG(yytext, *driver.loc.back()); }
{CONFIG_DIR_RES_BODY} { return yy::seclang_parser::make_CONFIG_DIR_RES_BODY(yytext, driver.loc.back()); } {CONFIG_DIR_RES_BODY} { return yy::seclang_parser::make_CONFIG_DIR_RES_BODY(yytext, *driver.loc.back()); }
{CONFIG_DIR_REQ_BODY} { return yy::seclang_parser::make_CONFIG_DIR_REQ_BODY(yytext, driver.loc.back()); } {CONFIG_DIR_REQ_BODY} { return yy::seclang_parser::make_CONFIG_DIR_REQ_BODY(yytext, *driver.loc.back()); }
%{ /* Audit log entries */ %} %{ /* Audit log entries */ %}
{CONFIG_DIR_AUDIT_DIR}[ ]{CONFIG_VALUE_PATH} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_DIR(strchr(yytext, ' ') + 1, driver.loc.back()); } {CONFIG_DIR_AUDIT_DIR}[ ]{CONFIG_VALUE_PATH} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_DIR(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_AUDIT_DIR_MOD}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_DIR_MOD(strchr(yytext, ' ') + 1, driver.loc.back()); } {CONFIG_DIR_AUDIT_DIR_MOD}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_DIR_MOD(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_AUDIT_ENG} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_ENG(yytext, driver.loc.back()); } {CONFIG_DIR_AUDIT_ENG} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_ENG(yytext, *driver.loc.back()); }
{CONFIG_DIR_AUDIT_FLE_MOD}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_FLE_MOD(strchr(yytext, ' ') + 1, driver.loc.back()); } {CONFIG_DIR_AUDIT_FLE_MOD}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_FLE_MOD(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_AUDIT_LOG2}[ ]{CONFIG_VALUE_PATH} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_LOG2(strchr(yytext, ' ') + 1, driver.loc.back()); } {CONFIG_DIR_AUDIT_LOG2}[ ]{CONFIG_VALUE_PATH} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_LOG2(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_AUDIT_LOG}[ ]{CONFIG_VALUE_PATH} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_LOG(strchr(yytext, ' ') + 1, driver.loc.back()); } {CONFIG_DIR_AUDIT_LOG}[ ]{CONFIG_VALUE_PATH} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_LOG(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_AUDIT_LOG_P}[ ]{AUDIT_PARTS} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_LOG_P(strchr(yytext, ' ') + 1, driver.loc.back()); } {CONFIG_DIR_AUDIT_LOG_P}[ ]{AUDIT_PARTS} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_LOG_P(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_AUDIT_STS}[ ]["]{FREE_TEXT}["] { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_STS(strchr(yytext, ' ') + 1, driver.loc.back()); } {CONFIG_DIR_AUDIT_STS}[ ]["]{FREE_TEXT}["] { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_STS(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_AUDIT_TPE} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_TPE(yytext, driver.loc.back()); } {CONFIG_DIR_AUDIT_TPE} { return yy::seclang_parser::make_CONFIG_DIR_AUDIT_TPE(yytext, *driver.loc.back()); }
%{ /* Debug log entries */ %} %{ /* Debug log entries */ %}
{CONFIG_DIR_DEBUG_LOG}[ ]{CONFIG_VALUE_PATH} { return yy::seclang_parser::make_CONFIG_DIR_DEBUG_LOG(strchr(yytext, ' ') + 1, driver.loc.back()); } {CONFIG_DIR_DEBUG_LOG}[ ]{CONFIG_VALUE_PATH} { return yy::seclang_parser::make_CONFIG_DIR_DEBUG_LOG(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_DEBUG_LVL}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_DEBUG_LVL(strchr(yytext, ' ') + 1, driver.loc.back()); } {CONFIG_DIR_DEBUG_LVL}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_DEBUG_LVL(strchr(yytext, ' ') + 1, *driver.loc.back()); }
%{ /* Variables */ %} %{ /* Variables */ %}
{VARIABLE}:?{DICT_ELEMENT}? { return yy::seclang_parser::make_VARIABLE(yytext, driver.loc.back()); } {VARIABLE}:?{DICT_ELEMENT}? { return yy::seclang_parser::make_VARIABLE(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_DUR} { return yy::seclang_parser::make_RUN_TIME_VAR_DUR(yytext, driver.loc.back()); } {RUN_TIME_VAR_DUR} { return yy::seclang_parser::make_RUN_TIME_VAR_DUR(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_ENV}:?{DICT_ELEMENT}? { return yy::seclang_parser::make_RUN_TIME_VAR_ENV(yytext, driver.loc.back()); } {RUN_TIME_VAR_ENV}:?{DICT_ELEMENT}? { return yy::seclang_parser::make_RUN_TIME_VAR_ENV(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_BLD} { return yy::seclang_parser::make_RUN_TIME_VAR_BLD(yytext, driver.loc.back()); } {RUN_TIME_VAR_BLD} { return yy::seclang_parser::make_RUN_TIME_VAR_BLD(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_HSV} { return yy::seclang_parser::make_RUN_TIME_VAR_HSV(yytext, driver.loc.back()); } {RUN_TIME_VAR_HSV} { return yy::seclang_parser::make_RUN_TIME_VAR_HSV(yytext, *driver.loc.back()); }
%{ /* Variables: TIME */ %} %{ /* Variables: TIME */ %}
{RUN_TIME_VAR_TIME} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME(yytext, driver.loc.back()); } {RUN_TIME_VAR_TIME} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_TIME_DAY} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_DAY(yytext, driver.loc.back()); } {RUN_TIME_VAR_TIME_DAY} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_DAY(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_TIME_EPOCH} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_EPOCH(yytext, driver.loc.back()); } {RUN_TIME_VAR_TIME_EPOCH} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_EPOCH(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_TIME_HOUR} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_HOUR(yytext, driver.loc.back()); } {RUN_TIME_VAR_TIME_HOUR} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_HOUR(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_TIME_MIN} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_MIN(yytext, driver.loc.back()); } {RUN_TIME_VAR_TIME_MIN} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_MIN(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_TIME_MON} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_MON(yytext, driver.loc.back()); } {RUN_TIME_VAR_TIME_MON} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_MON(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_TIME_SEC} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_SEC(yytext, driver.loc.back()); } {RUN_TIME_VAR_TIME_SEC} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_SEC(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_TIME_WDAY} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_WDAY(yytext, driver.loc.back()); } {RUN_TIME_VAR_TIME_WDAY} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_WDAY(yytext, *driver.loc.back()); }
{RUN_TIME_VAR_TIME_YEAR} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_YEAR(yytext, driver.loc.back()); } {RUN_TIME_VAR_TIME_YEAR} { return yy::seclang_parser::make_RUN_TIME_VAR_TIME_YEAR(yytext, *driver.loc.back()); }
%{ /* Geo DB loopkup */ %} %{ /* Geo DB loopkup */ %}
{CONFIG_DIR_GEO_DB}[ ]{FREE_TEXT_NEW_LINE} { return yy::seclang_parser::make_CONFIG_DIR_GEO_DB(strchr(yytext, ' ') + 1, driver.loc.back()); } {CONFIG_DIR_GEO_DB}[ ]{FREE_TEXT_NEW_LINE} { return yy::seclang_parser::make_CONFIG_DIR_GEO_DB(strchr(yytext, ' ') + 1, *driver.loc.back()); }
%{ /* Request body limit */ %} %{ /* Request body limit */ %}
{CONFIG_DIR_REQ_BODY_LIMIT}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_REQ_BODY_LIMIT(strchr(yytext, ' ') + 1, driver.loc.back()); } {CONFIG_DIR_REQ_BODY_LIMIT}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_REQ_BODY_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_REQ_BODY_LIMIT_ACTION} { return yy::seclang_parser::make_CONFIG_DIR_REQ_BODY_LIMIT_ACTION(yytext, driver.loc.back()); } {CONFIG_DIR_REQ_BODY_LIMIT_ACTION} { return yy::seclang_parser::make_CONFIG_DIR_REQ_BODY_LIMIT_ACTION(yytext, *driver.loc.back()); }
%{ /* Reponse body limit */ %} %{ /* Reponse body limit */ %}
{CONFIG_DIR_RES_BODY_LIMIT}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_RES_BODY_LIMIT(strchr(yytext, ' ') + 1, driver.loc.back()); } {CONFIG_DIR_RES_BODY_LIMIT}[ ]{CONFIG_VALUE_NUMBER} { return yy::seclang_parser::make_CONFIG_DIR_RES_BODY_LIMIT(strchr(yytext, ' ') + 1, *driver.loc.back()); }
{CONFIG_DIR_RES_BODY_LIMIT_ACTION} { return yy::seclang_parser::make_CONFIG_DIR_RES_BODY_LIMIT_ACTION(yytext, driver.loc.back()); } {CONFIG_DIR_RES_BODY_LIMIT_ACTION} { return yy::seclang_parser::make_CONFIG_DIR_RES_BODY_LIMIT_ACTION(yytext, *driver.loc.back()); }
{CONFIG_COMPONENT_SIG}[ ]["]{FREE_TEXT}["] { return yy::seclang_parser::make_CONFIG_COMPONENT_SIG(strchr(yytext, ' ') + 2, driver.loc.back()); } {CONFIG_COMPONENT_SIG}[ ]["]{FREE_TEXT}["] { return yy::seclang_parser::make_CONFIG_COMPONENT_SIG(strchr(yytext, ' ') + 2, *driver.loc.back()); }
{CONFIG_VALUE_WARN} { return yy::seclang_parser::make_CONFIG_VALUE_WARN(yytext, driver.loc.back()); } {CONFIG_VALUE_WARN} { return yy::seclang_parser::make_CONFIG_VALUE_WARN(yytext, *driver.loc.back()); }
{CONFIG_VALUE_ABORT} { return yy::seclang_parser::make_CONFIG_VALUE_ABORT(yytext, driver.loc.back()); } {CONFIG_VALUE_ABORT} { return yy::seclang_parser::make_CONFIG_VALUE_ABORT(yytext, *driver.loc.back()); }
{CONFIG_VALUE_ON} { return yy::seclang_parser::make_CONFIG_VALUE_ON(yytext, driver.loc.back()); } {CONFIG_VALUE_ON} { return yy::seclang_parser::make_CONFIG_VALUE_ON(yytext, *driver.loc.back()); }
{CONFIG_VALUE_OFF} { return yy::seclang_parser::make_CONFIG_VALUE_OFF(yytext, driver.loc.back()); } {CONFIG_VALUE_OFF} { return yy::seclang_parser::make_CONFIG_VALUE_OFF(yytext, *driver.loc.back()); }
{CONFIG_VALUE_SERIAL} { return yy::seclang_parser::make_CONFIG_VALUE_SERIAL(yytext, driver.loc.back()); } {CONFIG_VALUE_SERIAL} { return yy::seclang_parser::make_CONFIG_VALUE_SERIAL(yytext, *driver.loc.back()); }
{CONFIG_VALUE_PARALLEL} { return yy::seclang_parser::make_CONFIG_VALUE_PARALLEL(yytext, driver.loc.back()); } {CONFIG_VALUE_PARALLEL} { return yy::seclang_parser::make_CONFIG_VALUE_PARALLEL(yytext, *driver.loc.back()); }
{CONFIG_VALUE_DETC} { return yy::seclang_parser::make_CONFIG_VALUE_DETC(yytext, driver.loc.back()); } {CONFIG_VALUE_DETC} { return yy::seclang_parser::make_CONFIG_VALUE_DETC(yytext, *driver.loc.back()); }
{CONFIG_VALUE_RELEVANT_ONLY} { return yy::seclang_parser::make_CONFIG_VALUE_RELEVANT_ONLY(yytext, driver.loc.back()); } {CONFIG_VALUE_RELEVANT_ONLY} { return yy::seclang_parser::make_CONFIG_VALUE_RELEVANT_ONLY(yytext, *driver.loc.back()); }
{CONFIG_VALUE_PROCESS_PARTIAL} { return yy::seclang_parser::make_CONFIG_VALUE_PROCESS_PARTIAL(yytext, driver.loc.back()); } {CONFIG_VALUE_PROCESS_PARTIAL} { return yy::seclang_parser::make_CONFIG_VALUE_PROCESS_PARTIAL(yytext, *driver.loc.back()); }
{CONFIG_VALUE_REJECT} { return yy::seclang_parser::make_CONFIG_VALUE_REJECT(yytext, driver.loc.back()); } {CONFIG_VALUE_REJECT} { return yy::seclang_parser::make_CONFIG_VALUE_REJECT(yytext, *driver.loc.back()); }
["]{OPERATOR}[ ]{FREE_TEXT}["] { return yy::seclang_parser::make_OPERATOR(yytext, driver.loc.back()); } ["]{OPERATOR}[ ]{FREE_TEXT}["] { return yy::seclang_parser::make_OPERATOR(yytext, *driver.loc.back()); }
["]{OPERATORNOARG}["] { return yy::seclang_parser::make_OPERATOR(yytext, driver.loc.back()); } ["]{OPERATORNOARG}["] { return yy::seclang_parser::make_OPERATOR(yytext, *driver.loc.back()); }
{ACTION} { return yy::seclang_parser::make_ACTION(yytext, driver.loc.back()); } {ACTION} { return yy::seclang_parser::make_ACTION(yytext, *driver.loc.back()); }
{ACTION_SEVERITY} { return yy::seclang_parser::make_ACTION_SEVERITY(yytext, driver.loc.back()); } {ACTION_SEVERITY} { return yy::seclang_parser::make_ACTION_SEVERITY(yytext, *driver.loc.back()); }
["] { return yy::seclang_parser::make_QUOTATION_MARK(driver.loc.back()); } ["] { return yy::seclang_parser::make_QUOTATION_MARK(*driver.loc.back()); }
[,] { return yy::seclang_parser::make_COMMA(driver.loc.back()); } [,] { return yy::seclang_parser::make_COMMA(*driver.loc.back()); }
[|] { return yy::seclang_parser::make_PIPE(driver.loc.back()); } [|] { return yy::seclang_parser::make_PIPE(*driver.loc.back()); }
{VARIABLENOCOLON} { return yy::seclang_parser::make_VARIABLE(yytext, driver.loc.back()); } {VARIABLENOCOLON} { return yy::seclang_parser::make_VARIABLE(yytext, *driver.loc.back()); }
[ \t]+ { return yy::seclang_parser::make_SPACE(driver.loc.back()); } [ \t]+ { return yy::seclang_parser::make_SPACE(*driver.loc.back()); }
[\n]+ { driver.loc.back().lines(yyleng); driver.loc.back().step(); } [\n]+ { driver.loc.back()->lines(yyleng); driver.loc.back()->step(); }
. { driver.error (driver.loc.back(), "invalid character", yytext); } . { driver.error (*driver.loc.back(), "invalid character", yytext); }
<<EOF>> { <<EOF>> {
if (driver.ref.size() > 0) { if (driver.ref.size() > 0) {
driver.ref.pop_back(); driver.ref.pop_back();
} }
if (driver.loc.size() > 1) { if (driver.loc.size() > 1) {
yy::location *l = driver.loc.back();
driver.loc.pop_back(); driver.loc.pop_back();
delete l;
} }
if (yyin) { if (yyin) {
@ -211,7 +213,7 @@ FREE_TEXT_NEW_LINE [^\"|\n]+
yypop_buffer_state(); yypop_buffer_state();
if (!YY_CURRENT_BUFFER) if (!YY_CURRENT_BUFFER)
{ {
return yy::seclang_parser::make_END(driver.loc.back()); return yy::seclang_parser::make_END(*driver.loc.back());
} }
} }
@ -220,11 +222,11 @@ FREE_TEXT_NEW_LINE [^\"|\n]+
const char *file = strchr(yytext, ' ') + 1; const char *file = strchr(yytext, ' ') + 1;
yyin = fopen(file, "r" ); yyin = fopen(file, "r" );
if (!yyin) { if (!yyin) {
driver.error (driver.loc.back(), "", yytext + std::string(": Not able to open file.")); driver.error (*driver.loc.back(), "", yytext + std::string(": Not able to open file."));
throw yy::seclang_parser::syntax_error(driver.loc.back(), ""); throw yy::seclang_parser::syntax_error(*driver.loc.back(), "");
} }
driver.ref.push_back(file); driver.ref.push_back(file);
driver.loc.push_back(*(new yy::location())); driver.loc.push_back(new yy::location());
yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE )); yypush_buffer_state(yy_create_buffer( yyin, YY_BUF_SIZE ));
} }
@ -238,7 +240,7 @@ FREE_TEXT_NEW_LINE [^\"|\n]+
url = conf[2]; url = conf[2];
driver.ref.push_back(url); driver.ref.push_back(url);
driver.loc.push_back(*(new yy::location())); driver.loc.push_back(new yy::location());
YY_BUFFER_STATE temp = YY_CURRENT_BUFFER; YY_BUFFER_STATE temp = YY_CURRENT_BUFFER;
yypush_buffer_state(temp); yypush_buffer_state(temp);
@ -249,15 +251,15 @@ FREE_TEXT_NEW_LINE [^\"|\n]+
/** TODO: Implement the server logging mechanism. */ /** TODO: Implement the server logging mechanism. */
} }
if (driver.remoteRulesActionOnFailed == Rules::OnFailedRemoteRulesAction::AbortOnFailedRemoteRulesAction) { if (driver.remoteRulesActionOnFailed == Rules::OnFailedRemoteRulesAction::AbortOnFailedRemoteRulesAction) {
driver.error (driver.loc.back(), "", yytext + std::string(" - Failed to download: ") + c.error); driver.error (*driver.loc.back(), "", yytext + std::string(" - Failed to download: ") + c.error);
throw yy::seclang_parser::syntax_error(driver.loc.back(), ""); throw yy::seclang_parser::syntax_error(*driver.loc.back(), "");
} }
} }
yy_scan_string(c.content.c_str()); yy_scan_string(c.content.c_str());
} }
{CONFIG_SEC_REMOTE_RULES_FAIL_ACTION} { return yy::seclang_parser::make_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION(yytext, driver.loc.back()); } {CONFIG_SEC_REMOTE_RULES_FAIL_ACTION} { return yy::seclang_parser::make_CONFIG_SEC_REMOTE_RULES_FAIL_ACTION(yytext, *driver.loc.back()); }
%% %%

View File

@ -30,6 +30,7 @@ Multipart::Multipart(std:: string header)
containsDataBefore(false), containsDataBefore(false),
lf(false), lf(false),
missingSemicolon(false), missingSemicolon(false),
invalidQuote(false),
boundaryStartsWithWhiteSpace(false), boundaryStartsWithWhiteSpace(false),
boundaryIsQuoted(false), boundaryIsQuoted(false),
m_header(header) { m_header(header) {

View File

@ -34,27 +34,55 @@ using operators::Operator;
using actions::Action; using actions::Action;
using Variables::Variable; using Variables::Variable;
Rule::~Rule() {
delete op;
while (actions_conf.empty() == false) {
auto *a = actions_conf.back();
actions_conf.pop_back();
delete a;
}
while (actions_runtime_pre.empty() == false) {
auto *a = actions_runtime_pre.back();
actions_runtime_pre.pop_back();
delete a;
}
while (actions_runtime_pos.empty() == false) {
auto *a = actions_runtime_pos.back();
actions_runtime_pos.pop_back();
delete a;
}
while (variables->empty() == false) {
auto *a = variables->back();
variables->pop_back();
delete a;
}
delete variables;
}
Rule::Rule(Operator *_op, Rule::Rule(Operator *_op,
std::vector<Variable *> *_variables, std::vector<Variable *> *_variables,
std::vector<Action *> *_actions) std::vector<Action *> *actions)
: chained(false), : chained(false),
chainedRule(NULL), chainedRule(NULL),
variables(_variables), variables(_variables),
op(_op), op(_op),
rule_id(0), rule_id(0),
phase(-1) { phase(-1),
for (Action *a : *_actions) { m_referenceCount(0) {
for (Action *a : *actions) {
if (a->action_kind == Action::ConfigurationKind) { if (a->action_kind == Action::ConfigurationKind) {
actions_conf.push_back(a); actions_conf.push_back(a);
a->evaluate(this); a->evaluate(this);
} } else if (a->action_kind == Action::RunTimeBeforeMatchAttemptKind) {
if (a->action_kind == Action::RunTimeBeforeMatchAttemptKind) {
actions_runtime_pre.push_back(a); actions_runtime_pre.push_back(a);
} } else if (a->action_kind == Action::RunTimeOnlyIfMatchKind) {
if (a->action_kind == Action::RunTimeOnlyIfMatchKind) {
actions_runtime_pos.push_back(a); actions_runtime_pos.push_back(a);
} else {
std::cout << "General failure, action: " << a->name;
std::cout << " has an unknown type." << std::endl;
delete a;
} }
} }
/** /**
@ -64,6 +92,8 @@ Rule::Rule(Operator *_op,
if (phase == -1) { if (phase == -1) {
phase = ModSecurity::Phases::RequestHeadersPhase; phase = ModSecurity::Phases::RequestHeadersPhase;
} }
delete actions;
} }
bool Rule::evaluate(Assay *assay) { bool Rule::evaluate(Assay *assay) {
@ -115,7 +145,8 @@ bool Rule::evaluate(Assay *assay) {
a->evaluate(assay); a->evaluate(assay);
} }
if (this->chained && this->chainedRule == NULL) { if (this->chained && this->chainedRule == NULL) {
assay->debug(4, "Rule is marked as chained but there isn't a subsequent rule."); assay->debug(4, "Rule is marked as chained but there " \
"isn't a subsequent rule.");
} }
if (this->chained && this->chainedRule != NULL) { if (this->chained && this->chainedRule != NULL) {
assay->debug(4, "Executing chained rule."); assay->debug(4, "Executing chained rule.");

View File

@ -34,6 +34,7 @@ class Rule {
std::vector<Variables::Variable *> *_variables, std::vector<Variables::Variable *> *_variables,
std::vector<actions::Action *> *_actions); std::vector<actions::Action *> *_actions);
~Rule();
bool evaluate(Assay *assay); bool evaluate(Assay *assay);
operators::Operator *op; operators::Operator *op;
@ -47,6 +48,20 @@ class Rule {
Rule *chainedRule; Rule *chainedRule;
bool chained; bool chained;
void refCountDecreaseAndCheck() {
this->m_referenceCount--;
if (this->m_referenceCount == 0) {
delete this;
}
}
void refCountIncrease() {
this->m_referenceCount++;
}
private:
int m_referenceCount;
}; };
} // namespace ModSecurity } // namespace ModSecurity

View File

@ -78,7 +78,19 @@ void Rules::decrementReferenceCount(void) {
Rules::~Rules() { Rules::~Rules() {
// audit_log->refCountDecreaseAndCheck(); /** Cleanup the rules */
for (int i = 0; i < ModSecurity::Phases::NUMBER_OF_PHASES; i++) {
std::vector<Rule *> rules = this->rules[i];
while (rules.empty() == false) {
Rule *rule = rules.back();
rule->refCountDecreaseAndCheck();
rules.pop_back();
}
}
/** Cleanup audit log */
audit_log->refCountDecreaseAndCheck();
/** Cleanup debug log */
debugLog->refCountDecreaseAndCheck();
} }
@ -171,6 +183,7 @@ int Rules::merge(Driver *from) {
for (int j = 0; j < rules.size(); j++) { for (int j = 0; j < rules.size(); j++) {
Rule *rule = rules[j]; Rule *rule = rules[j];
this->rules[i].push_back(rule); this->rules[i].push_back(rule);
rule->refCountIncrease();
} }
} }
@ -192,8 +205,10 @@ int Rules::merge(Driver *from) {
} else { } else {
this->debugLog = new DebugLog(); this->debugLog = new DebugLog();
} }
this->debugLog->refCountIncrease();
this->audit_log = from->audit_log; this->audit_log = from->audit_log;
this->audit_log->refCountIncrease();
this->debugLog->setDebugLevel(this->debug_level); this->debugLog->setDebugLevel(this->debug_level);
this->debugLog->setOutputFile(this->debug_log_path); this->debugLog->setOutputFile(this->debug_log_path);
@ -208,6 +223,7 @@ int Rules::merge(Rules *from) {
for (int j = 0; j < rules.size(); j++) { for (int j = 0; j < rules.size(); j++) {
Rule *rule = rules[j]; Rule *rule = rules[j];
this->rules[i].push_back(rule); this->rules[i].push_back(rule);
rule->refCountIncrease();
} }
} }
@ -227,8 +243,10 @@ int Rules::merge(Rules *from) {
} else { } else {
this->debugLog = new DebugLog(); this->debugLog = new DebugLog();
} }
this->debugLog->refCountIncrease();
this->audit_log = from->audit_log; this->audit_log = from->audit_log;
this->audit_log->refCountIncrease();
this->debugLog->setDebugLevel(this->debug_level); this->debugLog->setDebugLevel(this->debug_level);
this->debugLog->setOutputFile(this->debug_log_path); this->debugLog->setOutputFile(this->debug_log_path);

View File

@ -30,8 +30,20 @@ namespace ModSecurity {
namespace Utils { namespace Utils {
bool GeoLookup::setDataBase(std::string file_path) { GeoLookup::~GeoLookup() {
m_gi = GeoIP_open(file_path.c_str(), GEOIP_INDEX_CACHE); cleanUp();
}
void GeoLookup::cleanUp() {
if (m_gi != NULL) {
GeoIP_delete(m_gi);
m_gi = NULL;
}
}
bool GeoLookup::setDataBase(const std::string& filePath) {
m_gi = GeoIP_open(filePath.c_str(), GEOIP_INDEX_CACHE);
if (m_gi == NULL) { if (m_gi == NULL) {
return false; return false;

View File

@ -36,13 +36,15 @@ class GeoLookup {
return instance; return instance;
} }
bool setDataBase(std::string file_path); bool setDataBase(const std::string& filePath);
bool lookup(const std::string& target, GeoIPRecord **georec, bool lookup(const std::string& target, GeoIPRecord **georec,
std::function<bool(int, std::string)> callback); std::function<bool(int, std::string)> callback);
void cleanUp();
private: private:
GeoLookup() : m_gi(NULL) {} GeoLookup()
: m_gi(NULL) { }
~GeoLookup();
GeoLookup(GeoLookup const&); GeoLookup(GeoLookup const&);
void operator=(GeoLookup const&); void operator=(GeoLookup const&);

View File

@ -40,12 +40,17 @@ std::list<std::pair<std::string, std::string>>
std::map<std::string, std::string> envs; std::map<std::string, std::string> envs;
for (char **current = environ; *current; current++) { for (char **current = environ; *current; current++) {
std::string env = std::string(*current); std::string env = std::string(*current);
std::vector<std::string> key_value = split(env, '='); size_t pos = env.find_first_of("=");
envs.insert(std::pair<std::string, std::string>("ENV:" + key_value[0], if (pos == std::string::npos) {
key_value[1])); continue;
if ("env:" + key_value[0] == name) { }
std::string key = std::string(env, 0, pos);
std::string value = std::string(env, pos+1, env.length() - (pos + 1));
envs.insert(std::pair<std::string, std::string>("ENV:" + key, value));
if ("env:" + key == name) {
std::pair<std::string, std::string> pair; std::pair<std::string, std::string> pair;
pair = std::make_pair(name, key_value[1]); pair = std::make_pair(name, value);
resl.push_back(pair); resl.push_back(pair);
return resl; return resl;
} }

View File

@ -72,6 +72,7 @@ int main(int argc, char *argv[]) {
int i = 0; int i = 0;
ModSecurity::ModSecurity *modsec; ModSecurity::ModSecurity *modsec;
ModSecurity::Rules *rules; ModSecurity::Rules *rules;
ModSecurity::ModSecurityIntervention it;
modsec = new ModSecurity::ModSecurity(); modsec = new ModSecurity::ModSecurity();
modsec->setConnectorInformation("ModSecurity-benchmark v0.0.1-alpha" \ modsec->setConnectorInformation("ModSecurity-benchmark v0.0.1-alpha" \
@ -86,12 +87,12 @@ int main(int argc, char *argv[]) {
Assay *modsecAssay = new Assay(modsec, rules); Assay *modsecAssay = new Assay(modsec, rules);
modsecAssay->processConnection(ip, 12345, "127.0.0.1", 80); modsecAssay->processConnection(ip, 12345, "127.0.0.1", 80);
if (modsecAssay->intervention()) { if (modsecAssay->intervention(&it)) {
std::cout << "There is an intervention" << std::endl; std::cout << "There is an intervention" << std::endl;
continue; continue;
} }
modsecAssay->processURI(request_uri, "GET", "1.1"); modsecAssay->processURI(request_uri, "GET", "1.1");
if (modsecAssay->intervention()) { if (modsecAssay->intervention(&it)) {
std::cout << "There is an intervention" << std::endl; std::cout << "There is an intervention" << std::endl;
continue; continue;
} }
@ -122,7 +123,7 @@ int main(int argc, char *argv[]) {
"no-cache"); "no-cache");
modsecAssay->processRequestHeaders(); modsecAssay->processRequestHeaders();
if (modsecAssay->intervention()) { if (modsecAssay->intervention(&it)) {
std::cout << "There is an intervention" << std::endl; std::cout << "There is an intervention" << std::endl;
continue; continue;
} }
@ -130,7 +131,7 @@ int main(int argc, char *argv[]) {
modsecAssay->processRequestBody(); modsecAssay->processRequestBody();
if (modsecAssay->intervention()) { if (modsecAssay->intervention(&it)) {
std::cout << "There is an intervention" << std::endl; std::cout << "There is an intervention" << std::endl;
continue; continue;
} }
@ -144,7 +145,7 @@ int main(int argc, char *argv[]) {
modsecAssay->processResponseHeaders(); modsecAssay->processResponseHeaders();
if (modsecAssay->intervention()) { if (modsecAssay->intervention(&it)) {
std::cout << "There is an intervention" << std::endl; std::cout << "There is an intervention" << std::endl;
continue; continue;
} }
@ -154,7 +155,7 @@ int main(int argc, char *argv[]) {
strlen((const char*)response_body)); strlen((const char*)response_body));
modsecAssay->processResponseBody(); modsecAssay->processResponseBody();
if (modsecAssay->intervention()) { if (modsecAssay->intervention(&it)) {
std::cout << "There is an intervention" << std::endl; std::cout << "There is an intervention" << std::endl;
continue; continue;
} }

View File

@ -85,11 +85,13 @@ bool ModSecurityTest<T>::load_test_json(std::string file) {
vec->push_back(u); vec->push_back(u);
} }
} }
yajl_tree_free(node);
return true; return true;
} }
template <class T> template <class T>
std::pair<std::string, std::vector<T *>>* ModSecurityTest<T>::load_tests() { std::pair<std::string, std::vector<T *>>* ModSecurityTest<T>::load_tests() {
DIR *dir; DIR *dir;

View File

@ -44,16 +44,19 @@ void print_help() {
void actions(ModSecurityTestResults<RegressionTest> *r, void actions(ModSecurityTestResults<RegressionTest> *r,
ModSecurity::ModSecurityIntervention *it) { ModSecurity::Assay *a) {
if (it != NULL) { ModSecurity::ModSecurityIntervention it;
if (it->pause != 0) { memset(&it, '\0', sizeof(ModSecurity::ModSecurityIntervention));
it.status = 200;
if (a->intervention(&it) == true) {
if (it.pause != 0) {
// FIXME: // FIXME:
} }
if (it->status != 0) { if (it.status != 0) {
r->status = it->status; r->status = it.status;
} }
if (it->url != NULL) { if (it.url != NULL) {
r->location = it->url; r->location = it.url;
} }
} }
} }
@ -61,13 +64,13 @@ void actions(ModSecurityTestResults<RegressionTest> *r,
void perform_unit_test(std::vector<RegressionTest *> *tests, void perform_unit_test(std::vector<RegressionTest *> *tests,
ModSecurityTestResults<RegressionTest> *res, int *count) { ModSecurityTestResults<RegressionTest> *res, int *count) {
ModSecurity::ModSecurity *modsec;
ModSecurity::Rules *modsec_rules;
ModSecurity::Assay *modsec_assay;
CustomDebugLog *debug_log = new CustomDebugLog(); CustomDebugLog *debug_log = new CustomDebugLog();
for (RegressionTest *t : *tests) { for (RegressionTest *t : *tests) {
ModSecurity::ModSecurity *modsec = NULL;
ModSecurity::Rules *modsec_rules = NULL;
ModSecurity::Assay *modsec_assay = NULL;
ModSecurityTestResults<RegressionTest> r; ModSecurityTestResults<RegressionTest> r;
r.status = 200; r.status = 200;
(*count)++; (*count)++;
@ -123,7 +126,7 @@ void perform_unit_test(std::vector<RegressionTest *> *tests,
modsec_assay->processConnection(t->clientIp.c_str(), modsec_assay->processConnection(t->clientIp.c_str(),
t->clientPort, t->serverIp.c_str(), t->serverPort); t->clientPort, t->serverIp.c_str(), t->serverPort);
actions(&r, modsec_assay->intervention()); actions(&r, modsec_assay);
if (r.status != 200) { if (r.status != 200) {
goto end; goto end;
} }
@ -131,7 +134,7 @@ void perform_unit_test(std::vector<RegressionTest *> *tests,
modsec_assay->processURI(t->uri.c_str(), t->protocol.c_str(), modsec_assay->processURI(t->uri.c_str(), t->protocol.c_str(),
t->httpVersion.c_str()); t->httpVersion.c_str());
actions(&r, modsec_assay->intervention()); actions(&r, modsec_assay);
if (r.status != 200) { if (r.status != 200) {
goto end; goto end;
} }
@ -143,7 +146,7 @@ void perform_unit_test(std::vector<RegressionTest *> *tests,
} }
modsec_assay->processRequestHeaders(); modsec_assay->processRequestHeaders();
actions(&r, modsec_assay->intervention()); actions(&r, modsec_assay);
if (r.status != 200) { if (r.status != 200) {
goto end; goto end;
} }
@ -152,7 +155,7 @@ void perform_unit_test(std::vector<RegressionTest *> *tests,
(unsigned char *)t->request_body.c_str(), (unsigned char *)t->request_body.c_str(),
t->request_body.size()); t->request_body.size());
modsec_assay->processRequestBody(); modsec_assay->processRequestBody();
actions(&r, modsec_assay->intervention()); actions(&r, modsec_assay);
if (r.status != 200) { if (r.status != 200) {
goto end; goto end;
} }
@ -164,7 +167,7 @@ void perform_unit_test(std::vector<RegressionTest *> *tests,
} }
modsec_assay->processResponseHeaders(); modsec_assay->processResponseHeaders();
actions(&r, modsec_assay->intervention()); actions(&r, modsec_assay);
if (r.status != 200) { if (r.status != 200) {
goto end; goto end;
} }
@ -173,7 +176,7 @@ void perform_unit_test(std::vector<RegressionTest *> *tests,
(unsigned char *)t->response_body.c_str(), (unsigned char *)t->response_body.c_str(),
t->response_body.size()); t->response_body.size());
modsec_assay->processResponseBody(); modsec_assay->processResponseBody();
actions(&r, modsec_assay->intervention()); actions(&r, modsec_assay);
if (r.status != 200) { if (r.status != 200) {
goto end; goto end;
} }
@ -208,6 +211,8 @@ after_debug_log:
res->insert(res->end(), r.begin(), r.end()); res->insert(res->end(), r.begin(), r.end());
} }
delete debug_log;
} }
@ -241,7 +246,7 @@ int main(int argc, char **argv) {
} }
keyList.sort(); keyList.sort();
for (std::string a : keyList) { for (std::string &a : keyList) {
std::vector<RegressionTest *> *tests = test[a]; std::vector<RegressionTest *> *tests = test[a];
ModSecurityTestResults<RegressionTest> res; ModSecurityTestResults<RegressionTest> res;
@ -251,8 +256,13 @@ int main(int argc, char **argv) {
} }
test_log.close(); test_log.close();
for (std::pair<std::string, std::vector<RegressionTest *> *> a : test) {
std::vector<RegressionTest *> *vec = a.second;
for (int i = 0; i < vec->size(); i++) {
delete vec->at(i);
}
delete vec;
}
return 0; return 0;
} }

View File

@ -0,0 +1,76 @@
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:_Znwm
fun:_ZN2yy14seclang_parser5parseEv
fun:_ZN11ModSecurity6Parser6Driver5parseERKSsS3_
fun:_ZN11ModSecurity5Rules4loadEPKcRKSs
fun:_Z17perform_unit_testPSt6vectorIPN16modsecurity_test14RegressionTestESaIS2_EEPNS0_22ModSecurityTestResultsIS1_EEPi
fun:main
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
fun:yyalloc
fun:_Z14yy_scan_bufferPcm
fun:_Z13yy_scan_bytesPKcm
fun:_ZN11ModSecurity6Parser6Driver10scan_beginEv
fun:_ZN11ModSecurity6Parser6Driver5parseERKSsS3_
fun:_ZN11ModSecurity5Rules4loadEPKcRKSs
fun:_Z17perform_unit_testPSt6vectorIPN16modsecurity_test14RegressionTestESaIS2_EEPNS0_22ModSecurityTestResultsIS1_EEPi
fun:main
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:_Znwm
fun:_Z17perform_unit_testPSt6vectorIPN16modsecurity_test14RegressionTestESaIS2_EEPNS0_22ModSecurityTestResultsIS1_EEPi
fun:main
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:_Znwm
fun:_Z17perform_unit_testPSt6vectorIPN16modsecurity_test14RegressionTestESaIS2_EEPNS0_22ModSecurityTestResultsIS1_EEPi
fun:main
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:_Znwm
fun:_ZN11ModSecurity5Rules4loadEPKcRKSs
fun:_Z17perform_unit_testPSt6vectorIPN16modsecurity_test14RegressionTestESaIS2_EEPNS0_22ModSecurityTestResultsIS1_EEPi
fun:main
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:malloc
fun:yyalloc
fun:_Z16yy_create_bufferP8_IO_FILEi
fun:_Z5yylexRN11ModSecurity6Parser6DriverE
fun:_ZN2yy14seclang_parser5parseEv
fun:_ZN11ModSecurity6Parser6Driver5parseERKSsS3_
fun:_ZN11ModSecurity5Rules4loadEPKcRKSs
fun:_Z17perform_unit_testPSt6vectorIPN16modsecurity_test14RegressionTestESaIS2_EEPNS0_22ModSecurityTestResultsIS1_EEPi
fun:main
}
{
<insert_a_suppression_name_here>
Memcheck:Leak
match-leak-kinds: definite
fun:_Znwm
fun:_ZN11ModSecurity8AuditLog4initEv
fun:_ZN11ModSecurity6Parser6Driver5parseERKSsS3_
fun:_ZN11ModSecurity5Rules4loadEPKcRKSs
fun:_Z17perform_unit_testPSt6vectorIPN16modsecurity_test14RegressionTestESaIS2_EEPNS0_22ModSecurityTestResultsIS1_EEPi
fun:main
}