DebugLogs are now being redirected to the correct files

This commit is contained in:
Felipe Zimmerle 2015-08-27 01:27:34 -03:00
parent 01542e28c3
commit 24b7d72666
14 changed files with 330 additions and 177 deletions

View File

@ -14,8 +14,6 @@
*/
#ifdef __cplusplus
#include <iostream>
#include <fstream>
#include <string>
#endif
@ -32,39 +30,25 @@ typedef struct DebugLog_t DebugLog;
namespace ModSecurity {
/** @ingroup ModSecurity_CPP_API */
class DebugLog : public std::ofstream {
class DebugLog {
public:
/*
static ModSecurityDebugLog& instance() {
static ModSecurityDebugLog i;
return i;
}
*/
DebugLog()
: m_is_configured(false),
m_debug_level(0),
m_referenceCount(0) { }
: m_debugLevel(-1),
m_fileName("") { }
bool setOutputFile(const std::string& file);
virtual bool write_log(int level, const std::string& data);
bool setDebugLevel(int level);
bool isConfigured();
~DebugLog();
virtual DebugLog *new_instance();
void refCountDecreaseAndCheck(void);
void refCountIncrease(void);
virtual void write(int level, const std::string &msg);
bool isLogFileSet();
bool isLogLevelSet();
void setDebugLogLevel(int level);
void setDebugLogFile(const std::string &fileName);
const std::string& getDebugLogFile();
int getDebugLogLevel();
private:
/*
ModSecurityDebugLog(ModSecurityDebugLog const&);
void operator=(ModSecurityDebugLog const&);
*/
int m_debug_level;
bool m_is_configured;
int m_referenceCount;
int m_debugLevel;
std::string m_fileName;
};
} // namespace ModSecurity

View File

@ -45,8 +45,7 @@ class Driver;
class Rules : public RulesProperties {
public:
Rules()
: debugLog(NULL),
RulesProperties(NULL),
: RulesProperties(new DebugLog()),
m_referenceCount(0),
unicode_codepage(0) {
unicode_map_table = reinterpret_cast<int *>(
@ -55,8 +54,7 @@ class Rules : public RulesProperties {
}
explicit Rules(DebugLog *customLog)
: debugLog(NULL),
m_referenceCount(0),
: m_referenceCount(0),
unicode_codepage(0),
RulesProperties(customLog) {
unicode_map_table = reinterpret_cast<int *>(
@ -86,7 +84,6 @@ class Rules : public RulesProperties {
std::ostringstream parserError;
DebugLog *debugLog;
int *unicode_map_table;
int64_t unicode_codepage;

View File

@ -42,7 +42,7 @@ class RulesProperties {
public:
RulesProperties()
: audit_log(NULL),
customDebugLog(NULL),
m_debugLog(new DebugLog()),
remoteRulesActionOnFailed(AbortOnFailedRemoteRulesAction),
requestBodyLimit(0),
requestBodyNoFilesLimit(0),
@ -51,26 +51,25 @@ class RulesProperties {
secResponseBodyAccess(false),
requestBodyLimitAction(ProcessPartialBodyLimitAction),
responseBodyLimit(0),
debugLevel(0),
responseBodyLimitAction(ProcessPartialBodyLimitAction),
secRuleEngine(DetectionOnlyRuleEngine) { }
explicit RulesProperties(DebugLog *customDebugLog)
explicit RulesProperties(DebugLog *debugLog)
: audit_log(NULL),
customDebugLog(customDebugLog),
m_debugLog(debugLog),
remoteRulesActionOnFailed(AbortOnFailedRemoteRulesAction),
secRequestBodyAccess(false),
secResponseBodyAccess(false),
debugLevel(0),
requestBodyLimit(0),
requestBodyLimitAction(ProcessPartialBodyLimitAction),
requestBodyNoFilesLimit(0),
requestBodyInMemoryLimit(0),
secRequestBodyAccess(false),
secResponseBodyAccess(false),
requestBodyLimitAction(ProcessPartialBodyLimitAction),
responseBodyLimit(0),
responseBodyLimitAction(ProcessPartialBodyLimitAction),
secRuleEngine(DetectionOnlyRuleEngine) { }
~RulesProperties() { }
~RulesProperties() {
delete m_debugLog;
}
std::vector<Rule *> rules[7]; // ModSecurity::Phases::NUMBER_OF_PHASES
@ -167,16 +166,13 @@ class RulesProperties {
BodyLimitAction requestBodyLimitAction;
BodyLimitAction responseBodyLimitAction;
DebugLog *customDebugLog;
bool secRequestBodyAccess;
bool secResponseBodyAccess;
std::string audit_log_path;
std::string audit_log_parts;
std::string debug_log_path;
int debugLevel;
std::list<std::string> components;
DebugLog *m_debugLog;
std::ostringstream parserError;

View File

@ -169,6 +169,8 @@ libmodsecurity_la_SOURCES = \
rules.cc \
utils.cc \
debug_log.cc \
debug_log_writer.cc \
debug_log_writer_agent.cc \
macro_expansion.cc \
request_body_processor/multipart.cc \
request_body_processor/multipart_blob.cc \

View File

@ -19,122 +19,60 @@
#include <fstream>
#include "src/debug_log_writer.h"
#include "src/debug_log_writer_agent.h"
namespace ModSecurity {
/**
* @name new_instance
* @brief Create a new instance of the DebugLog.
*
* @return Debug log pointer
* @retval >0 Debug log structure was initialized correctly
* @retval NULL Debug log could not be initialized.
*
*/
DebugLog *DebugLog::new_instance() {
return new DebugLog();
DebugLog::~DebugLog() {
DebugLogWriter::getInstance().close(m_fileName);
}
/**
* @name setOutputFile
* @brief Set an output file where the log will be saved
*
* @param file_path Path to the log file.
*
* @return If the operation successful or not.
* @retval true Operation was successful.
* @retval false Operation failed.
*
*/
bool DebugLog::setOutputFile(const std::string& file_path) {
if (is_open()) {
close();
void DebugLog::setDebugLogFile(const std::string& fileName) {
m_fileName = fileName;
if (isLogFileSet()) {
DebugLogWriter::getInstance().close(m_fileName);
}
open(file_path, std::fstream::out | std::fstream::app);
if (!is_open()) {
return false;
}
return true;
DebugLogWriter::getInstance().open(m_fileName);
}
/**
* @name write_log
* @brief Write a message into the debug log.
*
* @param debug_level Debug level of the given message.
* @param text Message to be written.
*
* @return If the operation successful or not.
* @retval true Operation was successful.
* @retval false Operation failed.
*
*/
bool DebugLog::write_log(int debug_level, const std::string &text) {
std::cout << "?" << std::to_string(is_open()) << ":" << std::to_string(m_debug_level) <<" [" << debug_level << "] " << text << std::endl;
if (!is_open()) {
return false;
}
if (debug_level <= m_debug_level) {
*this << "[" << debug_level << "] " << text << std::endl;
}
return true;
void DebugLog::setDebugLogLevel(int level) {
m_debugLevel = level;
}
/**
* @name setDebugLevel
* @brief Changes the default debug level.
*
* @param level Debug level.
*
* @return If the operation successful or not.
* @retval true Operation was successful.
* @retval false Operation failed.
*
*/
bool DebugLog::setDebugLevel(int level) {
if (level < 0 || level > 9) {
return false;
bool DebugLog::isLogFileSet() {
return m_fileName.empty() == false;
}
bool DebugLog::isLogLevelSet() {
return m_debugLevel != -1;
}
const std::string& DebugLog::getDebugLogFile() {
return m_fileName;
}
int DebugLog::getDebugLogLevel() {
if (m_debugLevel < 0) {
return 0;
}
m_debug_level = level;
return true;
return m_debugLevel;
}
/**
* @name isConfigured
* @brief Returns if debug log is configured or not.
*
* @return If the debug log is configured or not
* @retval true It is configured.
* @retval false It is not configured.
*
*/
bool DebugLog::isConfigured() {
return m_is_configured;
}
void DebugLog::refCountDecreaseAndCheck(void) {
this->m_referenceCount--;
if (this->m_referenceCount == 0) {
delete this;
void DebugLog::write(int level, const std::string &msg) {
if (level <= m_debugLevel) {
DebugLogWriter::getInstance().write(m_fileName, "[" + std::to_string(level) + "] " + msg);
}
}
void DebugLog::refCountIncrease(void) {
this->m_referenceCount++;
}
} // namespace ModSecurity
} // namespace ModSecurity

72
src/debug_log_writer.cc Normal file
View File

@ -0,0 +1,72 @@
/*
* 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 "src/debug_log_writer.h"
#include <stddef.h>
#include <fstream>
#include "src/debug_log_writer_agent.h"
namespace ModSecurity {
void DebugLogWriter::open(const std::string& fileName) {
std::map<std::string, DebugLogWriterAgent *>::iterator it;
DebugLogWriterAgent *agent;
it = agents.find(fileName);
if (it != agents.end()) {
agent = it->second;
} else {
agent = new DebugLogWriterAgent(fileName);
agents[fileName] = agent;
}
agent->refCountIncrease();
}
void DebugLogWriter::close(const std::string& fileName) {
#if 0
std::map<std::string, DebugLogWriterAgent *>::iterator it;
DebugLogWriterAgent *agent;
it = agents.find(fileName);
if (it != agents.end()) {
agent = it->second;
if (agent->refCountDecreaseAndCheck()) {
agents.erase(it);
}
}
#endif
}
void DebugLogWriter::write(const std::string& file, const std::string &msg) {
std::map<std::string, DebugLogWriterAgent *>::iterator it;
DebugLogWriterAgent *agent;
it = agents.find(file);
if (it != agents.end()) {
agent = it->second;
agent->write(msg);
} else {
std::cout << file << ": " << msg << std::endl;
}
}
} // namespace ModSecurity

57
src/debug_log_writer.h Normal file
View File

@ -0,0 +1,57 @@
/*
* 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 <iostream>
#include <map>
#include <string>
#ifndef SRC_DEBUG_LOG_WRITER_H_
#define SRC_DEBUG_LOG_WRITER_H_
#include "debug_log_writer_agent.h"
namespace ModSecurity {
/** @ingroup ModSecurity_CPP_API */
class DebugLogWriter {
public:
static DebugLogWriter& getInstance() {
static DebugLogWriter instance;
return instance;
}
void write(const std::string& file, const std::string& msg);
void close(const std::string& m_fileName);
void open(const std::string& m_fileName);
private:
DebugLogWriter() {};
// C++ 03
// ========
// Dont forget to declare these two. You want to make sure they
// are unacceptable otherwise you may accidentally get copies of
// your singleton appearing.
DebugLogWriter(DebugLogWriter const&);
void operator=(DebugLogWriter const&);
std::map<std::string, DebugLogWriterAgent *> agents;
};
} // namespace ModSecurity
#endif // SRC_DEBUG_LOG_WRITER_H_

View File

@ -0,0 +1,46 @@
/*
* 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 "src/debug_log_writer_agent.h"
#include <stddef.h>
#include <fstream>
#include "debug_log_writer.h"
namespace ModSecurity {
DebugLogWriterAgent::DebugLogWriterAgent(const std::string& fileName) :
m_referenceCount(0),
m_fileName(fileName) {
open(m_fileName, std::fstream::out | std::fstream::app);
}
void DebugLogWriterAgent::write(const std::string& msg) {
if (!is_open()) {
std::cout << "Agent: " << m_fileName << ": " << msg << std::endl;
return;
}
*this << msg << std::endl;
*this << flush();
}
} // namespace ModSecurity

View File

@ -0,0 +1,56 @@
/*
* 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 <iostream>
#include <fstream>
#include <string>
#ifndef SRC_DEBUG_LOG_WRITER_AGENT_H_
#define SRC_DEBUG_LOG_WRITER_AGENT_H_
namespace ModSecurity {
/** @ingroup ModSecurity_CPP_API */
class DebugLogWriterAgent : public std::ofstream {
public:
DebugLogWriterAgent(const std::string& fileName);
~DebugLogWriterAgent() {
if (is_open()) {
close();
}
}
void write(const std::string& msg);
bool refCountDecreaseAndCheck() {
this->m_referenceCount--;
if (this->m_referenceCount == 0) {
delete this;
return true;
}
return false;
}
void refCountIncrease() {
this->m_referenceCount++;
}
int m_referenceCount;
std::string m_fileName;
};
} // namespace ModSecurity
#endif // SRC_DEBUG_LOG_WRITER_AGENT_H_

View File

@ -373,11 +373,23 @@ expression:
/* Debug log: start */
| CONFIG_DIR_DEBUG_LVL
{
driver.debugLevel = atoi($1.c_str());
if (driver.m_debugLog != NULL) {
driver.m_debugLog->setDebugLogLevel(atoi($1.c_str()));
} else {
driver.parserError << "Internal error, there is no DebugLog ";
driver.parserError << "object associated with the driver class";
YYERROR;
}
}
| CONFIG_DIR_DEBUG_LOG
{
driver.debug_log_path = $1;
if (driver.m_debugLog != NULL) {
driver.m_debugLog->setDebugLogFile($1);
} else {
driver.parserError << "Internal error, there is no DebugLog ";
driver.parserError << "object associated with the driver class";
YYERROR;
}
}
/* Debug log: end */
| CONFIG_DIR_GEO_DB

View File

@ -91,10 +91,6 @@ Rules::~Rules() {
if (audit_log) {
audit_log->refCountDecreaseAndCheck();
}
/** Cleanup debug log */
if (debugLog) {
debugLog->refCountDecreaseAndCheck();
}
}
@ -197,27 +193,25 @@ int Rules::merge(Driver *from) {
this->secRuleEngine = from->secRuleEngine;
this->secRequestBodyAccess = from->secRequestBodyAccess;
this->secResponseBodyAccess = from->secResponseBodyAccess;
this->debug_log_path = from->debug_log_path;
this->debugLevel = from->debugLevel;
if (from->m_debugLog && this->m_debugLog &&
from->m_debugLog->isLogFileSet()) {
this->m_debugLog->setDebugLogFile(from->m_debugLog->getDebugLogFile());
}
if (from->m_debugLog && this->m_debugLog &&
from->m_debugLog->isLogLevelSet()) {
this->m_debugLog->setDebugLogLevel(
from->m_debugLog->getDebugLogLevel());
}
this->components = from->components;
this->requestBodyLimit = from->requestBodyLimit;
this->responseBodyLimit = from->responseBodyLimit;
this->requestBodyLimitAction = from->requestBodyLimitAction;
this->responseBodyLimitAction = from->responseBodyLimitAction;
if (customDebugLog) {
this->debugLog = customDebugLog->new_instance();
} else {
this->debugLog = new DebugLog();
}
this->debugLog->refCountIncrease();
this->audit_log = from->audit_log;
this->audit_log->refCountIncrease();
this->debugLog->setDebugLevel(from->debugLevel);
this->debugLog->setOutputFile(from->debug_log_path);
return amount_of_rules;
}
@ -243,28 +237,28 @@ int Rules::merge(Rules *from) {
this->requestBodyLimitAction = from->requestBodyLimitAction;
this->responseBodyLimitAction = from->responseBodyLimitAction;
if (customDebugLog) {
this->debugLog = customDebugLog->new_instance();
} else {
this->debugLog = new DebugLog();
if (from->m_debugLog && this->m_debugLog &&
from->m_debugLog->isLogFileSet()) {
this->m_debugLog->setDebugLogFile(from->m_debugLog->getDebugLogFile());
}
if (from->m_debugLog && this->m_debugLog &&
from->m_debugLog->isLogLevelSet()) {
this->m_debugLog->setDebugLogLevel(
from->m_debugLog->getDebugLogLevel());
}
this->debugLog->refCountIncrease();
this->audit_log = from->audit_log;
if (this->audit_log != NULL) {
this->audit_log->refCountIncrease();
}
this->debugLog->setDebugLevel(from->debugLevel);
this->debugLog->setOutputFile(from->debug_log_path);
return amount_of_rules;
}
void Rules::debug(int level, std::string message) {
if (debugLog != NULL) {
debugLog->write_log(level, message);
if (m_debugLog != NULL) {
m_debugLog->write(level, message);
}
}

View File

@ -28,9 +28,8 @@ CustomDebugLog *CustomDebugLog::new_instance() {
}
bool CustomDebugLog::write_log(int level, const std::string& message) {
void CustomDebugLog::write(int level, const std::string& message) {
m_log << "[" << level << "] " << message << std::endl;
return true;
}

View File

@ -27,7 +27,7 @@ class CustomDebugLog : public ModSecurity::DebugLog {
public:
CustomDebugLog *new_instance();
bool write_log(int level, const std::string& message) override;
void write(int level, const std::string& message) override;
bool contains(const std::string& pattern);
std::string log_messages();

View File

@ -191,7 +191,7 @@ end:
modsec_assay->processLogging(r.status);
CustomDebugLog *d = reinterpret_cast<CustomDebugLog *>
(modsec_rules->debugLog);
(modsec_rules->m_debugLog);
if (d != NULL) {
if (!d->contains(t->debug_log)) {
@ -220,7 +220,7 @@ after_debug_log:
delete modsec_assay;
delete modsec_rules;
delete modsec;
delete debug_log;
/* delete debug_log; */
res->insert(res->end(), r.begin(), r.end());
}