diff --git a/headers/modsecurity/rule_message.h b/headers/modsecurity/rule_message.h index 51eca0e8ef..9e1ef556a6 100644 --- a/headers/modsecurity/rule_message.h +++ b/headers/modsecurity/rule_message.h @@ -67,6 +67,7 @@ class RuleMessage { m_ruleLine(rule->getLineNumber()), m_saveMessage(true), m_serverIpAddress(trans->m_serverIpAddress), + m_requestHostName(trans->m_requestHostName), m_severity(0), m_uriNoQueryStringDecoded(trans->m_uri_no_query_string_decoded), m_ver(rule->m_ver), @@ -92,6 +93,7 @@ class RuleMessage { m_ruleLine(rule->m_ruleLine), m_saveMessage(rule->m_saveMessage), m_serverIpAddress(rule->m_serverIpAddress), + m_requestHostName(rule->m_requestHostName), m_severity(rule->m_severity), m_uriNoQueryStringDecoded(rule->m_uriNoQueryStringDecoded), m_ver(rule->m_ver), @@ -117,6 +119,7 @@ class RuleMessage { m_ruleLine(ruleMessage.m_ruleLine), m_saveMessage(ruleMessage.m_saveMessage), m_serverIpAddress(ruleMessage.m_serverIpAddress), + m_requestHostName(ruleMessage.m_requestHostName), m_severity(ruleMessage.m_severity), m_uriNoQueryStringDecoded(ruleMessage.m_uriNoQueryStringDecoded), m_ver(ruleMessage.m_ver), @@ -142,6 +145,7 @@ class RuleMessage { m_ruleLine = ruleMessage.m_ruleLine; m_saveMessage = ruleMessage.m_saveMessage; m_serverIpAddress = ruleMessage.m_serverIpAddress; + m_requestHostName = ruleMessage.m_requestHostName; m_severity = ruleMessage.m_severity; m_uriNoQueryStringDecoded = ruleMessage.m_uriNoQueryStringDecoded; m_ver = ruleMessage.m_ver; @@ -201,6 +205,7 @@ class RuleMessage { int m_ruleLine; bool m_saveMessage; std::shared_ptr m_serverIpAddress; + std::shared_ptr m_requestHostName; int m_severity; std::shared_ptr m_uriNoQueryStringDecoded; std::string m_ver; diff --git a/headers/modsecurity/transaction.h b/headers/modsecurity/transaction.h index 811a2c8314..9caace2c9a 100644 --- a/headers/modsecurity/transaction.h +++ b/headers/modsecurity/transaction.h @@ -393,6 +393,8 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa int processLogging(); int updateStatusCode(int status); + int setRequestHostName(const std::string& hostname); + bool intervention(ModSecurityIntervention *it); bool addArgument(const std::string& orig, const std::string& key, @@ -443,6 +445,11 @@ class Transaction : public TransactionAnchoredVariables, public TransactionSecMa */ std::shared_ptr m_serverIpAddress; + /** + * Holds the request's hostname + */ + std::shared_ptr m_requestHostName; + /** * Holds the raw URI that was requested. */ @@ -724,6 +731,9 @@ int msc_process_logging(Transaction *transaction); /** @ingroup ModSecurity_C_API */ int msc_update_status_code(Transaction *transaction, int status); +/** @ingroup ModSecurity_C_API */ +int msc_set_request_hostname(Transaction *transaction, const unsigned char *hostname); + #ifdef __cplusplus } } // namespace modsecurity diff --git a/src/rule_message.cc b/src/rule_message.cc index b88ca5c6be..5be23839eb 100644 --- a/src/rule_message.cc +++ b/src/rule_message.cc @@ -42,8 +42,8 @@ std::string RuleMessage::_details(const RuleMessage *rm) { msg.append(" [tag \"" + utils::string::toHexIfNeeded(a, true) + "\"]"); } - msg.append(" [hostname \"" + *rm->m_serverIpAddress.get() \ - + "\"]"); + msg.append(" [hostname \"" + *rm->m_requestHostName.get() + "\"]"); + msg.append(" [uri \"" + utils::string::limitTo(200, *rm->m_uriNoQueryStringDecoded.get()) + "\"]"); msg.append(" [unique_id \"" + *rm->m_id + "\"]"); msg.append(" [ref \"" + utils::string::limitTo(200, rm->m_reference) + "\"]"); diff --git a/src/transaction.cc b/src/transaction.cc index a076212571..efd1cd1b84 100644 --- a/src/transaction.cc +++ b/src/transaction.cc @@ -107,6 +107,7 @@ Transaction::Transaction(ModSecurity *ms, RulesSet *rules, void *logCbData) m_clientIpAddress(std::make_shared("")), m_httpVersion(""), m_serverIpAddress(std::make_shared("")), + m_requestHostName(std::make_shared("")), m_uri(""), m_uri_no_query_string_decoded(std::make_shared("")), m_ARGScombinedSizeDouble(0), @@ -183,6 +184,7 @@ Transaction::Transaction(ModSecurity *ms, RulesSet *rules, char *id, void *logCb m_clientIpAddress(std::make_shared("")), m_httpVersion(""), m_serverIpAddress(std::make_shared("")), + m_requestHostName(std::make_shared("")), m_uri(""), m_uri_no_query_string_decoded(std::make_shared("")), m_ARGScombinedSizeDouble(0), @@ -319,6 +321,7 @@ int Transaction::processConnection(const char *client, int cPort, const char *server, int sPort) { m_clientIpAddress = std::unique_ptr(new std::string(client)); m_serverIpAddress = std::unique_ptr(new std::string(server)); + m_requestHostName = std::unique_ptr(new std::string(server)); this->m_clientPort = cPort; this->m_serverPort = sPort; ms_dbg(4, "Transaction context created."); @@ -2358,5 +2361,52 @@ extern "C" int msc_update_status_code(Transaction *transaction, int status) { } +/** + * @name setRequestHostName + * @brief Set request's host name + * + * With this method it is possible to set the request's hostname. + * + * @note This function expects a NULL terminated string. + * + * @param hostname hostname. + * + * @returns If the operation was successful or not. + * @retval true Operation was successful. + * @retval false Operation failed. + * + */ +int Transaction::setRequestHostName(const std::string& hostname) { + + if (hostname != "") { + m_requestHostName = std::unique_ptr(new std::string(hostname)); + } + + return true; +} + + +/** + * @name msc_set_request_hostname + * @brief Set request's host name + * + * With this method it is possible to set request's hostname. + * + * @note This function expects a NULL terminated string. + * + * @param transaction ModSecurity transaction. + * @param hostname hostname. + * + * @returns If the operation was successful or not. + * @retval 1 Operation was successful. + * @retval 0 Operation failed. + * + */ +extern "C" int msc_set_request_hostname(Transaction *transaction, + const unsigned char *hostname) { + return transaction->setRequestHostName(reinterpret_cast(hostname)); +} + + } // namespace modsecurity diff --git a/test/regression/regression.cc b/test/regression/regression.cc index 759b7dbb82..962aff0e27 100644 --- a/test/regression/regression.cc +++ b/test/regression/regression.cc @@ -309,6 +309,10 @@ void perform_unit_test(ModSecurityTest *test, modsec_transaction->processConnection(t->clientIp.c_str(), t->clientPort, t->serverIp.c_str(), t->serverPort); + if (t->hostname != "") { + modsec_transaction->setRequestHostName(t->hostname); + } + actions(&r, modsec_transaction, &serverLog); #if 0 if (r.status != 200) { diff --git a/test/regression/regression_test.cc b/test/regression/regression_test.cc index 1580a0257f..01ad2aacc9 100644 --- a/test/regression/regression_test.cc +++ b/test/regression/regression_test.cc @@ -134,6 +134,9 @@ RegressionTest *RegressionTest::from_yajl_node(const yajl_val &node) { if (strcmp(key2, "port") == 0) { u->serverPort = YAJL_GET_INTEGER(val2); } + if (strcmp(key2, "hostname") == 0) { + u->hostname = YAJL_GET_STRING(val2); + } } } if (strcmp(key, "request") == 0) { diff --git a/test/regression/regression_test.h b/test/regression/regression_test.h index 5ed93b86f9..eb37986723 100644 --- a/test/regression/regression_test.h +++ b/test/regression/regression_test.h @@ -61,6 +61,7 @@ class RegressionTest { std::string serverIp; int clientPort; int serverPort; + std::string hostname; std::string method; std::string httpVersion; diff --git a/test/test-cases/regression/fn-setHostname.json b/test/test-cases/regression/fn-setHostname.json new file mode 100644 index 0000000000..33d9069545 --- /dev/null +++ b/test/test-cases/regression/fn-setHostname.json @@ -0,0 +1,41 @@ +[ + { + "enabled":1, + "version_min":300000, + "title":"Testing function :: setRequestHostName", + "client": { + "ip":"200.249.12.31" + }, + "server":{ + "ip":"200.249.12.31", + "port":80, + "hostname":"modsecurity.org" + }, + "request": { + "headers": { + "Host":"www.modsecurity.org" + }, + "uri":"/foo?q=attack", + "http_version": 1.1 + }, + "response":{ + "headers":{ + "Date":"Mon, 13 Jul 2015 20:02:41 GMT", + "Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT", + "Content-Type":"text/plain" + }, + "body":[ + "denystring" + ] + }, + "expected":{ + "http_code": 200, + "debug_log": "[hostname: \"modsecurity.org\"]" + }, + "rules":[ + "SecRuleEngine On", + "SecResponseBodyAccess On", + "SecRule ARGS_GET \"@contains attack\" \"id:1,phase:2,deny\"" + ] + } +]