From aa8dc9115b734e9b04bb8c49ed97df15d75be311 Mon Sep 17 00:00:00 2001 From: Felipe Zimmerle Date: Wed, 8 Jul 2015 19:22:43 -0300 Subject: [PATCH] Adds first version of Assay's materialization in a JSON format That format will be used by the audit logs. --- headers/modsecurity/assay.h | 20 +++++++ src/Makefile.am | 4 +- src/assay.cc | 110 ++++++++++++++++++++++++++++++++++++ src/audit_log.cc | 10 +--- src/audit_log.h | 1 - src/audit_log_writer.cc | 10 +++- src/audit_log_writer.h | 2 +- test/benchmark/Makefile.am | 3 +- 8 files changed, 145 insertions(+), 15 deletions(-) diff --git a/headers/modsecurity/assay.h b/headers/modsecurity/assay.h index e2bb4467..a71a0f58 100644 --- a/headers/modsecurity/assay.h +++ b/headers/modsecurity/assay.h @@ -38,8 +38,25 @@ typedef struct Rules_t Rules; #include "modsecurity/intervention.h" +#define LOGFY_ADD(a, b) \ + yajl_gen_string(g, reinterpret_cast(a), strlen(a)); \ + if (b == NULL) { \ + yajl_gen_string(g, reinterpret_cast(""), \ + strlen("")); \ + } else { \ + yajl_gen_string(g, reinterpret_cast(b), \ + strlen(b)); \ + } +#define LOGFY_ADD_INT(a, b) \ + yajl_gen_string(g, reinterpret_cast(a), strlen(a)); \ + yajl_gen_number(g, reinterpret_cast(b), strlen(b)); + +#define LOGFY_ADD_NUM(a, b) \ + yajl_gen_string(g, reinterpret_cast(a), strlen(a)); \ + yajl_gen_integer(g, b); + #ifdef __cplusplus namespace ModSecurity { @@ -134,10 +151,13 @@ class Assay { int http_code_returned; + std::string to_json(int parts); + private: std::string id; std::ofstream myfile; Rules *m_rules; + const char *m_clientIpAddress; const char *m_serverIpAddress; int m_clientPort; diff --git a/src/Makefile.am b/src/Makefile.am index 478cc6a9..66106c34 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -148,8 +148,8 @@ libmodsecurity_la_CPPFLAGS = \ libmodsecurity_la_LIBADD = \ - @LEXLIB@ - + @LEXLIB@ \ + $(YAJL_LDADD) libmodsecurity_la_LDFLAGS = \ -version-info @MSC_VERSION_INFO@ diff --git a/src/assay.cc b/src/assay.cc index a655780a..f19ff6e2 100644 --- a/src/assay.cc +++ b/src/assay.cc @@ -15,6 +15,8 @@ #include "modsecurity/assay.h" +#include +#include #include #include @@ -23,12 +25,14 @@ #include #include #include +#include #include "modsecurity/modsecurity.h" #include "modsecurity/intervention.h" #include "actions/action.h" #include "src/utils.h" #include "src/audit_log.h" +#include "src/unique_id.h" using ModSecurity::actions::Action; @@ -682,6 +686,112 @@ ModSecurityIntervention *Assay::intervention() { } +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 uniqueId = UniqueId::uniqueId(); + + g = yajl_gen_alloc(NULL); + if (g == NULL) { + return ""; + } + yajl_gen_config(g, yajl_gen_beautify, 1); + + /* main */ + yajl_gen_map_open(g); + + /* trasaction */ + yajl_gen_string(g, reinterpret_cast("transaction"), + strlen("transaction")); + + yajl_gen_map_open(g); + LOGFY_ADD("client_ip", this->m_clientIpAddress); + LOGFY_ADD("time_stamp", ts.c_str()); + LOGFY_ADD("server_id", uniqueId.c_str()); + LOGFY_ADD_NUM("client_port", m_clientPort); + LOGFY_ADD("host_ip", m_serverIpAddress); + LOGFY_ADD_NUM("host_port", m_serverPort); + LOGFY_ADD("id", this->id.c_str()); + + /* request */ + yajl_gen_string(g, reinterpret_cast("request"), + strlen("request")); + yajl_gen_map_open(g); + + LOGFY_ADD("protocol", m_protocol); + LOGFY_ADD_INT("http_version", m_httpVersion); + LOGFY_ADD("uri", this->m_uri); + LOGFY_ADD("body", this->m_requestBody.str().c_str()); + + /* request headers */ + yajl_gen_string(g, reinterpret_cast("headers"), + strlen("headers")); + yajl_gen_map_open(g); + + for (auto h : this->m_variables_strings) { + std::string filter = "REQUEST_HEADERS:"; + std::string a = h.first; + std::string b = h.second; + + if (a.compare(0, filter.length(), filter) == 0) { + if (a.length() > filter.length()) { + LOGFY_ADD(a.c_str() + filter.length(), b.c_str()); + } + } + } + + /* end: request headers */ + yajl_gen_map_close(g); + /* end: request */ + yajl_gen_map_close(g); + + /* response */ + yajl_gen_string(g, reinterpret_cast("response"), + strlen("response")); + yajl_gen_map_open(g); + + LOGFY_ADD("body", this->m_responseBody.str().c_str()); + LOGFY_ADD_NUM("http_code", http_code_returned); + + /* response headers */ + yajl_gen_string(g, reinterpret_cast("headers"), + strlen("headers")); + yajl_gen_map_open(g); + + for (auto h : this->m_variables_strings) { + std::string filter = "RESPONSE_HEADERS:"; + std::string a = h.first; + std::string b = h.second; + + if (a.compare(0, filter.length(), filter) == 0) { + if (a.length() > filter.length()) { + LOGFY_ADD(a.c_str() + filter.length(), b.c_str()); + } + } + } + /* end: response headers */ + yajl_gen_map_close(g); + /* end: response */ + yajl_gen_map_close(g); + + + /* end: transaction */ + yajl_gen_map_close(g); + + /* end: main */ + yajl_gen_map_close(g); + + yajl_gen_get_buf(g, &buf, &len); + + std::string log(reinterpret_cast(buf), len); + + yajl_gen_free(g); + + return log; +} + void Assay::store_variable(std::string key, std::string value) { this->m_variables_strings[key] = value; } diff --git a/src/audit_log.cc b/src/audit_log.cc index b2ce496d..43ae85c8 100644 --- a/src/audit_log.cc +++ b/src/audit_log.cc @@ -15,8 +15,6 @@ #include "src/audit_log.h" -#include -#include #include #include #include @@ -150,7 +148,7 @@ bool AuditLog::saveIfRelevant(Assay *assay) { return true; } - std::string log = logfy(assay); + std::string log = assay->to_json(0); m_writer->write(log); @@ -158,12 +156,6 @@ bool AuditLog::saveIfRelevant(Assay *assay) { } -std::string AuditLog::logfy(Assay *assay) { - std::string log("ops"); - return log; -} - - bool AuditLog::close() { return true; } diff --git a/src/audit_log.h b/src/audit_log.h index 9a6e2a0b..df9a9a17 100644 --- a/src/audit_log.h +++ b/src/audit_log.h @@ -160,7 +160,6 @@ class AuditLog { bool close(); bool saveIfRelevant(Assay *assay); - std::string logfy(Assay *assay); bool isRelevant(int status); private: diff --git a/src/audit_log_writer.cc b/src/audit_log_writer.cc index cda49dae..e3667608 100644 --- a/src/audit_log_writer.cc +++ b/src/audit_log_writer.cc @@ -28,6 +28,14 @@ std::string AuditLogWriter::file_name(const std::string& unique_id) { /** TODO: return file with time stamp and etc. */ return std::string("/tmp/temp_audit_log_file.txt"); } - +/** + * + * Temporary print the log into the std::cout to debug purposes. + * + */ +bool AuditLogWriter::write(const std::string& log) { + std::cout << log << std::endl; + return true; +} } // namespace ModSecurity diff --git a/src/audit_log_writer.h b/src/audit_log_writer.h index 5441073b..e939361f 100644 --- a/src/audit_log_writer.h +++ b/src/audit_log_writer.h @@ -34,7 +34,7 @@ class AuditLogWriter : public std::ofstream { virtual bool close() { return true; } virtual bool init() { return true; } - virtual bool write(const std::string& log) { return true; } + virtual bool write(const std::string& log); std::string file_name(const std::string& unique_id); }; diff --git a/test/benchmark/Makefile.am b/test/benchmark/Makefile.am index 60208f67..469924a9 100644 --- a/test/benchmark/Makefile.am +++ b/test/benchmark/Makefile.am @@ -6,7 +6,8 @@ benchmark_SOURCES = \ benchmark.cc benchmark_LDADD = \ - $(top_builddir)/src/.libs/libmodsecurity.a + $(top_builddir)/src/.libs/libmodsecurity.a \ + $(YAJL_LDADD) benchmark_CPPFLAGS = \ -std=c++11 \