Adds support to the operator @ipMatchFromFile and @ipMatchF

This commit is contained in:
Felipe Zimmerle 2015-08-03 17:21:13 -03:00
parent 6cd4c0492a
commit 774d897351
9 changed files with 214 additions and 47 deletions

View File

@ -33,9 +33,9 @@ class IpMatch : public Operator {
bool evaluate(Assay *assay, const std::string &input);
bool init(const char **error);
virtual bool init(const char **error);
private:
protected:
Utils::IpTree m_tree;
};

View File

@ -22,21 +22,6 @@
namespace ModSecurity {
namespace operators {
bool IpMatchF::evaluate(Assay *assay) {
/**
* @todo Implement the operator IpMatchF.
* Reference: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#ipmatchf
*/
return true;
}
IpMatchF::IpMatchF(std::string op, std::string param,
bool negation)
: Operator() {
this->op = op;
this->param = param;
}
} // namespace operators
} // namespace ModSecurity

View File

@ -18,17 +18,16 @@
#include <string>
#include "operators/operator.h"
#include "operators/ip_match_from_file.h"
#ifdef __cplusplus
namespace ModSecurity {
namespace operators {
class IpMatchF : public Operator {
class IpMatchF : public IpMatchFromFile {
public:
/** @ingroup ModSecurity_Operator */
IpMatchF(std::string p, std::string o, bool i);
bool evaluate(Assay *assay);
IpMatchF(std::string op, std::string param, bool negation)
: IpMatchFromFile(op, param, negation) { }
};
} // namespace operators

View File

@ -22,21 +22,24 @@
namespace ModSecurity {
namespace operators {
bool IpMatchFromFile::evaluate(Assay *assay) {
/**
* @todo Implement the operator IpMatchFromFile.
* Reference: https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual#ipmatchfromfile
*/
return true;
bool IpMatchFromFile::init(const char **error) {
std::string e("");
bool res = false;
if (param.compare(0, 8, "https://") == 0) {
res = m_tree.addFromUrl(param, &e);
} else {
res = m_tree.addFromFile(param, &e);
}
if (res == false) {
*error = e.c_str();
}
return res;
}
IpMatchFromFile::IpMatchFromFile(std::string op, std::string param,
bool negation)
: Operator() {
this->op = op;
this->param = param;
}
} // namespace operators
} // namespace ModSecurity

View File

@ -17,17 +17,19 @@
#include <string>
#include "operators/operator.h"
#include "operators/ip_match.h"
#ifdef __cplusplus
namespace ModSecurity {
namespace operators {
class IpMatchFromFile : public Operator {
class IpMatchFromFile : public IpMatch {
public:
/** @ingroup ModSecurity_Operator */
IpMatchFromFile(std::string o, std::string p, bool i);
bool evaluate(Assay *assay);
IpMatchFromFile(std::string op, std::string param, bool negation)
: IpMatch(op, param, negation) { }
bool init(const char **error) override;
};
} // namespace operators

View File

@ -25,6 +25,7 @@
#include <iostream>
#include "utils/geo_lookup.h"
#include "utils/https_client.h"
namespace ModSecurity {
namespace Utils {
@ -77,16 +78,12 @@ IpTree::~IpTree() {
}
}
bool IpTree::addFromBuffer(const std::string& buffer, std::string *error) {
bool IpTree::addFromBuffer(std::istream *ss, std::string *error) {
char *error_msg = NULL;
std::stringstream ss;
std::string line;
ss << buffer;
int res = 0;
for (std::string line; std::getline(ss, line); ) {
res = ip_tree_from_param(buffer.c_str(), &m_tree, &error_msg);
for (std::string line; std::getline(*ss, line); ) {
res = ip_tree_from_param(line.c_str(), &m_tree, &error_msg);
if (res != 0) {
if (error_msg != NULL) {
error->assign(error_msg);
@ -99,6 +96,40 @@ bool IpTree::addFromBuffer(const std::string& buffer, std::string *error) {
}
bool IpTree::addFromBuffer(const std::string& buffer, std::string *error) {
std::stringstream ss;
ss << buffer;
return addFromBuffer(&ss, error);
}
bool IpTree::addFromFile(const std::string& file, std::string *error) {
std::ifstream myfile(file, std::ios::in);
if (myfile.is_open() == false) {
error->assign("Failed to open file: " + file);
return false;
}
return addFromBuffer(&myfile, error);
}
bool IpTree::addFromUrl(const std::string& url, std::string *error) {
HttpsClient c;
bool ret = c.download(url);
if (ret == false) {
error->assign(c.error);
} else {
ret = addFromBuffer(c.content, error);
}
return ret;
}
bool IpTree::contains(const std::string& ip) {
int res = 0;
char *error_msg = NULL;

View File

@ -37,8 +37,11 @@ class IpTree {
~IpTree();
bool contains(const std::string &ip);
bool addFromBuffer(const std::string& buffer, std::string *error);
void postOrderTraversal(TreeNode *node);
bool addFromBuffer(std::istream *ss, std::string *error);
bool addFromBuffer(const std::string& buffer, std::string *error);
bool addFromFile(const std::string& file, std::string *error);
bool addFromUrl(const std::string& url, std::string *error);
private:
TreeRoot *m_tree;
};

View File

@ -0,0 +1,4 @@
127.0.0.1
10.10.10.1
::1
200.249.12.31

View File

@ -0,0 +1,140 @@
[
{
"enabled":1,
"version_min":300000,
"title":"Testing Operator :: @ipMatchFromFile",
"client":{
"ip":"200.249.12.31",
"port":123
},
"server":{
"ip":"200.249.12.31",
"port":80
},
"request":{
"headers":{
"Host":"localhost",
"User-Agent":"curl/7.38.0",
"Accept":"*/*",
"Content-Length": "27",
"Content-Type": "application/x-www-form-urlencoded"
},
"uri":"/",
"protocol":"POST",
"body": [
"param1=value1&param2=value2"
]
},
"response":{
"headers":{
"Date":"Mon, 13 Jul 2015 20:02:41 GMT",
"Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT",
"Content-Type":"text/html"
},
"body":[
"no need."
]
},
"expected":{
"debug_log":"Rule returned 1"
},
"rules":[
"SecRuleEngine On",
"SecDebugLog \/tmp\/modsec_debug.log",
"SecDebugLogLevel 9",
"SecRule REMOTE_ADDR \"@ipMatchFromFile test-cases\/data\/ipMatchFromFile.txt\" \"phase:3,pass,t:trim\""
]
},
{
"enabled":1,
"version_min":300000,
"title":"Testing Operator :: @ipMatchFromFile - file not found",
"client":{
"ip":"200.249.12.31",
"port":123
},
"server":{
"ip":"200.249.12.31",
"port":80
},
"request":{
"headers":{
"Host":"localhost",
"User-Agent":"curl/7.38.0",
"Accept":"*/*",
"Content-Length": "27",
"Content-Type": "application/x-www-form-urlencoded"
},
"uri":"/",
"protocol":"POST",
"body": [
"param1=value1&param2=value2"
]
},
"response":{
"headers":{
"Date":"Mon, 13 Jul 2015 20:02:41 GMT",
"Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT",
"Content-Type":"text/html"
},
"body":[
"no need."
]
},
"expected":{
"parser_error":"Failed to open file: file-not-found.txt"
},
"rules":[
"SecRuleEngine On",
"SecDebugLog \/tmp\/modsec_debug.log",
"SecDebugLogLevel 9",
"SecRule REMOTE_ADDR \"@ipMatchFromFile file-not-found.txt\" \"phase:3,pass,t:trim\""
]
},
{
"enabled":1,
"version_min":300000,
"title":"Testing Operator :: @ipMatchFromFile - https",
"client":{
"ip":"8.8.4.4",
"port":123
},
"server":{
"ip":"200.249.12.31",
"port":80
},
"request":{
"headers":{
"Host":"localhost",
"User-Agent":"curl/7.38.0",
"Accept":"*/*",
"Content-Length": "27",
"Content-Type": "application/x-www-form-urlencoded"
},
"uri":"/",
"protocol":"POST",
"body": [
"param1=value1&param2=value2"
]
},
"response":{
"headers":{
"Date":"Mon, 13 Jul 2015 20:02:41 GMT",
"Last-Modified":"Sun, 26 Oct 2014 22:33:37 GMT",
"Content-Type":"text/html"
},
"body":[
"no need."
]
},
"expected":{
"debug_log":"Rule returned 1."
},
"rules":[
"SecRuleEngine On",
"SecDebugLog \/tmp\/modsec_debug.log",
"SecDebugLogLevel 9",
"SecRule REMOTE_ADDR \"@ipMatchFromFile https://www.modsecurity.org/modsecurity-regression-test.txt\" \"phase:3,pass,t:trim\""
]
}
]