mirror of
https://github.com/falcosecurity/falco.git
synced 2025-07-05 10:56:47 +00:00
cleanup(userspace/engine): remove lua files and lua-related code sections
Signed-off-by: Jason Dellaluce <jasondellaluce@gmail.com>
This commit is contained in:
parent
7db9dd66ff
commit
b74dcbd851
2
.gitignore
vendored
2
.gitignore
vendored
@ -12,6 +12,4 @@ test/build
|
||||
|
||||
.vscode/*
|
||||
|
||||
.luacheckcache
|
||||
|
||||
*.idea*
|
||||
|
@ -1,8 +0,0 @@
|
||||
std = "min"
|
||||
cache = true
|
||||
include_files = {
|
||||
"userspace/engine/lua/*.lua",
|
||||
"userspace/engine/lua/lyaml/*.lua",
|
||||
"*.luacheckrc"
|
||||
}
|
||||
exclude_files = {"build"}
|
@ -10,10 +10,7 @@
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations under the License.
|
||||
|
||||
add_subdirectory(lua)
|
||||
|
||||
set(FALCO_ENGINE_SOURCE_FILES
|
||||
rules.cpp
|
||||
falco_common.cpp
|
||||
falco_engine.cpp
|
||||
falco_utils.cpp
|
||||
|
@ -14,11 +14,7 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include <fstream>
|
||||
|
||||
#include "falco_common.h"
|
||||
#include "banned.h" // This raises a compilation error when certain functions are used
|
||||
#include "falco_engine_lua_files.hh"
|
||||
|
||||
std::vector<std::string> falco_common::priority_names = {
|
||||
"Emergency",
|
||||
|
@ -19,13 +19,6 @@ limitations under the License.
|
||||
#include <string>
|
||||
#include <exception>
|
||||
#include <mutex>
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lualib.h"
|
||||
#include "lauxlib.h"
|
||||
}
|
||||
|
||||
#include <sinsp.h>
|
||||
|
||||
//
|
||||
|
@ -28,17 +28,9 @@ limitations under the License.
|
||||
|
||||
#include "formats.h"
|
||||
|
||||
#include "lua_filter_helper.h"
|
||||
extern "C" {
|
||||
#include "lyaml.h"
|
||||
}
|
||||
|
||||
#include "utils.h"
|
||||
#include "banned.h" // This raises a compilation error when certain functions are used
|
||||
|
||||
|
||||
string lua_on_event = "on_event";
|
||||
string lua_print_stats = "print_stats";
|
||||
const std::string falco_engine::s_default_ruleset = "falco-default-ruleset";
|
||||
|
||||
using namespace std;
|
||||
|
@ -29,7 +29,6 @@ limitations under the License.
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "gen_filter.h"
|
||||
#include "rules.h"
|
||||
#include "ruleset.h"
|
||||
|
||||
#include "falco_common.h"
|
||||
@ -40,7 +39,7 @@ limitations under the License.
|
||||
// handled in a separate class falco_outputs.
|
||||
//
|
||||
|
||||
class falco_engine : public falco_common
|
||||
class falco_engine
|
||||
{
|
||||
public:
|
||||
falco_engine(bool seed_rng=true);
|
||||
|
@ -18,16 +18,7 @@ limitations under the License.
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "lua.h"
|
||||
#include "lualib.h"
|
||||
#include "lauxlib.h"
|
||||
}
|
||||
|
||||
#include <gen_filter.h>
|
||||
|
||||
#include "falco_engine.h"
|
||||
|
||||
class falco_formats
|
||||
|
@ -1,21 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2021 The Falco Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations under the License.
|
||||
|
||||
file(GLOB_RECURSE lua_files ${CMAKE_CURRENT_SOURCE_DIR} *.lua)
|
||||
|
||||
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/falco_engine_lua_files.cpp
|
||||
COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/lua-to-cpp.sh ${CMAKE_CURRENT_SOURCE_DIR} ${LYAML_LUA_DIR} ${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS ${lua_files} ${CMAKE_CURRENT_SOURCE_DIR}/lua-to-cpp.sh lyaml)
|
||||
|
||||
add_library(luafiles falco_engine_lua_files.cpp)
|
||||
|
||||
target_include_directories(luafiles PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
|
@ -1,78 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
LUA_FILE_DIR=$1
|
||||
LYAML_LUA_DIR=$2
|
||||
OUTPUT_DIR=$3
|
||||
|
||||
MODULE_SYMS=()
|
||||
CODE_SYMS=()
|
||||
|
||||
function add_lua_file {
|
||||
filename=$1
|
||||
is_module=$2
|
||||
|
||||
# Take the basename of the file
|
||||
BASE_NAME=$(basename ${file} .lua)
|
||||
SYMBOL_NAME="${BASE_NAME}_lua_file_contents"
|
||||
FILE_CONTENTS=$(<${file})
|
||||
|
||||
# Add a symbol to the .cc file containing the contents of the file
|
||||
echo "const char *${SYMBOL_NAME}=R\"LUAFILE(${FILE_CONTENTS})LUAFILE\";" >> ${OUTPUT_DIR}/falco_engine_lua_files.cpp
|
||||
|
||||
# Add an extern reference to the .hh file
|
||||
echo "extern const char *${SYMBOL_NAME};" >> ${OUTPUT_DIR}/falco_engine_lua_files.hh
|
||||
|
||||
if [[ "${is_module}" == "true" ]]; then
|
||||
# Determine the module name for the file
|
||||
if [[ "${file}" == *"/"* ]]; then
|
||||
MODULE_NAME=$(echo ${file} | tr / . | sed -e 's/.lua//')
|
||||
else
|
||||
MODULE_NAME=$(basename ${file} .lua)
|
||||
fi
|
||||
|
||||
# Add the pair (string contents, module name) to MODULE_SYMS
|
||||
PAIR=$(echo "{${SYMBOL_NAME},\"${MODULE_NAME}\"}")
|
||||
MODULE_SYMS+=(${PAIR})
|
||||
else
|
||||
# Add the string to CODE_SYMS
|
||||
CODE_SYMS+=(${SYMBOL_NAME})
|
||||
fi
|
||||
}
|
||||
|
||||
cat <<EOF > ${OUTPUT_DIR}/falco_engine_lua_files.cpp
|
||||
// Automatically generated. Do not edit
|
||||
#include "falco_engine_lua_files.hh"
|
||||
EOF
|
||||
|
||||
cat <<EOF > ${OUTPUT_DIR}/falco_engine_lua_files.hh
|
||||
#pragma once
|
||||
// Automatically generated. Do not edit
|
||||
#include <list>
|
||||
#include <utility>
|
||||
EOF
|
||||
|
||||
# lyaml and any files in the "modules" subdirectory are treated as lua
|
||||
# modules.
|
||||
pushd ${LYAML_LUA_DIR}
|
||||
for file in *.lua */*.lua; do
|
||||
add_lua_file $file "true"
|
||||
done
|
||||
popd
|
||||
|
||||
# Any .lua files in this directory are treated as code with functions
|
||||
# to execute.
|
||||
pushd ${LUA_FILE_DIR}
|
||||
for file in ${LUA_FILE_DIR}/*.lua; do
|
||||
add_lua_file $file "false"
|
||||
done
|
||||
popd
|
||||
|
||||
# Create a list of lua module (string, module name) pairs from MODULE_SYMS
|
||||
echo "extern std::list<std::pair<const char *,const char *>> lua_module_strings;" >> ${OUTPUT_DIR}/falco_engine_lua_files.hh
|
||||
echo "std::list<std::pair<const char *,const char *>> lua_module_strings = {$(IFS=, ; echo "${MODULE_SYMS[*]}")};" >> ${OUTPUT_DIR}/falco_engine_lua_files.cpp
|
||||
|
||||
# Create a list of lua code strings from CODE_SYMS
|
||||
echo "extern std::list<const char *> lua_code_strings;" >> ${OUTPUT_DIR}/falco_engine_lua_files.hh
|
||||
echo "std::list<const char *> lua_code_strings = {$(IFS=, ; echo "${CODE_SYMS[*]}")};" >> ${OUTPUT_DIR}/falco_engine_lua_files.cpp
|
File diff suppressed because it is too large
Load Diff
@ -1,190 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2022 The Falco Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include <sinsp.h>
|
||||
#include "lua_filter_helper.h"
|
||||
#include "filter_macro_resolver.h"
|
||||
#include "rules.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace libsinsp::filter;
|
||||
|
||||
// The code below implements the Lua wrapper.
|
||||
// todo(jasondellaluce): remove this once Lua is removed from Falco
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lualib.h"
|
||||
#include "lauxlib.h"
|
||||
}
|
||||
|
||||
const static struct luaL_Reg ll_filter_helper[] =
|
||||
{
|
||||
{"compile_filter", &lua_filter_helper::compile_filter},
|
||||
{"parse_filter", &lua_filter_helper::parse_filter},
|
||||
{"expand_macro", &lua_filter_helper::expand_macro},
|
||||
{"find_unknown_macro", &lua_filter_helper::find_unknown_macro},
|
||||
{"clone_ast", &lua_filter_helper::clone_ast},
|
||||
{"delete_ast", &lua_filter_helper::delete_ast},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
void lua_filter_helper::init(lua_State *ls)
|
||||
{
|
||||
luaL_openlib(ls, "filter_helper", ll_filter_helper, 0);
|
||||
}
|
||||
|
||||
int lua_filter_helper::parse_filter(lua_State *ls)
|
||||
{
|
||||
if (! lua_isstring(ls, -1))
|
||||
{
|
||||
lua_pushstring(ls, "invalid argument passed to parse_filter()");
|
||||
lua_error(ls);
|
||||
}
|
||||
|
||||
string filter_str = lua_tostring(ls, -1);
|
||||
|
||||
parser p(filter_str);
|
||||
p.set_max_depth(1000);
|
||||
try
|
||||
{
|
||||
auto filter = p.parse();
|
||||
lua_pushboolean(ls, true);
|
||||
lua_pushlightuserdata(ls, filter);
|
||||
}
|
||||
catch (const sinsp_exception& e)
|
||||
{
|
||||
string err = to_string(p.get_pos().col) + ": " + e.what();
|
||||
lua_pushboolean(ls, false);
|
||||
lua_pushstring(ls, err.c_str());
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
int lua_filter_helper::compile_filter(lua_State *ls)
|
||||
{
|
||||
if (! lua_islightuserdata(ls, -4) ||
|
||||
! lua_islightuserdata(ls, -3) ||
|
||||
! lua_isstring(ls, -2) ||
|
||||
! lua_isnumber(ls, -1))
|
||||
{
|
||||
lua_pushstring(ls, "invalid argument passed to compile_filter()");
|
||||
lua_error(ls);
|
||||
}
|
||||
|
||||
falco_rules *rules = (falco_rules *) lua_topointer(ls, -4);
|
||||
ast::expr* ast = (ast::expr*) lua_topointer(ls, -3);
|
||||
std::string source = lua_tostring(ls, -2);
|
||||
int32_t check_id = (int32_t) luaL_checkinteger(ls, -1);
|
||||
|
||||
try
|
||||
{
|
||||
sinsp_filter_compiler compiler(rules->get_filter_factory(source), ast);
|
||||
compiler.set_check_id(check_id);
|
||||
gen_event_filter* filter = compiler.compile();
|
||||
lua_pushboolean(ls, true);
|
||||
lua_pushlightuserdata(ls, filter);
|
||||
}
|
||||
catch (const sinsp_exception& e)
|
||||
{
|
||||
lua_pushboolean(ls, false);
|
||||
lua_pushstring(ls, e.what());
|
||||
}
|
||||
catch (const falco_exception& e)
|
||||
{
|
||||
lua_pushboolean(ls, false);
|
||||
lua_pushstring(ls, e.what());
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
int lua_filter_helper::expand_macro(lua_State *ls)
|
||||
{
|
||||
if (! lua_islightuserdata(ls, -3) || // ast
|
||||
! lua_isstring(ls, -2) || // name
|
||||
! lua_islightuserdata(ls, -1)) // macro
|
||||
{
|
||||
lua_pushstring(ls, "invalid arguments passed to expand_macro()");
|
||||
lua_error(ls);
|
||||
}
|
||||
|
||||
ast::expr* ast = (ast::expr*) lua_topointer(ls, -3);
|
||||
std::string name = lua_tostring(ls, -2);
|
||||
ast::expr* macro = (ast::expr*) lua_topointer(ls, -1);
|
||||
|
||||
// For now we need to clone the macro AST because the current Lua
|
||||
// rule-loader implementation manages the pointer lifecycle manually,
|
||||
// and it's not compatible with shared_ptr.
|
||||
shared_ptr<ast::expr> macro_clone(ast::clone(macro));
|
||||
filter_macro_resolver resolver;
|
||||
resolver.set_macro(name, macro_clone);
|
||||
bool resolved = resolver.run(ast);
|
||||
lua_pushboolean(ls, resolved);
|
||||
lua_pushlightuserdata(ls, ast);
|
||||
return 2;
|
||||
}
|
||||
|
||||
int lua_filter_helper::find_unknown_macro(lua_State *ls)
|
||||
{
|
||||
if (! lua_islightuserdata(ls, -1)) // ast
|
||||
{
|
||||
lua_pushstring(ls, "invalid arguments passed to find_unknown_macro()");
|
||||
lua_error(ls);
|
||||
}
|
||||
|
||||
ast::expr* ast = (ast::expr*) lua_topointer(ls, -1);
|
||||
|
||||
// Running a macro resolver without defining any macro allows
|
||||
// us to spot all the still-unresolved macros in an AST.
|
||||
filter_macro_resolver resolver;
|
||||
resolver.run(ast);
|
||||
if (!resolver.get_unknown_macros().empty())
|
||||
{
|
||||
lua_pushboolean(ls, true);
|
||||
lua_pushstring(ls, resolver.get_unknown_macros().begin()->c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushboolean(ls, false);
|
||||
lua_pushstring(ls, "");
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
int lua_filter_helper::clone_ast(lua_State *ls)
|
||||
{
|
||||
if (! lua_islightuserdata(ls, -1)) // ast
|
||||
{
|
||||
lua_pushstring(ls, "Invalid arguments passed to clone_ast()");
|
||||
lua_error(ls);
|
||||
}
|
||||
|
||||
ast::expr* ast = (ast::expr*) lua_topointer(ls, -1);
|
||||
ast::expr* cloned_ast = ast::clone(ast);
|
||||
lua_pushlightuserdata(ls, cloned_ast);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lua_filter_helper::delete_ast(lua_State *ls)
|
||||
{
|
||||
if (! lua_islightuserdata(ls, -1)) // ptr
|
||||
{
|
||||
lua_pushstring(ls, "Invalid arguments passed to delete_ast()");
|
||||
lua_error(ls);
|
||||
}
|
||||
|
||||
delete (ast::expr*) lua_topointer(ls, -1);
|
||||
return 0;
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2022 The Falco Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// todo(jasondellaluce): remove this once Lua is removed from Falco
|
||||
typedef struct lua_State lua_State;
|
||||
|
||||
/*!
|
||||
\brief This is a Lua helper for filter-related operations
|
||||
todo(jasondellaluce): remove this once Lua is removed from Falco
|
||||
*/
|
||||
class lua_filter_helper
|
||||
{
|
||||
public:
|
||||
static void init(lua_State *ls);
|
||||
static int compile_filter(lua_State *ls);
|
||||
static int parse_filter(lua_State *ls);
|
||||
static int expand_macro(lua_State *ls);
|
||||
static int find_unknown_macro(lua_State *ls);
|
||||
static int clone_ast(lua_State *ls);
|
||||
static int delete_ast(lua_State *ls);
|
||||
};
|
@ -1,471 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2019 The Falco Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "rules.h"
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lualib.h"
|
||||
#include "lauxlib.h"
|
||||
}
|
||||
|
||||
#include "falco_engine.h"
|
||||
#include "banned.h" // This raises a compilation error when certain functions are used
|
||||
|
||||
const static struct luaL_Reg ll_falco_rules[] =
|
||||
{
|
||||
{"clear_filters", &falco_rules::clear_filters},
|
||||
{"add_filter", &falco_rules::add_filter},
|
||||
{"enable_rule", &falco_rules::enable_rule},
|
||||
{"engine_version", &falco_rules::engine_version},
|
||||
{"is_source_valid", &falco_rules::is_source_valid},
|
||||
{"is_format_valid", &falco_rules::is_format_valid},
|
||||
{"is_defined_field", &falco_rules::is_defined_field},
|
||||
{NULL, NULL}};
|
||||
|
||||
falco_rules::falco_rules(falco_engine *engine,
|
||||
lua_State *ls)
|
||||
: m_engine(engine),
|
||||
m_ls(ls)
|
||||
{
|
||||
}
|
||||
|
||||
void falco_rules::add_filter_factory(const std::string &source,
|
||||
std::shared_ptr<gen_event_filter_factory> factory)
|
||||
{
|
||||
m_filter_factories[source] = factory;
|
||||
}
|
||||
|
||||
void falco_rules::init(lua_State *ls)
|
||||
{
|
||||
luaL_openlib(ls, "falco_rules", ll_falco_rules, 0);
|
||||
}
|
||||
|
||||
int falco_rules::clear_filters(lua_State *ls)
|
||||
{
|
||||
if (! lua_islightuserdata(ls, -1))
|
||||
{
|
||||
lua_pushstring(ls, "Invalid arguments passed to clear_filters()");
|
||||
lua_error(ls);
|
||||
}
|
||||
|
||||
falco_rules *rules = (falco_rules *) lua_topointer(ls, -1);
|
||||
rules->clear_filters();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void falco_rules::clear_filters()
|
||||
{
|
||||
m_engine->clear_filters();
|
||||
}
|
||||
|
||||
std::shared_ptr<gen_event_filter_factory> falco_rules::get_filter_factory(const std::string &source)
|
||||
{
|
||||
auto it = m_filter_factories.find(source);
|
||||
if(it == m_filter_factories.end())
|
||||
{
|
||||
throw falco_exception(string("unknown event source: ") + source);
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
|
||||
int falco_rules::add_filter(lua_State *ls)
|
||||
{
|
||||
if (! lua_islightuserdata(ls, -5) ||
|
||||
! lua_islightuserdata(ls, -4) ||
|
||||
! lua_isstring(ls, -3) ||
|
||||
! lua_isstring(ls, -2) ||
|
||||
! lua_istable(ls, -1))
|
||||
{
|
||||
lua_pushstring(ls, "Invalid arguments passed to add_filter()");
|
||||
lua_error(ls);
|
||||
}
|
||||
|
||||
falco_rules *rules = (falco_rules *) lua_topointer(ls, -5);
|
||||
gen_event_filter *filter = (gen_event_filter*) lua_topointer(ls, -4);
|
||||
std::string rule = lua_tostring(ls, -3);
|
||||
std::string source = lua_tostring(ls, -2);
|
||||
|
||||
set<string> tags;
|
||||
|
||||
lua_pushnil(ls); /* first key */
|
||||
while (lua_next(ls, -2) != 0) {
|
||||
// key is at index -2, value is at index
|
||||
// -1. We want the values.
|
||||
tags.insert(lua_tostring(ls, -1));
|
||||
|
||||
// Remove value, keep key for next iteration
|
||||
lua_pop(ls, 1);
|
||||
}
|
||||
|
||||
// todo(jasondellaluce,leogr,fededp): temp workaround, remove when fixed in libs
|
||||
size_t num_evttypes = 1; // assume plugin
|
||||
if(source == "syscall" || source == "k8s_audit")
|
||||
{
|
||||
num_evttypes = filter->evttypes().size();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
std::shared_ptr<gen_event_filter> filter_ptr(filter);
|
||||
rules->add_filter(filter_ptr, rule, source, tags);
|
||||
}
|
||||
catch (exception &e)
|
||||
{
|
||||
std::string errstr = string("Could not add rule to falco engine: ") + e.what();
|
||||
lua_pushstring(ls, errstr.c_str());
|
||||
lua_error(ls);
|
||||
}
|
||||
|
||||
lua_pushnumber(ls, num_evttypes);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void falco_rules::add_filter(std::shared_ptr<gen_event_filter> filter, string &rule, string &source, set<string> &tags)
|
||||
{
|
||||
m_engine->add_filter(filter, rule, source, tags);
|
||||
}
|
||||
|
||||
int falco_rules::enable_rule(lua_State *ls)
|
||||
{
|
||||
if (! lua_islightuserdata(ls, -3) ||
|
||||
! lua_isstring(ls, -2) ||
|
||||
! lua_isnumber(ls, -1))
|
||||
{
|
||||
lua_pushstring(ls, "Invalid arguments passed to enable_rule()");
|
||||
lua_error(ls);
|
||||
}
|
||||
|
||||
falco_rules *rules = (falco_rules *) lua_topointer(ls, -3);
|
||||
const char *rulec = lua_tostring(ls, -2);
|
||||
std::string rule = rulec;
|
||||
bool enabled = (lua_tonumber(ls, -1) ? true : false);
|
||||
|
||||
rules->enable_rule(rule, enabled);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void falco_rules::enable_rule(string &rule, bool enabled)
|
||||
{
|
||||
m_engine->enable_rule(rule, enabled);
|
||||
}
|
||||
|
||||
int falco_rules::engine_version(lua_State *ls)
|
||||
{
|
||||
if (! lua_islightuserdata(ls, -1))
|
||||
{
|
||||
lua_pushstring(ls, "Invalid arguments passed to engine_version()");
|
||||
lua_error(ls);
|
||||
}
|
||||
|
||||
falco_rules *rules = (falco_rules *) lua_topointer(ls, -1);
|
||||
|
||||
lua_pushnumber(ls, rules->m_engine->engine_version());
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool falco_rules::is_source_valid(const std::string &source)
|
||||
{
|
||||
return m_engine->is_source_valid(source);
|
||||
}
|
||||
|
||||
int falco_rules::is_source_valid(lua_State *ls)
|
||||
{
|
||||
if (! lua_islightuserdata(ls, -2) ||
|
||||
! lua_isstring(ls, -1))
|
||||
{
|
||||
lua_pushstring(ls, "Invalid arguments passed to is_source_valid");
|
||||
lua_error(ls);
|
||||
}
|
||||
|
||||
falco_rules *rules = (falco_rules *) lua_topointer(ls, -2);
|
||||
string source = luaL_checkstring(ls, -1);
|
||||
|
||||
bool ret = rules->is_source_valid(source);
|
||||
|
||||
lua_pushboolean(ls, (ret ? 1 : 0));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int falco_rules::is_format_valid(lua_State *ls)
|
||||
{
|
||||
if (! lua_islightuserdata(ls, -3) ||
|
||||
! lua_isstring(ls, -2) ||
|
||||
! lua_isstring(ls, -1))
|
||||
{
|
||||
lua_pushstring(ls, "Invalid arguments passed to is_format_valid");
|
||||
lua_error(ls);
|
||||
}
|
||||
|
||||
falco_rules *rules = (falco_rules *) lua_topointer(ls, -3);
|
||||
string source = luaL_checkstring(ls, -2);
|
||||
string format = luaL_checkstring(ls, -1);
|
||||
string errstr;
|
||||
|
||||
bool ret = rules->is_format_valid(source, format, errstr);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
lua_pushstring(ls, errstr.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
lua_pushnil(ls);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool falco_rules::is_format_valid(const std::string &source, const std::string &format, std::string &errstr)
|
||||
{
|
||||
bool ret = true;
|
||||
|
||||
try
|
||||
{
|
||||
std::shared_ptr<gen_event_formatter> formatter;
|
||||
|
||||
formatter = m_engine->create_formatter(source, format);
|
||||
}
|
||||
catch(exception &e)
|
||||
{
|
||||
std::ostringstream os;
|
||||
|
||||
os << "Invalid output format '"
|
||||
<< format
|
||||
<< "': '"
|
||||
<< e.what()
|
||||
<< "'";
|
||||
|
||||
errstr = os.str();
|
||||
ret = false;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int falco_rules::is_defined_field(lua_State *ls)
|
||||
{
|
||||
if (! lua_islightuserdata(ls, -3) ||
|
||||
! lua_isstring(ls, -2) ||
|
||||
! lua_isstring(ls, -1))
|
||||
{
|
||||
lua_pushstring(ls, "Invalid arguments passed to is_defined_field");
|
||||
lua_error(ls);
|
||||
}
|
||||
|
||||
falco_rules *rules = (falco_rules *) lua_topointer(ls, -3);
|
||||
string source = luaL_checkstring(ls, -2);
|
||||
string fldname = luaL_checkstring(ls, -1);
|
||||
|
||||
bool ret = rules->is_defined_field(source, fldname);
|
||||
|
||||
lua_pushboolean(ls, (ret ? 1 : 0));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool falco_rules::is_defined_field(const std::string &source, const std::string &fldname)
|
||||
{
|
||||
auto it = m_filter_factories.find(source);
|
||||
|
||||
if(it == m_filter_factories.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto *chk = it->second->new_filtercheck(fldname.c_str());
|
||||
|
||||
if (chk == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
delete(chk);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::list<std::string> get_lua_table_values(lua_State *ls, int idx)
|
||||
{
|
||||
std::list<std::string> ret;
|
||||
|
||||
if (lua_isnil(ls, idx)) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
lua_pushnil(ls); /* first key */
|
||||
while (lua_next(ls, idx-1) != 0) {
|
||||
// key is at index -2, value is at index
|
||||
// -1. We want the values.
|
||||
if (! lua_isstring(ls, -1)) {
|
||||
std::string err = "Non-string value in table of strings";
|
||||
throw falco_exception(err);
|
||||
}
|
||||
ret.push_back(string(lua_tostring(ls, -1)));
|
||||
|
||||
// Remove value, keep key for next iteration
|
||||
lua_pop(ls, 1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void get_lua_table_list_values(lua_State *ls,
|
||||
int idx,
|
||||
std::map<std::string, std::list<std::string>> &required_plugin_versions)
|
||||
{
|
||||
if (lua_isnil(ls, idx)) {
|
||||
return;
|
||||
}
|
||||
|
||||
lua_pushnil(ls); /* first key */
|
||||
while (lua_next(ls, idx-1) != 0) {
|
||||
// key is at index -2, table of values is at index -1.
|
||||
if (! lua_isstring(ls, -2)) {
|
||||
std::string err = "Non-string key in table of strings";
|
||||
throw falco_exception(err);
|
||||
}
|
||||
|
||||
std::string key = string(lua_tostring(ls, -2));
|
||||
std::list<std::string> vals = get_lua_table_values(ls, -1);
|
||||
|
||||
if (required_plugin_versions.find(key) == required_plugin_versions.end())
|
||||
{
|
||||
required_plugin_versions[key] = vals;
|
||||
}
|
||||
else
|
||||
{
|
||||
required_plugin_versions[key].insert(required_plugin_versions[key].end(),
|
||||
vals.begin(),
|
||||
vals.end());
|
||||
}
|
||||
|
||||
// Remove value, keep key for next iteration
|
||||
lua_pop(ls, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void falco_rules::load_rules(const string &rules_content,
|
||||
bool verbose, bool all_events,
|
||||
string &extra, bool replace_container_info,
|
||||
falco_common::priority_type min_priority,
|
||||
uint64_t &required_engine_version,
|
||||
std::map<std::string, std::list<std::string>> &required_plugin_versions)
|
||||
{
|
||||
lua_getglobal(m_ls, m_lua_load_rules.c_str());
|
||||
if(lua_isfunction(m_ls, -1))
|
||||
{
|
||||
lua_pushstring(m_ls, rules_content.c_str());
|
||||
lua_pushlightuserdata(m_ls, this);
|
||||
lua_pushboolean(m_ls, (verbose ? 1 : 0));
|
||||
lua_pushboolean(m_ls, (all_events ? 1 : 0));
|
||||
lua_pushstring(m_ls, extra.c_str());
|
||||
lua_pushboolean(m_ls, (replace_container_info ? 1 : 0));
|
||||
lua_pushnumber(m_ls, min_priority);
|
||||
if(lua_pcall(m_ls, 7, 5, 0) != 0)
|
||||
{
|
||||
const char* lerr = lua_tostring(m_ls, -1);
|
||||
|
||||
string err = "Error loading rules: " + string(lerr);
|
||||
|
||||
throw falco_exception(err);
|
||||
}
|
||||
|
||||
// Returns:
|
||||
// Load result: bool
|
||||
// required engine version: will be nil when load result is false
|
||||
// required_plugin_versions: will be nil when load result is false
|
||||
// array of errors
|
||||
// array of warnings
|
||||
bool successful = lua_toboolean(m_ls, -5);
|
||||
required_engine_version = lua_tonumber(m_ls, -4);
|
||||
get_lua_table_list_values(m_ls, -3, required_plugin_versions);
|
||||
std::list<std::string> errors = get_lua_table_values(m_ls, -2);
|
||||
std::list<std::string> warnings = get_lua_table_values(m_ls, -1);
|
||||
|
||||
// Concatenate errors/warnings
|
||||
std::ostringstream os;
|
||||
if (errors.size() > 0)
|
||||
{
|
||||
os << errors.size() << " errors:" << std::endl;
|
||||
for(auto err : errors)
|
||||
{
|
||||
os << err << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (warnings.size() > 0)
|
||||
{
|
||||
os << warnings.size() << " warnings:" << std::endl;
|
||||
for(auto warn : warnings)
|
||||
{
|
||||
os << warn << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if(!successful)
|
||||
{
|
||||
throw falco_exception(os.str());
|
||||
}
|
||||
|
||||
if (verbose && os.str() != "") {
|
||||
// We don't really have a logging callback
|
||||
// from the falco engine, but this would be a
|
||||
// good place to use it.
|
||||
fprintf(stderr, "When reading rules content: %s", os.str().c_str());
|
||||
}
|
||||
|
||||
lua_pop(m_ls, 4);
|
||||
|
||||
} else {
|
||||
throw falco_exception("No function " + m_lua_load_rules + " found in lua rule module");
|
||||
}
|
||||
}
|
||||
|
||||
void falco_rules::describe_rule(std::string *rule)
|
||||
{
|
||||
lua_getglobal(m_ls, m_lua_describe_rule.c_str());
|
||||
if(lua_isfunction(m_ls, -1))
|
||||
{
|
||||
if (rule == NULL)
|
||||
{
|
||||
lua_pushnil(m_ls);
|
||||
} else {
|
||||
lua_pushstring(m_ls, rule->c_str());
|
||||
}
|
||||
|
||||
if(lua_pcall(m_ls, 1, 0, 0) != 0)
|
||||
{
|
||||
const char* lerr = lua_tostring(m_ls, -1);
|
||||
string err = "Could not describe " + (rule == NULL ? "all rules" : "rule " + *rule) + ": " + string(lerr);
|
||||
throw falco_exception(err);
|
||||
}
|
||||
} else {
|
||||
throw falco_exception("No function " + m_lua_describe_rule + " found in lua rule module");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
falco_rules::~falco_rules()
|
||||
{
|
||||
}
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
Copyright (C) 2019 The Falco Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <set>
|
||||
#include <memory>
|
||||
|
||||
#include "sinsp.h"
|
||||
#include "filter.h"
|
||||
|
||||
#include "json_evt.h"
|
||||
#include "falco_common.h"
|
||||
|
||||
typedef struct lua_State lua_State;
|
||||
|
||||
class falco_engine;
|
||||
|
||||
class falco_rules
|
||||
{
|
||||
public:
|
||||
falco_rules(falco_engine *engine,
|
||||
lua_State *ls);
|
||||
~falco_rules();
|
||||
|
||||
void add_filter_factory(const std::string &source,
|
||||
std::shared_ptr<gen_event_filter_factory> factory);
|
||||
|
||||
std::shared_ptr<gen_event_filter_factory> get_filter_factory(const std::string &source);
|
||||
|
||||
void load_rules(const string &rules_content, bool verbose, bool all_events,
|
||||
std::string &extra, bool replace_container_info,
|
||||
falco_common::priority_type min_priority,
|
||||
uint64_t &required_engine_version,
|
||||
std::map<std::string, std::list<std::string>> &required_plugin_versions);
|
||||
void describe_rule(string *rule);
|
||||
|
||||
bool is_source_valid(const std::string &source);
|
||||
|
||||
bool is_format_valid(const std::string &source, const std::string &format, std::string &errstr);
|
||||
|
||||
bool is_defined_field(const std::string &source, const std::string &field);
|
||||
|
||||
static void init(lua_State *ls);
|
||||
static int clear_filters(lua_State *ls);
|
||||
static int add_filter(lua_State *ls);
|
||||
static int enable_rule(lua_State *ls);
|
||||
static int engine_version(lua_State *ls);
|
||||
|
||||
static int is_source_valid(lua_State *ls);
|
||||
|
||||
// err = falco_rules.is_format_valid(source, format_string)
|
||||
static int is_format_valid(lua_State *ls);
|
||||
|
||||
// err = falco_rules.is_defined_field(source, field)
|
||||
static int is_defined_field(lua_State *ls);
|
||||
|
||||
private:
|
||||
void clear_filters();
|
||||
void add_filter(std::shared_ptr<gen_event_filter> filter, string &rule, string &source, std::set<string> &tags);
|
||||
void enable_rule(string &rule, bool enabled);
|
||||
|
||||
falco_engine *m_engine;
|
||||
lua_State* m_ls;
|
||||
|
||||
// Maps from event source to an object that can create rules
|
||||
// for that event source.
|
||||
std::map<std::string, std::shared_ptr<gen_event_filter_factory>> m_filter_factories;
|
||||
|
||||
string m_lua_load_rules = "load_rules";
|
||||
string m_lua_describe_rule = "describe_rule";
|
||||
};
|
Loading…
Reference in New Issue
Block a user