Falco engine support for plugins

Mostly plugins are just handled as a new filter/formatter factory with
a new source based on the loaded input plugin, but there are a few
changes at the engine level:

- is_source_valid returns whether a filter/formatter factory exists
  for a given source. Will be used by rules loaded to skip rules for
  an unknown source.

- the falco engine now holds the required_plugin_version predicates
  found in rules files and a method is_plugin_compatible returns whether
  a plugin semver is compatible with the predicates in the rules

- Update the falco engine version and fields checksum for plugins

Co-authored-by: Leonardo Grasso <me@leonardograsso.com>
Co-authored-by: Loris Degioanni <loris@sysdig.com>
Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
This commit is contained in:
Mark Stemm
2021-10-15 16:36:30 -07:00
committed by poiana
parent 69e32f7ed1
commit 9075eea62f
3 changed files with 68 additions and 10 deletions

View File

@@ -19,6 +19,9 @@ limitations under the License.
#include <string>
#include <fstream>
#include <sinsp.h>
#include <plugin.h>
#include "falco_engine.h"
#include "falco_utils.h"
#include "falco_engine_version.h"
@@ -52,6 +55,8 @@ falco_engine::falco_engine(bool seed_rng, const std::string& alternate_lua_dir)
falco_common::init(m_lua_main_filename.c_str(), alternate_lua_dir.c_str());
falco_rules::init(m_ls);
m_required_plugin_versions.clear();
if(seed_rng)
{
srandom((unsigned) getpid());
@@ -152,7 +157,7 @@ void falco_engine::load_rules(const string &rules_content, bool verbose, bool al
}
}
m_rules->load_rules(rules_content, verbose, all_events, m_extra, m_replace_container_info, m_min_priority, required_engine_version);
m_rules->load_rules(rules_content, verbose, all_events, m_extra, m_replace_container_info, m_min_priority, required_engine_version, m_required_plugin_versions);
}
void falco_engine::load_rules_file(const string &rules_filename, bool verbose, bool all_events)
@@ -325,9 +330,9 @@ unique_ptr<falco_engine::rule_result> falco_engine::process_event(std::string &s
return process_event(source, ev, m_default_ruleset_id);
}
void falco_engine::add_source(std::string &source,
std::shared_ptr<gen_event_filter_factory> filter_factory,
std::shared_ptr<gen_event_formatter_factory> formatter_factory)
void falco_engine::add_source(const std::string &source,
std::shared_ptr<gen_event_filter_factory> filter_factory,
std::shared_ptr<gen_event_formatter_factory> formatter_factory)
{
m_filter_factories[source] = filter_factory;
m_format_factories[source] = formatter_factory;
@@ -427,6 +432,42 @@ void falco_engine::add_filter(std::shared_ptr<gen_event_filter> filter,
it->second->add(rule, tags, filter);
}
bool falco_engine::is_source_valid(const std::string &source)
{
return (m_rulesets.find(source) != m_rulesets.end());
}
bool falco_engine::is_plugin_compatible(const std::string &name,
const std::string &version,
std::string &required_version)
{
sinsp_plugin::version plugin_version(version.c_str());
if(!plugin_version.m_valid)
{
throw falco_exception(string("Plugin version string ") + version + " not valid");
}
if(m_required_plugin_versions.find(name) == m_required_plugin_versions.end())
{
// No required engine versions, so no restrictions. Compatible.
return true;
}
for(auto &rversion : m_required_plugin_versions[name])
{
sinsp_plugin::version req_version(rversion.c_str());
if(req_version.m_version_major > plugin_version.m_version_major)
{
required_version = rversion;
return false;
}
}
return true;
}
void falco_engine::clear_filters()
{
m_rulesets.clear();
@@ -436,6 +477,8 @@ void falco_engine::clear_filters()
std::shared_ptr<falco_ruleset> ruleset(new falco_ruleset());
m_rulesets[it.first] = ruleset;
}
m_required_plugin_versions.clear();
}
void falco_engine::set_sampling_ratio(uint32_t sampling_ratio)