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 <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <yaml-cpp/yaml.h>
|
#include <yaml-cpp/yaml.h>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
#include "falco_rule.h"
|
#include "falco_rule.h"
|
||||||
#include "falco_source.h"
|
#include "falco_source.h"
|
||||||
|
#include "falco_load_result.h"
|
||||||
#include "indexed_vector.h"
|
#include "indexed_vector.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -31,34 +33,111 @@ limitations under the License.
|
|||||||
class rule_loader
|
class rule_loader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/*!
|
class context
|
||||||
\brief Represents a section of text from which a certain info
|
|
||||||
struct has been decoded
|
|
||||||
*/
|
|
||||||
struct context
|
|
||||||
{
|
{
|
||||||
std::string content;
|
public:
|
||||||
|
struct location
|
||||||
/*!
|
|
||||||
\brief Wraps an error by adding info about the text section
|
|
||||||
*/
|
|
||||||
inline std::string error(std::string err) const
|
|
||||||
{
|
{
|
||||||
std::string cnt = content;
|
// The original location in the document
|
||||||
err += "\n---\n";
|
YAML::Mark mark;
|
||||||
err += trim(cnt);
|
|
||||||
err += "\n---";
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
// The kind of item at this location
|
||||||
\brief Appends another text section info to this one
|
// (e.g. "list", "macro", "rule", "exception", etc)
|
||||||
*/
|
std::string item_type;
|
||||||
inline void append(context& m)
|
|
||||||
{
|
// The name of this item (e.g. "Write Below Etc",
|
||||||
content += "\n\n";
|
// etc).
|
||||||
content += m.content;
|
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(
|
explicit configuration(
|
||||||
const std::string& cont,
|
const std::string& cont,
|
||||||
const indexed_vector<falco_source>& srcs)
|
const indexed_vector<falco_source>& srcs,
|
||||||
: content(cont), sources(srcs) {}
|
std::string name)
|
||||||
|
: content(cont), sources(srcs), name(name)
|
||||||
|
{
|
||||||
|
res.reset(new result(name));
|
||||||
|
}
|
||||||
|
|
||||||
const std::string& content;
|
const std::string& content;
|
||||||
const indexed_vector<falco_source>& sources;
|
const indexed_vector<falco_source>& sources;
|
||||||
std::vector<std::string> errors;
|
std::string name;
|
||||||
std::vector<std::string> warnings;
|
std::unique_ptr<result> res;
|
||||||
std::string output_extra;
|
std::string output_extra;
|
||||||
uint16_t default_ruleset_id;
|
uint16_t default_ruleset_id;
|
||||||
bool replace_output_container_info;
|
bool replace_output_container_info;
|
||||||
@@ -86,6 +169,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
struct engine_version_info
|
struct engine_version_info
|
||||||
{
|
{
|
||||||
|
engine_version_info(context &ctx);
|
||||||
|
~engine_version_info() = default;
|
||||||
|
|
||||||
|
context ctx;
|
||||||
uint32_t version;
|
uint32_t version;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -94,15 +181,26 @@ public:
|
|||||||
*/
|
*/
|
||||||
struct plugin_version_info
|
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 name;
|
||||||
std::string version;
|
std::string version;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Represents infos about a list
|
\brief Represents infos about a list
|
||||||
*/
|
*/
|
||||||
struct list_info
|
struct list_info
|
||||||
{
|
{
|
||||||
|
list_info(context &ctx);
|
||||||
|
~list_info() = default;
|
||||||
|
|
||||||
context ctx;
|
context ctx;
|
||||||
bool used;
|
bool used;
|
||||||
size_t index;
|
size_t index;
|
||||||
@@ -112,11 +210,15 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Represents infos about a macro
|
\brief Represents infos about a macro
|
||||||
*/
|
*/
|
||||||
struct macro_info
|
struct macro_info
|
||||||
{
|
{
|
||||||
|
macro_info(context &ctx);
|
||||||
|
~macro_info() = default;
|
||||||
|
|
||||||
context ctx;
|
context ctx;
|
||||||
|
context cond_ctx;
|
||||||
bool used;
|
bool used;
|
||||||
size_t index;
|
size_t index;
|
||||||
size_t visibility;
|
size_t visibility;
|
||||||
@@ -130,6 +232,9 @@ public:
|
|||||||
*/
|
*/
|
||||||
struct rule_exception_info
|
struct rule_exception_info
|
||||||
{
|
{
|
||||||
|
rule_exception_info(context &ctx);
|
||||||
|
~rule_exception_info() = default;
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief This is necessary due to the dynamic-typed nature of
|
\brief This is necessary due to the dynamic-typed nature of
|
||||||
exceptions. Each of fields, comps, and values, can either be a
|
exceptions. Each of fields, comps, and values, can either be a
|
||||||
@@ -148,6 +253,7 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
context ctx;
|
||||||
std::string name;
|
std::string name;
|
||||||
entry fields;
|
entry fields;
|
||||||
entry comps;
|
entry comps;
|
||||||
@@ -155,11 +261,16 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Represents infos about a rule
|
\brief Represents infos about a rule
|
||||||
*/
|
*/
|
||||||
struct rule_info
|
struct rule_info
|
||||||
{
|
{
|
||||||
|
rule_info(context &ctx);
|
||||||
|
~rule_info() = default;
|
||||||
|
|
||||||
context ctx;
|
context ctx;
|
||||||
|
context cond_ctx;
|
||||||
|
context output_ctx;
|
||||||
size_t index;
|
size_t index;
|
||||||
size_t visibility;
|
size_t visibility;
|
||||||
std::string name;
|
std::string name;
|
||||||
@@ -185,7 +296,7 @@ public:
|
|||||||
/*!
|
/*!
|
||||||
\brief Uses the internal state to compile a list of falco_rules
|
\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
|
\brief Returns the set of all required versions for each plugin according
|
||||||
|
Reference in New Issue
Block a user