diff --git a/examples/simple_example_using_c/test.c b/examples/simple_example_using_c/test.c index 858f5dc3..9835dded 100644 --- a/examples/simple_example_using_c/test.c +++ b/examples/simple_example_using_c/test.c @@ -55,7 +55,7 @@ int main (int argc, char **argv) } msc_rules_dump(rules); - assay = msc_new_assay(modsec, rules); + assay = msc_new_assay(modsec, rules, NULL); msc_process_connection(assay, "127.0.0.1", 12345, "127.0.0.1", 80); msc_process_uri(assay, diff --git a/headers/modsecurity/assay.h b/headers/modsecurity/assay.h index 539883d3..f13f7603 100644 --- a/headers/modsecurity/assay.h +++ b/headers/modsecurity/assay.h @@ -159,7 +159,7 @@ class ModSecurityStringVariables : /** @ingroup ModSecurity_CPP_API */ class Assay { public: - Assay(ModSecurity *assay, Rules *rules); + Assay(ModSecurity *assay, Rules *rules, void *logCbData); ~Assay(); /** TODO: Should be an structure that fits an IP address */ @@ -292,6 +292,7 @@ class Assay { std::ostringstream m_requestBody; std::ostringstream m_responseBody; ModSecurityCollectionsVariables m_variables_collections; + void *m_logCbData; }; @@ -302,7 +303,7 @@ extern "C" { #endif /** @ingroup ModSecurity_C_API */ -Assay *msc_new_assay(ModSecurity *ms, Rules *rules); +Assay *msc_new_assay(ModSecurity *ms, Rules *rules, void *logCbData); /** @ingroup ModSecurity_C_API */ int msc_process_connection(Assay *assay, const char *client, int cPort, diff --git a/headers/modsecurity/modsecurity.h b/headers/modsecurity/modsecurity.h index f7022530..6dbb1474 100644 --- a/headers/modsecurity/modsecurity.h +++ b/headers/modsecurity/modsecurity.h @@ -120,6 +120,8 @@ typedef struct ModSecurity_t ModSecurity; #define MODSECURITY_VERSION_NUM MODSECURITY_MAJOR \ MODSECURITY_MINOR MODSECURITY_PATCHLEVEL MODSECURITY_TAG_NUM +typedef void (*LogCb) (void *, const char *); + #ifdef __cplusplus namespace ModSecurity { @@ -140,6 +142,8 @@ class ModSecurity { static std::string whoAmI(); void setConnectorInformation(std::string connector); + void setServerLogCb(LogCb cb); + void serverLog(void *data, const std::string& msg); const std::string& getConnectorInformation(); /** @@ -220,6 +224,7 @@ class ModSecurity { private: std::string m_connector; + LogCb m_logCb; }; @@ -236,6 +241,8 @@ const char *msc_who_am_i(ModSecurity *msc); /** @ingroup ModSecurity_C_API */ void msc_set_connector_info(ModSecurity *msc, const char *connector); /** @ingroup ModSecurity_C_API */ +void msc_set_log_cb(ModSecurity *msc, LogCb cb); +/** @ingroup ModSecurity_C_API */ void msc_cleanup(ModSecurity *msc); #ifdef __cplusplus diff --git a/src/assay.cc b/src/assay.cc index 96c66208..9f06d194 100644 --- a/src/assay.cc +++ b/src/assay.cc @@ -81,7 +81,7 @@ namespace ModSecurity { * @endcode * */ -Assay::Assay(ModSecurity *ms, Rules *rules) +Assay::Assay(ModSecurity *ms, Rules *rules, void *logCbData) : m_clientIpAddress(""), m_serverIpAddress(""), m_clientPort(0), @@ -105,6 +105,7 @@ Assay::Assay(ModSecurity *ms, Rules *rules) m_responseHeadersNames(NULL), m_marker(""), start(cpu_seconds()), + m_logCbData(logCbData), m_ms(ms) { id = std::to_string(this->timeStamp) + \ std::to_string(generate_assay_unique_id()); @@ -1428,10 +1429,12 @@ std::list> return l; } + void Assay::serverLog(const std::string& msg) { - std::cerr << "Server log is not ready : " << msg << std::endl; + m_ms->serverLog(m_logCbData, msg); } + std::string* Assay::resolve_variable_first(const std::string& var) { auto range = m_variables_strings.equal_range(var); @@ -1500,8 +1503,8 @@ void Assay::setCollection(const std::string& collectionName, * */ extern "C" Assay *msc_new_assay(ModSecurity *ms, - Rules *rules) { - return new Assay(ms, rules); + Rules *rules, void *logCbData) { + return new Assay(ms, rules, logCbData); } diff --git a/src/modsecurity.cc b/src/modsecurity.cc index 20583d72..63b4ed3d 100644 --- a/src/modsecurity.cc +++ b/src/modsecurity.cc @@ -44,7 +44,8 @@ namespace ModSecurity { * @endcode */ ModSecurity::ModSecurity() - : m_connector("") { + : m_connector(""), + m_logCb(NULL) { UniqueId::uniqueId(); srand(time(NULL)); #ifdef MSC_WITH_CURL @@ -138,6 +139,23 @@ const std::string& ModSecurity::getConnectorInformation() { } +void ModSecurity::serverLog(void *data, const std::string& msg) { + if (m_logCb == NULL) { + std::cout << "Server log callback is not set -- " << msg << std::endl; + } else { + m_logCb(data, msg.c_str()); + } +} + + +void ModSecurity::setServerLogCb(LogCb cb) { + m_logCb = (LogCb) cb; +} + +extern "C" void msc_set_log_cb(ModSecurity *msc, LogCb cb) { + msc->setServerLogCb(cb); +} + /** * @name msc_set_connector_info * @brief Set information about the connector that is using the library. diff --git a/test/benchmark/benchmark.cc b/test/benchmark/benchmark.cc index 361e91a3..bc4e1b56 100644 --- a/test/benchmark/benchmark.cc +++ b/test/benchmark/benchmark.cc @@ -84,7 +84,7 @@ int main(int argc, char *argv[]) { for (i = 0; i < NUM_REQUESTS; i++) { std::cout << "Proceding with request " << i << std::endl; - Assay *modsecAssay = new Assay(modsec, rules); + Assay *modsecAssay = new Assay(modsec, rules, NULL); modsecAssay->processConnection(ip, 12345, "127.0.0.1", 80); if (modsecAssay->intervention(&it)) { diff --git a/test/regression/regression.cc b/test/regression/regression.cc index f47040c7..b20b45ac 100644 --- a/test/regression/regression.cc +++ b/test/regression/regression.cc @@ -67,6 +67,11 @@ void actions(ModSecurityTestResults *r, } } +void logCb(void *data, const char *msg) { + std::stringstream *ss = (std::stringstream *) data; + *ss << msg << std::endl; +} + void perform_unit_test(std::vector *tests, ModSecurityTestResults *res, int *count) { @@ -77,7 +82,8 @@ void perform_unit_test(std::vector *tests, ModSecurity::ModSecurity *modsec = NULL; ModSecurity::Rules *modsec_rules = NULL; ModSecurity::Assay *modsec_assay = NULL; - ModSecurityTestResults r; + ModSecurityTestResults r; + std::stringstream serverLog; RegressionTestResult *testRes = new RegressionTestResult(); testRes->test = t; r.status = 200; @@ -99,6 +105,7 @@ void perform_unit_test(std::vector *tests, modsec = new ModSecurity::ModSecurity(); modsec->setConnectorInformation("ModSecurity-regression v0.0.1-alpha" \ " (ModSecurity regression test utility)"); + modsec->setServerLogCb(logCb); modsec_rules = new ModSecurity::Rules(debug_log); if (modsec_rules->load(t->rules.c_str(), filename) < 0) { @@ -140,7 +147,8 @@ void perform_unit_test(std::vector *tests, } } - modsec_assay = new ModSecurity::Assay(modsec, modsec_rules); + modsec_assay = new ModSecurity::Assay(modsec, modsec_rules, + &serverLog); modsec_assay->processConnection(t->clientIp.c_str(), t->clientPort, t->serverIp.c_str(), t->serverPort);