mirror of
https://github.com/falcosecurity/falco.git
synced 2025-07-09 12:43:31 +00:00
200 lines
7.2 KiB
C++
200 lines
7.2 KiB
C++
// SPDX-License-Identifier: Apache-2.0
|
|
/*
|
|
Copyright (C) 2023 The Falco Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
#include <gtest/gtest.h>
|
|
#include <engine/evttype_index_ruleset.h>
|
|
|
|
#define RULESET_0 0
|
|
#define RULESET_1 1
|
|
#define RULESET_2 2
|
|
|
|
/* Helpers methods */
|
|
static std::shared_ptr<sinsp_filter_factory> create_factory(sinsp* inspector,
|
|
filter_check_list& list) {
|
|
return std::make_shared<sinsp_filter_factory>(inspector, list);
|
|
}
|
|
|
|
static std::shared_ptr<filter_ruleset> create_ruleset(std::shared_ptr<sinsp_filter_factory> f) {
|
|
return std::make_shared<evttype_index_ruleset>(f);
|
|
}
|
|
|
|
static std::shared_ptr<libsinsp::filter::ast::expr> create_ast(
|
|
std::shared_ptr<sinsp_filter_factory> f) {
|
|
libsinsp::filter::parser parser("evt.type=open");
|
|
return parser.parse();
|
|
}
|
|
|
|
static std::shared_ptr<sinsp_filter> create_filter(std::shared_ptr<sinsp_filter_factory> f,
|
|
libsinsp::filter::ast::expr* ast) {
|
|
sinsp_filter_compiler compiler(f, ast);
|
|
return std::shared_ptr<sinsp_filter>(compiler.compile());
|
|
}
|
|
|
|
TEST(Ruleset, enable_disable_rules_using_names) {
|
|
sinsp inspector;
|
|
|
|
sinsp_filter_check_list filterlist;
|
|
auto f = create_factory(&inspector, filterlist);
|
|
auto r = create_ruleset(f);
|
|
auto ast = create_ast(f);
|
|
auto filter = create_filter(f, ast.get());
|
|
|
|
falco_rule rule_A = {};
|
|
rule_A.name = "rule_A";
|
|
rule_A.source = falco_common::syscall_source;
|
|
|
|
falco_rule rule_B = {};
|
|
rule_B.name = "rule_B";
|
|
rule_B.source = falco_common::syscall_source;
|
|
|
|
falco_rule rule_C = {};
|
|
rule_C.name = "rule_C";
|
|
rule_C.source = falco_common::syscall_source;
|
|
|
|
r->add(rule_A, filter, ast);
|
|
r->add(rule_B, filter, ast);
|
|
r->add(rule_C, filter, ast);
|
|
|
|
/* Enable `rule_A` for RULESET_0 */
|
|
r->enable(rule_A.name, filter_ruleset::match_type::exact, RULESET_0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_0), 1);
|
|
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
|
|
|
|
/* Disable `rule_A` for RULESET_1, this should have no effect */
|
|
r->disable(rule_A.name, filter_ruleset::match_type::exact, RULESET_1);
|
|
ASSERT_EQ(r->enabled_count(RULESET_0), 1);
|
|
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
|
|
|
|
/* Enable a not existing rule for RULESET_2, this should have no effect */
|
|
r->disable("<NA>", filter_ruleset::match_type::exact, RULESET_2);
|
|
ASSERT_EQ(r->enabled_count(RULESET_0), 1);
|
|
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
|
|
|
|
/* Enable all rules for RULESET_0 */
|
|
r->enable("rule_", filter_ruleset::match_type::substring, RULESET_0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_0), 3);
|
|
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
|
|
|
|
/* Try to disable all rules with exact match for RULESET_0, this should have no effect */
|
|
r->disable("rule_", filter_ruleset::match_type::exact, RULESET_0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_0), 3);
|
|
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
|
|
|
|
/* Disable all rules for RULESET_0 */
|
|
r->disable("rule_", filter_ruleset::match_type::substring, RULESET_0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_0), 0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
|
|
|
|
/* Enable rule_C for RULESET_2 without exact_match */
|
|
r->enable("_C", filter_ruleset::match_type::substring, RULESET_2);
|
|
ASSERT_EQ(r->enabled_count(RULESET_0), 0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_2), 1);
|
|
|
|
/* Disable rule_C for RULESET_2 without exact_match */
|
|
r->disable("_C", filter_ruleset::match_type::substring, RULESET_2);
|
|
ASSERT_EQ(r->enabled_count(RULESET_0), 0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
|
|
|
|
/* Enable all rules for RULESET_0 with wildcard */
|
|
r->enable("*", filter_ruleset::match_type::wildcard, RULESET_0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_0), 3);
|
|
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
|
|
|
|
/* Disable rule C for RULESET_0 with wildcard */
|
|
r->disable("*C*", filter_ruleset::match_type::wildcard, RULESET_0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_0), 2);
|
|
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
|
|
|
|
/* Disable all rules for RULESET_0 with wildcard */
|
|
r->disable("*_*", filter_ruleset::match_type::wildcard, RULESET_0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_0), 0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
|
|
}
|
|
|
|
TEST(Ruleset, enable_disable_rules_using_tags) {
|
|
sinsp inspector;
|
|
|
|
sinsp_filter_check_list filterlist;
|
|
auto f = create_factory(&inspector, filterlist);
|
|
auto r = create_ruleset(f);
|
|
auto ast = create_ast(f);
|
|
auto filter = create_filter(f, ast.get());
|
|
|
|
falco_rule rule_A = {};
|
|
rule_A.name = "rule_A";
|
|
rule_A.source = falco_common::syscall_source;
|
|
rule_A.tags = {"first_rule_A_tag", "second_rule_A_tag", "common_tag"};
|
|
|
|
falco_rule rule_B = {};
|
|
rule_B.name = "rule_B";
|
|
rule_B.source = falco_common::syscall_source;
|
|
rule_B.tags = {"first_rule_B_tag", "second_rule_B_tag", "common_tag"};
|
|
|
|
r->add(rule_A, filter, ast);
|
|
r->add(rule_B, filter, ast);
|
|
|
|
/* Enable `rule_A` for RULESET_0 using its first tag */
|
|
r->enable_tags({"first_rule_A_tag"}, RULESET_0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_0), 1);
|
|
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
|
|
|
|
/* Disable `rule_A` for RULESET_1 using its first tag, this should have no effect */
|
|
r->disable_tags({"first_rule_A_tag"}, RULESET_1);
|
|
ASSERT_EQ(r->enabled_count(RULESET_0), 1);
|
|
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
|
|
|
|
/* Enable a not existing rule for RULESET_0, this should have no effect */
|
|
r->enable_tags({"<NA_tag>"}, RULESET_0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_0), 1);
|
|
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
|
|
|
|
/* Enable all rules for RULESET_2 */
|
|
r->enable_tags({"common_tag"}, RULESET_2);
|
|
ASSERT_EQ(r->enabled_count(RULESET_0), 1);
|
|
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_2), 2);
|
|
|
|
/* Disable `rule_A` for RULESET_0 using its second tag
|
|
* Note that we have previously enabled it using the first tag,
|
|
* so here we are using a different tag of the rule t disable it!
|
|
*/
|
|
r->disable_tags({"second_rule_A_tag"}, RULESET_0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_0), 0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_2), 2);
|
|
|
|
/* Disable all rules for RULESET_2 */
|
|
r->disable_tags({"common_tag"}, RULESET_2);
|
|
ASSERT_EQ(r->enabled_count(RULESET_0), 0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_1), 0);
|
|
ASSERT_EQ(r->enabled_count(RULESET_2), 0);
|
|
}
|