sync code

This commit is contained in:
Ned Wright
2024-10-14 14:51:28 +00:00
parent b58f7781e6
commit c2ea2cda6d
89 changed files with 2545 additions and 447 deletions

View File

@@ -157,6 +157,9 @@ MatchQuery::load(cereal::JSONInputArchive &archive_in)
dbgDebug(D_RULEBASE_CONFIG) << "Failed to compile regex. Error: " << e.what();
}
}
if (isKeyTypeIp()) {
sortAndMergeIpRangesValues();
}
first_value = *(value.begin());
}
break;
@@ -301,7 +304,7 @@ MatchQuery::matchAttributes(
bool negate = type == MatchQuery::Conditions::NotEquals || type == MatchQuery::Conditions::NotIn;
bool match = false;
if (isIP()) {
if (isKeyTypeIp()) {
match = matchAttributesIp(values);
} else if (isRegEx()) {
match = matchAttributesRegEx(values, matched_override_keywords);
@@ -352,10 +355,18 @@ MatchQuery::matchAttributesString(const set<string> &values) const
bool
MatchQuery::matchAttributesIp(const set<string> &values) const
{
for (const IPRange &rule_ip_range : ip_addr_value) {
for (const string &requested_value : values) {
IpAddress ip_addr = IPUtilities::createIpFromString(requested_value);
if (IPUtilities::isIpAddrInRange(rule_ip_range, ip_addr)) return true;
for (const string &requested_value : values) {
int left = 0;
int right = ip_addr_value.size() - 1;
IpAddress ip_addr = IPUtilities::createIpFromString(requested_value);
while (left <= right) {
int mid = left + (right - left) / 2;
if (IPUtilities::isIpAddrInRange(ip_addr_value[mid], ip_addr)) return true;
if (ip_addr_value[mid].start < ip_addr) {
left = mid + 1;
} else {
right = mid - 1;
}
}
}
return false;
@@ -367,8 +378,23 @@ MatchQuery::isRegEx() const
return key != "protectionName";
}
bool
MatchQuery::isIP() const
void
MatchQuery::sortAndMergeIpRangesValues()
{
return key == "sourceIP" || key == "destinationIP";
if (ip_addr_value.empty()) return;
sort(ip_addr_value.begin(), ip_addr_value.end());
size_t mergedIndex = 0;
for (size_t i = 1; i < ip_addr_value.size(); ++i) {
if (ip_addr_value[i].start <= ip_addr_value[mergedIndex].end) {
if (ip_addr_value[mergedIndex].end <= ip_addr_value[i].end) {
ip_addr_value[mergedIndex].end = ip_addr_value[i].end;
}
} else {
++mergedIndex;
ip_addr_value[mergedIndex] = ip_addr_value[i];
}
}
ip_addr_value.resize(mergedIndex + 1);
}

View File

@@ -22,7 +22,10 @@ bool
operator<(const IpAddress &this_ip_addr, const IpAddress &other_ip_addr)
{
if (this_ip_addr.ip_type < other_ip_addr.ip_type) return true;
if (this_ip_addr.ip_type == IP_VERSION_4) return this_ip_addr.addr4_t.s_addr < other_ip_addr.addr4_t.s_addr;
if (this_ip_addr.ip_type > other_ip_addr.ip_type) return false;
if (this_ip_addr.ip_type == IP_VERSION_4) {
return ntohl(this_ip_addr.addr4_t.s_addr) < ntohl(other_ip_addr.addr4_t.s_addr);
}
return memcmp(&this_ip_addr.addr6_t, &other_ip_addr.addr6_t, sizeof(struct in6_addr)) < 0;
}
@@ -33,6 +36,19 @@ operator==(const IpAddress &this_ip_addr, const IpAddress &other_ip_addr)
if (this_ip_addr.ip_type == IP_VERSION_4) return this_ip_addr.addr4_t.s_addr == other_ip_addr.addr4_t.s_addr;
return memcmp(&this_ip_addr.addr6_t, &other_ip_addr.addr6_t, sizeof(struct in6_addr)) == 0;
}
bool
operator<=(const IpAddress &this_ip_addr, const IpAddress &other_ip_addr)
{
if (this_ip_addr < other_ip_addr || this_ip_addr == other_ip_addr) return true;
return false;
}
bool
operator<(const IPRange &range1, const IPRange &range2)
{
return range1.start < range2.start || (range1.start == range2.start && range1.end < range2.end);
}
// LCOV_EXCL_STOP
Maybe<pair<string, int>>

View File

@@ -5,6 +5,8 @@
using namespace std;
USE_DEBUG_FLAG(D_KEYWORD);
static const string whitespaces = " \t";
static string
@@ -14,6 +16,13 @@ getSubStrNoPadding(const string &str, uint start, uint end)
auto r_end = str.find_last_not_of(whitespaces, end-1);
if (r_end==string::npos || r_start==string::npos || r_start>r_end) {
dbgWarning(D_KEYWORD)
<< "Can't extract substring from '"
<< str
<< "', padded start: "
<< r_start
<< ", padded end: "
<< r_end;
throw KeywordError("Found an empty section in the '"+ str + "'");
}
@@ -45,13 +54,24 @@ split(const string &str, const string &delim, uint start = 0)
}
default:
if (!in_string && delim.find(str[index])!=string::npos) {
res.push_back(getSubStrNoPadding(str, part_start, index));
if (part_start == index) {
dbgTrace(D_KEYWORD) << "Encountered consecutive delimiter in: " << str;
} else {
res.push_back(getSubStrNoPadding(str, part_start, index));
}
part_start = index+1;
}
}
}
if (escape||in_string) throw KeywordError("Split has ended in the middle of the parsing");
if (escape||in_string) {
dbgWarning(D_KEYWORD)
<< "Failed to split "
<< str
<< ". Split ended in "
<< (escape ? "escape" : "middle of string");
throw KeywordError("Split has ended in the middle of the parsing");
}
if (str.find_first_not_of(whitespaces, part_start)!=string::npos) {
res.push_back(getSubStrNoPadding(str, part_start, str.size()));

View File

@@ -55,6 +55,13 @@ TEST_F(KeywordsRuleTest, data_basic_test) {
EXPECT_FALSE(ruleRun("data: \"75\", part HTTP_RESPONSE_BODY;"));
}
TEST_F(KeywordsRuleTest, consecutive_delimiter_test) {
appendBuffer("HTTP_RESPONSE_BODY", "123456789");
EXPECT_TRUE(ruleRun("data: \"234\" , part HTTP_RESPONSE_BODY;"));
EXPECT_FALSE(ruleRun("data: \"75\", part HTTP_RESPONSE_BODY;"));
}
TEST_F(KeywordsRuleTest, data_relative_test) {
appendBuffer("HTTP_RESPONSE_BODY", "1234567890");