Writes audit log in parallel mode

First version still missing the index among other things
This commit is contained in:
Felipe Zimmerle 2015-07-10 15:23:15 -03:00
parent 693238b235
commit c9620ac50f
13 changed files with 164 additions and 30 deletions

View File

@ -126,7 +126,7 @@ class Assay {
int processResponseBody();
int appendResponseBody(const unsigned char *body, size_t size);
int processLogging();
int processLogging(int status_code);
ModSecurityIntervention *intervention();
@ -149,12 +149,14 @@ class Assay {
bool save_in_auditlog;
bool do_not_save_in_auditlog;
int http_code_returned;
int httpCodeReturned;
std::string to_json(int parts);
private:
std::string id;
time_t timeStamp;
private:
std::ofstream myfile;
Rules *m_rules;
ModSecurity *m_ms;
@ -166,7 +168,6 @@ class Assay {
const char *m_uri;
const char *m_protocol;
const char *m_httpVersion;
time_t m_timeStamp;
std::ostringstream m_requestBody;
std::ostringstream m_responseBody;
@ -236,7 +237,7 @@ void msc_assay_cleanup(Assay *assay);
ModSecurityIntervention *msc_intervention(Assay *assay);
/** @ingroup ModSecurity_C_API */
int msc_process_logging(Assay *assay);
int msc_process_logging(Assay *assay, int code);
#ifdef __cplusplus
}

View File

@ -87,10 +87,10 @@ Assay::Assay(ModSecurity *ms, Rules *rules)
m_rules(rules),
save_in_auditlog(false),
do_not_save_in_auditlog(false),
m_timeStamp(std::time(NULL)),
http_code_returned(200),
timeStamp(std::time(NULL)),
httpCodeReturned(200),
m_ms(ms) {
id = std::to_string(this->m_timeStamp) + \
id = std::to_string(this->timeStamp) + \
std::to_string(generate_assay_unique_id());
m_rules->incrementReferenceCount();
this->debug(4, "Initialising transaction");
@ -617,8 +617,9 @@ int Assay::getResponseBodyLenth() {
* @retval false Operation failed.
*
*/
int Assay::processLogging() {
int Assay::processLogging(int returned_code) {
debug(4, "Starting phase LOGGING. (SecRules 5)");
this->httpCodeReturned = returned_code;
this->m_rules->evaluate(ModSecurity::LoggingPhase, this);
/* If relevant, save this assay information at the audit_logs */
@ -691,7 +692,7 @@ std::string Assay::to_json(int parts) {
const unsigned char *buf;
size_t len;
yajl_gen g = NULL;
std::string ts = ascTime(&m_timeStamp).c_str();
std::string ts = ascTime(&timeStamp).c_str();
std::string uniqueId = UniqueId::uniqueId();
g = yajl_gen_alloc(NULL);
@ -754,7 +755,7 @@ std::string Assay::to_json(int parts) {
yajl_gen_map_open(g);
LOGFY_ADD("body", this->m_responseBody.str().c_str());
LOGFY_ADD_NUM("http_code", http_code_returned);
LOGFY_ADD_NUM("http_code", httpCodeReturned);
/* response headers */
yajl_gen_string(g, reinterpret_cast<const unsigned char*>("headers"),
@ -1251,14 +1252,15 @@ extern "C" int msc_get_response_body_length(Assay *assay) {
* delivered prior to the execution of this function.
*
* @param assay ModSecurity assay.
* @param code HTTP code returned to the user.
*
* @returns If the operation was successful or not.
* @retval 1 Operation was successful.
* @retval 0 Operation failed.
*
*/
extern "C" int msc_process_logging(Assay *assay) {
return assay->processLogging();
extern "C" int msc_process_logging(Assay *assay, int code) {
return assay->processLogging(code);
}
} // namespace ModSecurity

View File

@ -102,11 +102,11 @@ bool AuditLog::setType(AuditLogType audit_type) {
bool AuditLog::init() {
if (m_type == ParallelAuditLogType) {
m_writer = new AuditLogWriterParallel();
m_writer = new AuditLogWriterParallel(this);
}
if (m_type == SerialAuditLogType) {
m_writer = new AuditLogWriterSerial();
m_writer = new AuditLogWriterSerial(this);
}
if (m_writer == NULL || m_writer->init() == false) {
@ -134,7 +134,7 @@ bool AuditLog::isRelevant(int status) {
bool AuditLog::saveIfRelevant(Assay *assay) {
if (this->isRelevant(assay->http_code_returned) == false &&
if (this->isRelevant(assay->httpCodeReturned) == false &&
assay->save_in_auditlog == false) {
return true;
}
@ -148,9 +148,7 @@ bool AuditLog::saveIfRelevant(Assay *assay) {
return true;
}
std::string log = assay->to_json(0);
m_writer->write(log);
m_writer->write(assay);
return true;
}

View File

@ -162,12 +162,13 @@ class AuditLog {
bool saveIfRelevant(Assay *assay);
bool isRelevant(int status);
private:
AuditLogStatus m_status;
std::string m_path1;
std::string m_path2;
std::string m_storage_dir;
private:
AuditLogStatus m_status;
int m_file_permissions;
int m_storage_permission;

View File

@ -33,8 +33,8 @@ std::string AuditLogWriter::file_name(const std::string& unique_id) {
* Temporary print the log into the std::cout to debug purposes.
*
*/
bool AuditLogWriter::write(const std::string& log) {
std::cout << log << std::endl;
bool AuditLogWriter::write(Assay *assay) {
std::cout << assay->to_json(0) << std::endl;
return true;
}

View File

@ -23,20 +23,28 @@
#include <fstream>
#endif
#include "modsecurity/assay.h"
#ifdef __cplusplus
namespace ModSecurity {
class AuditLog;
/** @ingroup ModSecurity_CPP_API */
class AuditLogWriter : public std::ofstream {
public:
AuditLogWriter() { }
explicit AuditLogWriter(AuditLog *audit)
: m_audit(audit) { }
virtual bool close() { return true; }
virtual bool init() { return true; }
virtual bool write(const std::string& log);
virtual bool write(Assay *assay);
std::string file_name(const std::string& unique_id);
protected:
AuditLog *m_audit;
};
} // namespace ModSecurity

View File

@ -15,9 +15,83 @@
#include "src/audit_log_writer_parallel.h"
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <fstream>
#include "src/audit_log.h"
#include "modsecurity/assay.h"
#include "src/utils.h"
namespace ModSecurity {
inline std::string AuditLogWriterParallel::logFilePath(time_t *t,
int part) {
struct tm timeinfo;
char tstr[300];
size_t len;
std::string name("");
localtime_r(t, &timeinfo);
if (part & YearMonthDayDirectory) {
memset(tstr, '\0', 300);
strftime(tstr, 299, "/%Y%m%d", &timeinfo);
name = tstr;
}
if (part & YearMonthDayAndTimeDirectory) {
memset(tstr, '\0', 300);
strftime(tstr, 299, "/%Y%m%d-%H%M", &timeinfo);
name = name + tstr;
}
if (part & YearMonthDayAndTimeFileName) {
memset(tstr, '\0', 300);
strftime(tstr, 299, "/%Y%m%d-%H%M%S", &timeinfo);
name = name + tstr;
}
return name;
}
bool AuditLogWriterParallel::init() {
/** TODO:: Check if the directory exists. */
/** TODO:: Checking if we have permission to write in the target dir */
return true;
}
bool AuditLogWriterParallel::close() {
return true;
}
bool AuditLogWriterParallel::write(Assay *assay) {
std::string log = assay->to_json(0);
std::string fileName = logFilePath(&assay->timeStamp,
YearMonthDayDirectory | YearMonthDayAndTimeDirectory
| YearMonthDayAndTimeFileName);
fileName = fileName + "-" + assay->id;
std::string logPath = m_audit->m_storage_dir;
createDir((logPath +
logFilePath(&assay->timeStamp, YearMonthDayDirectory)).c_str());
createDir((logPath +
logFilePath(&assay->timeStamp, YearMonthDayDirectory
| YearMonthDayAndTimeDirectory)).c_str());
std::ofstream f;
f.open(logPath + fileName, std::fstream::out | std::fstream::app);
f << log;
f.close();
return true;
}
} // namespace ModSecurity

View File

@ -13,10 +13,13 @@
*
*/
#include <string>
#ifndef SRC_AUDIT_LOG_WRITER_PARALLEL_H_
#define SRC_AUDIT_LOG_WRITER_PARALLEL_H_
#include "src/audit_log_writer.h"
#include "modsecurity/assay.h"
#ifdef __cplusplus
@ -25,7 +28,36 @@ namespace ModSecurity {
/** @ingroup ModSecurity_CPP_API */
class AuditLogWriterParallel : public AuditLogWriter {
public:
AuditLogWriterParallel() { }
explicit AuditLogWriterParallel(AuditLog *audit)
: AuditLogWriter(audit) { }
bool init() override;
bool close() override;
bool write(Assay *assay) override;
/**
*
* Audit log file is saved into a directory structure. This directory
* structure is based on the timestamp of the assay creation, at the exact
* moment that ModSecurity be aware of a particular request/transaction.
* The expect fromat is:
*
* [...]/YearMonthDay/YearMonthDayAndTime/YearMonthDayAndTime-RequestId
*
* Example:
*
* /20150710/20150710-1353/20150710-135353-143654723362.584244
*
* This enumeration describes the subpaths of this structure.
*
*/
enum AuditLogFilePath {
YearMonthDayDirectory = 2,
YearMonthDayAndTimeDirectory = 4,
YearMonthDayAndTimeFileName = 8,
};
inline std::string logFilePath(time_t *t, int part);
};
} // namespace ModSecurity

View File

@ -30,7 +30,7 @@ bool AuditLogWriterSerial::close() {
}
bool AuditLogWriterSerial::write(const std::string& log) {
bool AuditLogWriterSerial::write(Assay *assay) {
return true;
}

View File

@ -23,6 +23,7 @@
#define SRC_AUDIT_LOG_WRITER_SERIAL_H_
#include "src/audit_log_writer.h"
#include "modsecurity/assay.h"
#ifdef __cplusplus
@ -31,11 +32,12 @@ namespace ModSecurity {
/** @ingroup ModSecurity_CPP_API */
class AuditLogWriterSerial : public AuditLogWriter {
public:
AuditLogWriterSerial() { }
explicit AuditLogWriterSerial(AuditLog *audit)
: AuditLogWriter(audit) { }
bool init() override;
bool close() override;
bool write(const std::string& log) override;
bool write(Assay *assay) override;
};
} // namespace ModSecurity

View File

@ -24,6 +24,13 @@
#include <memory>
#include <functional>
#if defined _MSC_VER
#include <direct.h>
#elif defined __GNUC__
#include <sys/types.h>
#include <sys/stat.h>
#endif
#include "modsecurity/modsecurity.h"
namespace ModSecurity {
@ -62,5 +69,13 @@ std::string ascTime(time_t *t) {
}
void createDir(std::string dir) {
#if defined _MSC_VER
_mkdir(dir.data());
#elif defined __GNUC__
mkdir(dir.data(), 0777);
#endif
}
} // namespace ModSecurity

View File

@ -27,6 +27,7 @@ namespace ModSecurity {
double random_number(const double from, const double to);
double generate_assay_unique_id();
std::string ascTime(time_t *t);
void createDir(std::string dir);
} // namespace ModSecurity
#define SRC_UTILS_H_

View File

@ -139,7 +139,7 @@ void perform_unit_test(std::vector<RegressionTest *> *tests,
}
end:
modsec_assay->processLogging();
modsec_assay->processLogging(r.status);
CustomDebugLog *d = reinterpret_cast<CustomDebugLog *>
(modsec_rules->debug_log);