#pragma once
#include <array>
#include <memory>
#include <string>
#include <string_view>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#include "action_mapper.hpp"
#include "builder/module_builder.hpp"
#include "exclusion/input_filter.hpp"
#include "exclusion/rule_filter.hpp"
#include "matcher/base.hpp"
#include "module.hpp"
#include "module_category.hpp"
#include "obfuscator.hpp"
#include "processor/base.hpp"
#include "rule.hpp"
#include "scanner.hpp"
#include "target_address.hpp"
namespace ddwaf {
struct ruleset {
void insert_rules(std::shared_ptr<const std::vector<core_rule>> base,
std::shared_ptr<const std::vector<core_rule>> user)
{
base_rules = std::move(base);
user_rules = std::move(user);
for (const auto &rule : *base_rules) { rule.get_addresses(rule_addresses); }
for (const auto &rule : *user_rules) { rule.get_addresses(rule_addresses); }
rule_module_set_builder builder;
rule_modules = builder.build(*base_rules, *user_rules);
}
void insert_filters(std::shared_ptr<const std::vector<rule_filter>> filters)
{
rule_filters = std::move(filters);
for (const auto &filter : *rule_filters) { filter.get_addresses(filter_addresses); }
}
void insert_filters(std::shared_ptr<const std::vector<input_filter>> filters)
{
input_filters = std::move(filters);
for (const auto &filter : *input_filters) { filter.get_addresses(filter_addresses); }
}
void insert_preprocessors(
std::shared_ptr<const std::vector<std::unique_ptr<base_processor>>> processors)
{
preprocessors = std::move(processors);
for (const auto &proc : *preprocessors) { proc->get_addresses(preprocessor_addresses); }
}
void insert_postprocessors(
std::shared_ptr<const std::vector<std::unique_ptr<base_processor>>> processors)
{
postprocessors = std::move(processors);
for (const auto &proc : *postprocessors) { proc->get_addresses(postprocessor_addresses); }
}
[[nodiscard]] const std::vector<const char *> &get_root_addresses()
{
if (root_addresses.empty()) {
std::unordered_set<target_index> known_targets;
for (const auto &[index, str] : rule_addresses) {
const auto &[it, res] = known_targets.emplace(index);
if (res) {
root_addresses.emplace_back(str.c_str());
}
}
for (const auto &[index, str] : filter_addresses) {
const auto &[it, res] = known_targets.emplace(index);
if (res) {
root_addresses.emplace_back(str.c_str());
}
}
for (const auto &[index, str] : preprocessor_addresses) {
const auto &[it, res] = known_targets.emplace(index);
if (res) {
root_addresses.emplace_back(str.c_str());
}
}
for (const auto &[index, str] : postprocessor_addresses) {
const auto &[it, res] = known_targets.emplace(index);
if (res) {
root_addresses.emplace_back(str.c_str());
}
}
}
return root_addresses;
}
[[nodiscard]] const std::vector<const char *> &get_available_action_types()
{
if (available_action_types.empty()) {
std::unordered_set<std::string_view> all_types;
all_types.reserve(actions->size());
auto maybe_add_action = [&](auto &&action) {
auto it = actions->find(action);
if (it == actions->end()) {
return;
}
auto [new_it, res] = all_types.emplace(it->second.type_str);
if (res) {
available_action_types.emplace_back(it->second.type_str.c_str());
}
};
for (const auto &rule : *base_rules) {
for (const auto &action : rule.get_actions()) { maybe_add_action(action); }
}
for (const auto &rule : *user_rules) {
for (const auto &action : rule.get_actions()) { maybe_add_action(action); }
}
for (const auto &filter : *rule_filters) { maybe_add_action(filter.get_action()); }
}
return available_action_types;
}
std::shared_ptr<const match_obfuscator> obfuscator;
std::shared_ptr<const std::vector<std::unique_ptr<base_processor>>> preprocessors;
std::shared_ptr<const std::vector<std::unique_ptr<base_processor>>> postprocessors;
std::shared_ptr<const std::vector<rule_filter>> rule_filters;
std::shared_ptr<const std::vector<input_filter>> input_filters;
std::shared_ptr<const std::vector<core_rule>> base_rules;
std::shared_ptr<const std::vector<core_rule>> user_rules;
std::shared_ptr<const matcher_mapper> rule_matchers;
std::shared_ptr<const matcher_mapper> exclusion_matchers;
std::shared_ptr<const std::vector<scanner>> scanners;
std::shared_ptr<const action_mapper> actions;
std::array<rule_module, rule_module_count> rule_modules;
std::unordered_map<target_index, std::string> rule_addresses;
std::unordered_map<target_index, std::string> filter_addresses;
std::unordered_map<target_index, std::string> preprocessor_addresses;
std::unordered_map<target_index, std::string> postprocessor_addresses;
std::vector<const char *> root_addresses;
std::vector<const char *> available_action_types;
};
}