Adds support to ctl:auditLogParts variation

This commit is contained in:
Felipe Zimmerle 2015-09-01 15:17:53 -03:00
parent e89e395a32
commit fa4f72d90d
12 changed files with 221 additions and 20 deletions

View File

@ -263,6 +263,7 @@ class Assay {
std::list<std::string> rulesMessages;
std::list<std::string> ruleTags;
std::list<std::pair<int, std::string>> auditLogModifier;
private:
std::ofstream myfile;
ModSecurity *m_ms;

View File

@ -56,6 +56,7 @@ ACTIONS = \
actions/block.cc \
actions/capture.cc \
actions/chain.cc \
actions/ctl_audit_log_parts.cc \
actions/log_data.cc \
actions/msg.cc \
actions/no_audit_log.cc \

View File

@ -0,0 +1,45 @@
/*
* ModSecurity, http://www.modsecurity.org/
* Copyright (c) 2015 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 "actions/ctl_audit_log_parts.h"
#include <iostream>
#include <string>
#include "modsecurity/assay.h"
namespace ModSecurity {
namespace actions {
CtlAuditLogParts::CtlAuditLogParts(std::string action)
: Action(action, RunTimeOnlyIfMatchKind),
mPartsAction(0)
{
std::string what(action, 18, 1);
mParts = std::string(action, 19, action.length()-19);
if (what == "+") {
mPartsAction = 0;
} else {
mPartsAction = 1;
}
}
bool CtlAuditLogParts::evaluate(Rule *rule, Assay *assay) {
assay->auditLogModifier.push_back(std::make_pair(mPartsAction, mParts));
return true;
}
} // namespace actions
} // namespace ModSecurity

View File

@ -0,0 +1,40 @@
/*
* ModSecurity, http://www.modsecurity.org/
* Copyright (c) 2015 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 "actions/action.h"
#include "modsecurity/assay.h"
#ifndef SRC_CLT_ACTIONS_AUDIT_LOG_PARTS_H_
#define SRC_CLT_ACTIONS_AUDIT_LOG_PARTS_H_
namespace ModSecurity {
namespace actions {
class CtlAuditLogParts : public Action {
public:
explicit CtlAuditLogParts(std::string action);
bool evaluate(Rule *rule, Assay *assay) override;
int mPartsAction;
std::string mParts;
};
} // namespace actions
} // namespace ModSecurity
#endif // SRC_CLT_ACTIONS_AUDIT_LOG_PARTS_H_

View File

@ -962,7 +962,31 @@ int Assay::processLogging(int returned_code) {
/* If relevant, save this assay information at the audit_logs */
if (m_rules != NULL && m_rules->audit_log != NULL) {
this->m_rules->audit_log->saveIfRelevant(this);
debug(8, "Checking if this request is suitable to be saved as an audit log.");
int parts = -1;
if (this->auditLogModifier.size() > 0)
{
debug(4, "There was an audit log modifier for this transaction.");
std::list<std::pair<int, std::string>>::iterator it;
parts = this->m_rules->audit_log->m_parts;
for (it = auditLogModifier.begin(); it != auditLogModifier.end(); ++it) {
std::pair <int, std::string> p = *it;
if (p.first == 0) { // Add
parts = this->m_rules->audit_log->addParts(parts, p.second);
} else { // Remove
parts = this->m_rules->audit_log->removeParts(parts, p.second);
}
}
}
if (save_in_auditlog) {
debug(8, "This request was marked to be saved via auditlog action.");
}
bool saved = this->m_rules->audit_log->saveIfRelevant(this, parts);
if (saved) {
debug(8, "Request was relevant to be saved.");
}
}
return 0;

View File

@ -28,7 +28,13 @@
#define PARTS_CONSTAINS(a, c) \
if (new_parts.find(toupper(a)) != std::string::npos \
|| new_parts.find(tolower(a)) != std::string::npos) { \
this->m_parts = this->m_parts | c; \
parts = parts | c; \
}
#define PARTS_CONSTAINS_REM(a, c) \
if (new_parts.find(toupper(a)) != std::string::npos \
|| new_parts.find(tolower(a)) != std::string::npos) { \
parts = parts & ~c; \
}
namespace ModSecurity {
@ -84,7 +90,7 @@ bool AuditLog::setStatus(AuditLogStatus new_status) {
bool AuditLog::setRelevantStatus(const std::basic_string<char>& status) {
this->m_relevant = status;
this->m_relevant = std::string(status);
return true;
}
@ -107,7 +113,7 @@ bool AuditLog::setFilePath2(const std::basic_string<char>& path) {
}
bool AuditLog::setParts(const std::basic_string<char>& new_parts) {
int AuditLog::addParts(int parts, const std::string& new_parts) {
PARTS_CONSTAINS('A', AAuditLogPart)
PARTS_CONSTAINS('B', BAuditLogPart)
PARTS_CONSTAINS('C', CAuditLogPart)
@ -121,6 +127,45 @@ bool AuditLog::setParts(const std::basic_string<char>& new_parts) {
PARTS_CONSTAINS('K', KAuditLogPart)
PARTS_CONSTAINS('Z', ZAuditLogPart)
return parts;
}
int AuditLog::removeParts(int parts, const std::string& new_parts) {
PARTS_CONSTAINS_REM('A', AAuditLogPart)
PARTS_CONSTAINS_REM('B', BAuditLogPart)
PARTS_CONSTAINS_REM('C', CAuditLogPart)
PARTS_CONSTAINS_REM('D', DAuditLogPart)
PARTS_CONSTAINS_REM('E', EAuditLogPart)
PARTS_CONSTAINS_REM('F', FAuditLogPart)
PARTS_CONSTAINS_REM('G', GAuditLogPart)
PARTS_CONSTAINS_REM('H', HAuditLogPart)
PARTS_CONSTAINS_REM('I', IAuditLogPart)
PARTS_CONSTAINS_REM('J', JAuditLogPart)
PARTS_CONSTAINS_REM('K', KAuditLogPart)
PARTS_CONSTAINS_REM('Z', ZAuditLogPart)
return parts;
}
bool AuditLog::setParts(const std::basic_string<char>& new_parts) {
int parts = m_parts;
PARTS_CONSTAINS('A', AAuditLogPart)
PARTS_CONSTAINS('B', BAuditLogPart)
PARTS_CONSTAINS('C', CAuditLogPart)
PARTS_CONSTAINS('D', DAuditLogPart)
PARTS_CONSTAINS('E', EAuditLogPart)
PARTS_CONSTAINS('F', FAuditLogPart)
PARTS_CONSTAINS('G', GAuditLogPart)
PARTS_CONSTAINS('H', HAuditLogPart)
PARTS_CONSTAINS('I', IAuditLogPart)
PARTS_CONSTAINS('J', JAuditLogPart)
PARTS_CONSTAINS('K', KAuditLogPart)
PARTS_CONSTAINS('Z', ZAuditLogPart)
m_parts = parts;
return true;
}
@ -165,15 +210,24 @@ bool AuditLog::isRelevant(int status) {
return false;
}
if (sstatus.empty()) {
return true;
}
return Utils::regex_search(sstatus,
Utils::Regex(m_relevant)) != 0;
}
bool AuditLog::saveIfRelevant(Assay *assay) {
return saveIfRelevant(assay, -1);
}
bool AuditLog::saveIfRelevant(Assay *assay, int parts) {
if (this->isRelevant(assay->httpCodeReturned) == false &&
assay->save_in_auditlog == false) {
return true;
return false;
}
/**
@ -182,10 +236,14 @@ bool AuditLog::saveIfRelevant(Assay *assay) {
*
*/
if (assay->do_not_save_in_auditlog == true) {
return true;
return false;
}
m_writer->write(assay, m_parts);
if (parts == -1)
{
parts = m_parts;
}
m_writer->write(assay, parts);
return true;
}

View File

@ -154,8 +154,12 @@ class AuditLog {
bool close();
bool saveIfRelevant(Assay *assay);
bool saveIfRelevant(Assay *assay, int parts);
bool isRelevant(int status);
int addParts(int parts, const std::string& new_parts);
int removeParts(int parts, const std::string& new_parts);
std::string m_path1;
std::string m_path2;
std::string m_storage_dir;
@ -163,11 +167,12 @@ class AuditLog {
int filePermission;
int directoryPermission;
private:
int m_parts;
private:
AuditLogStatus m_status;
int m_parts;
AuditLogType m_type;
std::string m_relevant;

View File

@ -25,7 +25,7 @@ namespace ModSecurity {
AuditLogWriterSerial::~AuditLogWriterSerial() {
log.close();
m_log.close();
}
@ -42,7 +42,7 @@ void AuditLogWriterSerial::generateBoundary(std::string *boundary) {
bool AuditLogWriterSerial::init() {
log.open(m_audit->m_path1, std::fstream::out | std::fstream::app);
m_log.open(m_audit->m_path1, std::fstream::out | std::fstream::app);
return true;
}
@ -53,8 +53,12 @@ bool AuditLogWriterSerial::write(Assay *assay, int parts) {
generateBoundary(&boundary);
// serialLoggingMutex.lock();
log << assay->toOldAuditLogFormat(parts, "-" + boundary + "--");
m_log << assay->toOldAuditLogFormat(parts, "-" + boundary + "--");
m_log.flush();
// serialLoggingMutex.unlock();
return true;
}

View File

@ -45,17 +45,23 @@ class AuditLogWriterSerial : public AuditLogWriter {
void refCountDecreaseAndCheck() override {
/*
m_refereceCount--;
if (m_refereceCount == 0) {
delete this;
}
*/
delete this;
/*
/}
*/
}
bool init() override;;
bool write(Assay *assay, int parts) override;
private:
std::ofstream log;
std::ofstream m_log;
void generateBoundary(std::string *boundary);
};

View File

@ -28,10 +28,14 @@ Driver::Driver()
: trace_scanning(false),
trace_parsing(false) {
audit_log = new AuditLog();
audit_log->refCountIncrease();
}
Driver::~Driver() {
if (audit_log != NULL) {
audit_log->refCountDecreaseAndCheck();
}
delete loc.back();
}

View File

@ -18,6 +18,7 @@ class Driver;
#include "actions/action.h"
#include "actions/audit_log.h"
#include "actions/ctl_audit_log_parts.h"
#include "actions/set_var.h"
#include "actions/severity.h"
#include "actions/msg.h"
@ -47,6 +48,7 @@ class Driver;
#include "variables/time_year.h"
using ModSecurity::actions::Action;
using ModSecurity::actions::CtlAuditLogParts;
using ModSecurity::actions::SetVar;
using ModSecurity::actions::Severity;
using ModSecurity::actions::Tag;
@ -653,8 +655,7 @@ act:
}
| ACTION_CTL_AUDIT_LOG_PARTS
{
/* not ready yet. */
$$ = Action::instantiate($1);
$$ = new CtlAuditLogParts($1);
}
;

View File

@ -209,8 +209,15 @@ int Rules::merge(Driver *from) {
this->responseBodyLimitAction = from->responseBodyLimitAction;
this->audit_log = from->audit_log;
this->audit_log->refCountIncrease();
if (from->audit_log != NULL && this->audit_log != NULL) {
this->audit_log->refCountDecreaseAndCheck();
}
if (from->audit_log) {
this->audit_log = from->audit_log;
}
if (this->audit_log != NULL) {
this->audit_log->refCountIncrease();
}
return amount_of_rules;
}
@ -247,7 +254,12 @@ int Rules::merge(Rules *from) {
from->m_debugLog->getDebugLogLevel());
}
this->audit_log = from->audit_log;
if (from->audit_log != NULL && this->audit_log != NULL) {
this->audit_log->refCountDecreaseAndCheck();
}
if (from->audit_log) {
this->audit_log = from->audit_log;
}
if (this->audit_log != NULL) {
this->audit_log->refCountIncrease();
}