mirror of
https://github.com/falcosecurity/falco.git
synced 2025-09-05 16:50:34 +00:00
Rule loader changes to support result objects
Changes to the rule loader to support result objects: - Instead of throwing falco_exception on internal error, throw a rule_load_exception instead, which contains distinct error/message/context information. - A context object contains a chain of location structs chaining from the document root to the object where the error occurred. Each location has a file position (as a YAML::Mark), an item type (e.g. "rule", "list", "exception"), and an item name (e.g. "Write Below Etc"). This will allow showing the exact location of an error (e.g. list item/exception field) while also remembering the item that contained it. - All the _info structs now contain a context so errors that occur after yaml parsing can still point to the original location in the yaml file. - rule_loader::result is an implementation of the abstract class defined in falco_load_result. The implementation keeps track of a list of errors/warnigns that used to be in the configuration object, - Clean up compile_ methods to just throw rule_load_exceptions or return nothing, and ensure that all rule_load_exceptions are caught in compile(). When caught, errors are added to the result object. Signed-off-by: Mark Stemm <mark.stemm@gmail.com>
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -20,8 +20,10 @@ limitations under the License.
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <yaml-cpp/yaml.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "falco_rule.h"
|
||||
#include "falco_source.h"
|
||||
#include "falco_load_result.h"
|
||||
#include "indexed_vector.h"
|
||||
|
||||
|
||||
@@ -31,34 +33,111 @@ limitations under the License.
|
||||
class rule_loader
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
\brief Represents a section of text from which a certain info
|
||||
struct has been decoded
|
||||
*/
|
||||
struct context
|
||||
class context
|
||||
{
|
||||
std::string content;
|
||||
|
||||
/*!
|
||||
\brief Wraps an error by adding info about the text section
|
||||
*/
|
||||
inline std::string error(std::string err) const
|
||||
public:
|
||||
struct location
|
||||
{
|
||||
std::string cnt = content;
|
||||
err += "\n---\n";
|
||||
err += trim(cnt);
|
||||
err += "\n---";
|
||||
return err;
|
||||
}
|
||||
// The original location in the document
|
||||
YAML::Mark mark;
|
||||
|
||||
/*!
|
||||
\brief Appends another text section info to this one
|
||||
*/
|
||||
inline void append(context& m)
|
||||
{
|
||||
content += "\n\n";
|
||||
content += m.content;
|
||||
}
|
||||
// The kind of item at this location
|
||||
// (e.g. "list", "macro", "rule", "exception", etc)
|
||||
std::string item_type;
|
||||
|
||||
// The name of this item (e.g. "Write Below Etc",
|
||||
// etc).
|
||||
std::string item_name;
|
||||
};
|
||||
|
||||
context(const std::string& name);
|
||||
context(const YAML::Node& mark,
|
||||
const std::string item_type,
|
||||
const std::string item_name,
|
||||
const context& parent);
|
||||
virtual ~context() = default;
|
||||
|
||||
// Return a snippet of the provided rules content
|
||||
// corresponding to this context.
|
||||
std::string snippet(const std::string& content) const;
|
||||
|
||||
std::string as_string();
|
||||
nlohmann::json as_json();
|
||||
|
||||
private:
|
||||
std::string name;
|
||||
|
||||
// A chain of locations from the current item, its
|
||||
// parent, possibly older ancestors.
|
||||
std::vector<location> m_locs;
|
||||
};
|
||||
|
||||
struct warning
|
||||
{
|
||||
falco::load_result::warning_code wc;
|
||||
std::string msg;
|
||||
context ctx;
|
||||
std::string snippet;
|
||||
};
|
||||
|
||||
struct error
|
||||
{
|
||||
falco::load_result::error_code ec;
|
||||
std::string msg;
|
||||
context ctx;
|
||||
std::string snippet;
|
||||
};
|
||||
|
||||
class rule_load_exception : public std::exception
|
||||
{
|
||||
public:
|
||||
rule_load_exception(falco::load_result::error_code ec, std::string msg, const context& ctx);
|
||||
virtual ~rule_load_exception();
|
||||
const char* what();
|
||||
|
||||
falco::load_result::error_code ec;
|
||||
std::string msg;
|
||||
context ctx;
|
||||
|
||||
std::string errstr;
|
||||
};
|
||||
|
||||
/*!
|
||||
\brief Contains the result of loading rule definitions
|
||||
*/
|
||||
class result : public falco::load_result
|
||||
{
|
||||
public:
|
||||
result(const std::string &name);
|
||||
virtual ~result() = default;
|
||||
|
||||
virtual bool successful() override;
|
||||
virtual bool has_warnings() override;
|
||||
virtual const std::string& as_string(bool verbose) override;
|
||||
virtual const nlohmann::json& as_json() override;
|
||||
|
||||
void add_error(falco::load_result::error_code ec,
|
||||
const std::string& msg,
|
||||
const context& ctx,
|
||||
const std::string& rules_content);
|
||||
|
||||
void add_warning(falco::load_result::warning_code ec,
|
||||
const std::string& msg,
|
||||
const context& ctx,
|
||||
const std::string& rules_content);
|
||||
protected:
|
||||
|
||||
const std::string& as_summary_string();
|
||||
const std::string& as_verbose_string();
|
||||
std::string name;
|
||||
bool success;
|
||||
|
||||
std::vector<error> errors;
|
||||
std::vector<warning> warnings;
|
||||
|
||||
std::string res_summary_string;
|
||||
std::string res_verbose_string;
|
||||
nlohmann::json res_json;
|
||||
};
|
||||
|
||||
/*!
|
||||
@@ -68,13 +147,17 @@ public:
|
||||
{
|
||||
explicit configuration(
|
||||
const std::string& cont,
|
||||
const indexed_vector<falco_source>& srcs)
|
||||
: content(cont), sources(srcs) {}
|
||||
const indexed_vector<falco_source>& srcs,
|
||||
std::string name)
|
||||
: content(cont), sources(srcs), name(name)
|
||||
{
|
||||
res.reset(new result(name));
|
||||
}
|
||||
|
||||
const std::string& content;
|
||||
const indexed_vector<falco_source>& sources;
|
||||
std::vector<std::string> errors;
|
||||
std::vector<std::string> warnings;
|
||||
std::string name;
|
||||
std::unique_ptr<result> res;
|
||||
std::string output_extra;
|
||||
uint16_t default_ruleset_id;
|
||||
bool replace_output_container_info;
|
||||
@@ -86,6 +169,10 @@ public:
|
||||
*/
|
||||
struct engine_version_info
|
||||
{
|
||||
engine_version_info(context &ctx);
|
||||
~engine_version_info() = default;
|
||||
|
||||
context ctx;
|
||||
uint32_t version;
|
||||
};
|
||||
|
||||
@@ -94,6 +181,14 @@ public:
|
||||
*/
|
||||
struct plugin_version_info
|
||||
{
|
||||
// This differs from the other _info structs by having
|
||||
// a default constructor. This allows it to be used
|
||||
// by falco_engine, which aliases the type.
|
||||
plugin_version_info();
|
||||
plugin_version_info(context &ctx);
|
||||
~plugin_version_info() = default;
|
||||
|
||||
context ctx;
|
||||
std::string name;
|
||||
std::string version;
|
||||
};
|
||||
@@ -103,6 +198,9 @@ public:
|
||||
*/
|
||||
struct list_info
|
||||
{
|
||||
list_info(context &ctx);
|
||||
~list_info() = default;
|
||||
|
||||
context ctx;
|
||||
bool used;
|
||||
size_t index;
|
||||
@@ -116,7 +214,11 @@ public:
|
||||
*/
|
||||
struct macro_info
|
||||
{
|
||||
macro_info(context &ctx);
|
||||
~macro_info() = default;
|
||||
|
||||
context ctx;
|
||||
context cond_ctx;
|
||||
bool used;
|
||||
size_t index;
|
||||
size_t visibility;
|
||||
@@ -130,6 +232,9 @@ public:
|
||||
*/
|
||||
struct rule_exception_info
|
||||
{
|
||||
rule_exception_info(context &ctx);
|
||||
~rule_exception_info() = default;
|
||||
|
||||
/*!
|
||||
\brief This is necessary due to the dynamic-typed nature of
|
||||
exceptions. Each of fields, comps, and values, can either be a
|
||||
@@ -148,6 +253,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
context ctx;
|
||||
std::string name;
|
||||
entry fields;
|
||||
entry comps;
|
||||
@@ -159,7 +265,12 @@ public:
|
||||
*/
|
||||
struct rule_info
|
||||
{
|
||||
rule_info(context &ctx);
|
||||
~rule_info() = default;
|
||||
|
||||
context ctx;
|
||||
context cond_ctx;
|
||||
context output_ctx;
|
||||
size_t index;
|
||||
size_t visibility;
|
||||
std::string name;
|
||||
@@ -185,7 +296,7 @@ public:
|
||||
/*!
|
||||
\brief Uses the internal state to compile a list of falco_rules
|
||||
*/
|
||||
virtual bool compile(configuration& cfg, indexed_vector<falco_rule>& out) const;
|
||||
virtual void compile(configuration& cfg, indexed_vector<falco_rule>& out) const;
|
||||
|
||||
/*!
|
||||
\brief Returns the set of all required versions for each plugin according
|
||||
|
Reference in New Issue
Block a user