From ab77a5d6873d35d7af927d0bc28cd3a208683799 Mon Sep 17 00:00:00 2001 From: Jason Dellaluce Date: Thu, 31 Aug 2023 13:52:29 +0000 Subject: [PATCH] update(userspace/engine): refactor rule describe methods to accept plugins Signed-off-by: Jason Dellaluce --- userspace/engine/falco_engine.cpp | 98 +++++++++++-------- userspace/engine/falco_engine.h | 38 ++++--- .../falco/app/actions/load_rules_files.cpp | 6 +- 3 files changed, 86 insertions(+), 56 deletions(-) diff --git a/userspace/engine/falco_engine.cpp b/userspace/engine/falco_engine.cpp index 505237aa..e218d1c3 100644 --- a/userspace/engine/falco_engine.cpp +++ b/userspace/engine/falco_engine.cpp @@ -469,7 +469,7 @@ std::size_t falco_engine::add_source(const std::string &source, return m_sources.insert(src, source); } -void falco_engine::describe_rule(std::string *rule, bool json) const +void falco_engine::describe_rule(std::string *rule, const std::vector>& plugins, bool json) const { if(!json) { @@ -498,7 +498,6 @@ void falco_engine::describe_rule(std::string *rule, bool json) const return; } - std::unique_ptr insp(new sinsp()); Json::FastWriter writer; std::string json_str; @@ -541,7 +540,7 @@ void falco_engine::describe_rule(std::string *rule, bool json) const { auto ri = m_rule_collector.rules().at(r.name); Json::Value rule; - get_json_details(r, *ri, insp.get(), rule); + get_json_details(rule, r, *ri, plugins); // Append to rule array rules_array.append(rule); @@ -553,7 +552,7 @@ void falco_engine::describe_rule(std::string *rule, bool json) const for(const auto &m : m_rule_collector.macros()) { Json::Value macro; - get_json_details(m, macro); + get_json_details(macro, m, plugins); macros_array.append(macro); } output["macros"] = macros_array; @@ -563,7 +562,7 @@ void falco_engine::describe_rule(std::string *rule, bool json) const for(const auto &l : m_rule_collector.lists()) { Json::Value list; - get_json_details(l, list); + get_json_details(list, l); lists_array.append(list); } output["lists"] = lists_array; @@ -580,17 +579,18 @@ void falco_engine::describe_rule(std::string *rule, bool json) const } auto r = m_rules.at(ri->name); Json::Value rule; - get_json_details(*r, *ri, insp.get(), rule); + get_json_details(rule, *r, *ri, plugins); json_str = writer.write(rule); } fprintf(stdout, "%s", json_str.c_str()); } -void falco_engine::get_json_details(const falco_rule &r, +void falco_engine::get_json_details( + Json::Value &out, + const falco_rule &r, const rule_loader::rule_info &ri, - sinsp *insp, - Json::Value &rule) const + const std::vector>& plugins) const { Json::Value rule_info; @@ -608,25 +608,26 @@ void falco_engine::get_json_details(const falco_rule &r, tags.append(t); } rule_info["tags"] = tags; - rule["info"] = rule_info; + out["info"] = rule_info; // Parse rule condition and build the AST // Assumption: no exception because rules have already been loaded. auto ast = libsinsp::filter::parser(ri.cond).parse(); Json::Value json_details; - get_json_details(ast.get(), json_details); - rule["details"] = json_details; + get_json_details(json_details, ast.get()); + out["details"] = json_details; // Get fields from output string auto fmt = create_formatter(r.source, r.output); std::vector out_fields; fmt->get_field_names(out_fields); + // TODO: check these too for plugins Json::Value outputFields = Json::arrayValue; for(const auto &of : out_fields) { outputFields.append(of); } - rule["details"]["output_fields"] = outputFields; + out["details"]["output_fields"] = outputFields; // Get fields from exceptions Json::Value exception_fields = Json::arrayValue; @@ -634,7 +635,7 @@ void falco_engine::get_json_details(const falco_rule &r, { exception_fields.append(f); } - rule["details"]["exception_fields"] = exception_fields; + out["details"]["exception_fields"] = exception_fields; // Get names and operators from exceptions Json::Value exception_names = Json::arrayValue; @@ -665,42 +666,45 @@ void falco_engine::get_json_details(const falco_rule &r, exception_operators.append(e.comps.item); } } - rule["details"]["exceptions"] = exception_names; - rule["details"]["exception_operators"] = exception_operators; + out["details"]["exceptions"] = exception_names; + out["details"]["exception_operators"] = exception_operators; if(ri.source == falco_common::syscall_source) { // Store event types Json::Value events; - get_json_evt_types(ast.get(), events); - rule["details"]["events"] = events; + get_json_evt_types(events, ast.get()); + out["details"]["events"] = events; } } -void falco_engine::get_json_details(const rule_loader::macro_info& m, - Json::Value& macro) const +void falco_engine::get_json_details( + Json::Value& out, + const rule_loader::macro_info& m, + const std::vector>& plugins) const { Json::Value macro_info; macro_info["name"] = m.name; macro_info["condition"] = m.cond; - macro["info"] = macro_info; + out["info"] = macro_info; // Assumption: no exception because rules have already been loaded. auto ast = libsinsp::filter::parser(m.cond).parse(); Json::Value json_details; - get_json_details(ast.get(), json_details); - macro["details"] = json_details; + get_json_details(json_details, ast.get()); + out["details"] = json_details; // Store event types Json::Value events; - get_json_evt_types(ast.get(), events); - macro["details"]["events"] = events; + get_json_evt_types(events, ast.get()); + out["details"]["events"] = events; } -void falco_engine::get_json_details(const rule_loader::list_info& l, - Json::Value& list) const +void falco_engine::get_json_details( + Json::Value& out, + const rule_loader::list_info& l) const { Json::Value list_info; list_info["name"] = l.name; @@ -718,12 +722,14 @@ void falco_engine::get_json_details(const rule_loader::list_info& l, } list_info["items"] = items; - list["info"] = list_info; - list["details"]["lists"] = lists; + out["info"] = list_info; + out["details"]["lists"] = lists; + out["details"]["plugins"] = Json::arrayValue; } -void falco_engine::get_json_details(libsinsp::filter::ast::expr* ast, - Json::Value& output) const +void falco_engine::get_json_details( + Json::Value& out, + libsinsp::filter::ast::expr* ast) const { filter_details details; for(const auto &m : m_rule_collector.macros()) @@ -745,46 +751,56 @@ void falco_engine::get_json_details(libsinsp::filter::ast::expr* ast, { macros.append(m); } - output["macros"] = macros; + out["macros"] = macros; Json::Value operators = Json::arrayValue; for(const auto &o : details.operators) { operators.append(o); } - output["operators"] = operators; + out["operators"] = operators; Json::Value condition_fields = Json::arrayValue; for(const auto &f : details.fields) { condition_fields.append(f); } - output["condition_fields"] = condition_fields; + out["condition_fields"] = condition_fields; Json::Value lists = Json::arrayValue; for(const auto &l : details.lists) { lists.append(l); } - output["lists"] = lists; - - details.reset(); + out["lists"] = lists; } -void falco_engine::get_json_evt_types(libsinsp::filter::ast::expr* ast, - Json::Value& output) const +void falco_engine::get_json_evt_types( + Json::Value& out, + libsinsp::filter::ast::expr* ast) const { - output = Json::arrayValue; + out = Json::arrayValue; auto evtcodes = libsinsp::filter::ast::ppm_event_codes(ast); auto syscodes = libsinsp::filter::ast::ppm_sc_codes(ast); auto syscodes_to_evt_names = libsinsp::events::sc_set_to_event_names(syscodes); auto evtcodes_to_evt_names = libsinsp::events::event_set_to_names(evtcodes, false); for (const auto& n : unordered_set_union(syscodes_to_evt_names, evtcodes_to_evt_names)) { - output.append(n); + out.append(n); } } +void falco_engine::get_json_used_plugins( + Json::Value& out, + const std::string& source, + const std::unordered_set& evttypes, + const std::unordered_set& fields, + const std::vector>& plugins) const +{ + // TODO + out = Json::arrayValue; +} + void falco_engine::print_stats() const { diff --git a/userspace/engine/falco_engine.h b/userspace/engine/falco_engine.h index cb24e3c6..e1210410 100644 --- a/userspace/engine/falco_engine.h +++ b/userspace/engine/falco_engine.h @@ -125,7 +125,7 @@ public: // Print details on the given rule. If rule is NULL, print // details on all rules. // - void describe_rule(std::string *rule, bool json) const; + void describe_rule(std::string *rule, const std::vector>& plugins, bool json) const; // // Print statistics on how many events matched each rule. @@ -303,18 +303,30 @@ private: inline bool should_drop_evt() const; // Retrieve json details from rules, macros, lists - void get_json_details(const falco_rule& r, - const rule_loader::rule_info& ri, - sinsp* insp, - Json::Value& rule) const; - void get_json_details(const rule_loader::macro_info& m, - Json::Value& macro) const; - void get_json_details(const rule_loader::list_info& l, - Json::Value& list) const; - void get_json_details(libsinsp::filter::ast::expr* ast, - Json::Value& output) const; - void get_json_evt_types(libsinsp::filter::ast::expr* ast, - Json::Value& output) const; + void get_json_details( + Json::Value& out, + const falco_rule& r, + const rule_loader::rule_info& ri, + const std::vector>& plugins) const; + void get_json_details( + Json::Value& out, + const rule_loader::macro_info& m, + const std::vector>& plugins) const; + void get_json_details( + Json::Value& out, + const rule_loader::list_info& l) const; + void get_json_details( + Json::Value& out, + libsinsp::filter::ast::expr* ast) const; + void get_json_evt_types( + Json::Value& out, + libsinsp::filter::ast::expr* ast) const; + void get_json_used_plugins( + Json::Value& out, + const std::string& source, + const std::unordered_set& evttypes, + const std::unordered_set& fields, + const std::vector>& plugins) const; rule_loader::collector m_rule_collector; indexed_vector m_rules; diff --git a/userspace/falco/app/actions/load_rules_files.cpp b/userspace/falco/app/actions/load_rules_files.cpp index 592b0184..5b4d8de1 100644 --- a/userspace/falco/app/actions/load_rules_files.cpp +++ b/userspace/falco/app/actions/load_rules_files.cpp @@ -157,13 +157,15 @@ falco::app::run_result falco::app::actions::load_rules_files(falco::app::state& if (s.options.describe_all_rules) { - s.engine->describe_rule(NULL, s.config->m_json_output); + const auto& plugins = s.offline_inspector->get_plugin_manager()->plugins(); + s.engine->describe_rule(NULL, plugins, s.config->m_json_output); return run_result::exit(); } if (!s.options.describe_rule.empty()) { - s.engine->describe_rule(&(s.options.describe_rule), s.config->m_json_output); + const auto& plugins = s.offline_inspector->get_plugin_manager()->plugins(); + s.engine->describe_rule(&(s.options.describe_rule), plugins, s.config->m_json_output); return run_result::exit(); }