mirror of
https://github.com/falcosecurity/falco.git
synced 2025-06-26 22:57:24 +00:00
Add support for output formats
This commit is contained in:
parent
05362e2c68
commit
bba5aa6974
@ -163,12 +163,22 @@ local function macro (name, filter)
|
|||||||
return {type = "MacroDef", name = name, value = filter}
|
return {type = "MacroDef", name = name, value = filter}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function outputformat (format)
|
||||||
|
return {type = "OutputFormat", value = format}
|
||||||
|
end
|
||||||
|
|
||||||
|
local function rule(filter, output)
|
||||||
|
return {type = "Rule", filter = filter, output = output}
|
||||||
|
end
|
||||||
|
|
||||||
local G = {
|
local G = {
|
||||||
V"Start", -- Entry rule
|
V"Start", -- Entry rule
|
||||||
|
|
||||||
Start = V"Skip" * (V"MacroDef" / macro + V"Filter" / filter)^-1 * -1 + report_error();
|
Start = V"Skip" * (V"MacroDef" / macro + V"Rule" / rule)^-1 * -1 + report_error();
|
||||||
|
|
||||||
-- Grammar
|
-- Grammar
|
||||||
|
Rule = V"Filter" / filter * ((V"Skip" * V"Pipe" * V"Skip" * (P(1)^0 / outputformat) )^-1 );
|
||||||
|
|
||||||
Filter = V"OrExpression";
|
Filter = V"OrExpression";
|
||||||
OrExpression =
|
OrExpression =
|
||||||
bool(V"AndExpression", V"OrOp");
|
bool(V"AndExpression", V"OrOp");
|
||||||
@ -226,6 +236,7 @@ local G = {
|
|||||||
OrOp = kw("or") / "or";
|
OrOp = kw("or") / "or";
|
||||||
AndOp = kw("and") / "and";
|
AndOp = kw("and") / "and";
|
||||||
Colon = kw(":");
|
Colon = kw(":");
|
||||||
|
Pipe = kw("|");
|
||||||
RelOp = symb("=") / "=" +
|
RelOp = symb("=") / "=" +
|
||||||
symb("==") / "==" +
|
symb("==") / "==" +
|
||||||
symb("!=") / "!=" +
|
symb("!=") / "!=" +
|
||||||
@ -402,7 +413,12 @@ function print_ast(node, level)
|
|||||||
local prefix = string.rep(" ", level*2)
|
local prefix = string.rep(" ", level*2)
|
||||||
level = level + 1
|
level = level + 1
|
||||||
|
|
||||||
if t == "Filter" then
|
if t == "Rule" then
|
||||||
|
print_ast(node.filter, level)
|
||||||
|
if (node.output) then
|
||||||
|
print(prefix.."| "..node.output.value)
|
||||||
|
end
|
||||||
|
elseif t == "Filter" then
|
||||||
print_ast(node.value, level)
|
print_ast(node.value, level)
|
||||||
|
|
||||||
elseif t == "BinaryBoolOp" or t == "BinaryRelOp" then
|
elseif t == "BinaryBoolOp" or t == "BinaryRelOp" then
|
||||||
@ -463,6 +479,7 @@ function compiler.compile_line(line, state)
|
|||||||
local ast, error_msg = compiler.parser.parse_line(line)
|
local ast, error_msg = compiler.parser.parse_line(line)
|
||||||
|
|
||||||
if (error_msg) then
|
if (error_msg) then
|
||||||
|
print ("Compilation error: ", error_msg)
|
||||||
error(error_msg)
|
error(error_msg)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -474,7 +491,15 @@ function compiler.compile_line(line, state)
|
|||||||
return {}
|
return {}
|
||||||
end
|
end
|
||||||
|
|
||||||
local macros = get_macros(ast.value, {})
|
local macros
|
||||||
|
if (ast.type == "Rule") then
|
||||||
|
macros = get_macros(ast.filter, {})
|
||||||
|
elseif (ast.type == "MacroDef") then
|
||||||
|
macros = get_macros(ast.value, {})
|
||||||
|
else
|
||||||
|
error ("Unexpected type: "..t)
|
||||||
|
end
|
||||||
|
|
||||||
for m, _ in pairs(macros) do
|
for m, _ in pairs(macros) do
|
||||||
if state.macros[m] == nil then
|
if state.macros[m] == nil then
|
||||||
error ("Undefined macro '"..m.."' used in '"..line.."'")
|
error ("Undefined macro '"..m.."' used in '"..line.."'")
|
||||||
@ -487,11 +512,11 @@ function compiler.compile_line(line, state)
|
|||||||
state.macros[ast.name] = ast.value
|
state.macros[ast.name] = ast.value
|
||||||
return ast
|
return ast
|
||||||
|
|
||||||
elseif (ast.type == "Filter") then
|
elseif (ast.type == "Rule") then
|
||||||
-- Line is a filter, so expand in-clauses and macro references, then
|
-- Line is a filter, so expand in-clauses and macro references, then
|
||||||
-- stitch it into global ast
|
-- stitch it into global ast
|
||||||
|
|
||||||
expand_in(ast)
|
expand_in(ast.filter)
|
||||||
|
|
||||||
repeat
|
repeat
|
||||||
expanded = expand_macros(ast, state.macros, false)
|
expanded = expand_macros(ast, state.macros, false)
|
||||||
|
@ -54,10 +54,13 @@ good "evt.dir=> and fd.name=*.log"
|
|||||||
good "evt.dir=> and fd.name=/var/log/httpd.log"
|
good "evt.dir=> and fd.name=/var/log/httpd.log"
|
||||||
good "a.g in (1, 'a', b.c)"
|
good "a.g in (1, 'a', b.c)"
|
||||||
good "a.b = a.a"
|
good "a.b = a.a"
|
||||||
|
good "a.b = a.a |"
|
||||||
|
good "a.b = a.a | %evt.type %fd.num blabla"
|
||||||
|
|
||||||
bad "a.g in ()"
|
bad "a.g in ()"
|
||||||
bad "a.b = b = 1"
|
bad "a.b = b = 1"
|
||||||
bad "(a.b = 1"
|
bad "(a.b = 1"
|
||||||
|
bad " | %a.b"
|
||||||
# Macros
|
# Macros
|
||||||
|
|
||||||
good "a: a.b exists"
|
good "a: a.b exists"
|
||||||
@ -67,6 +70,8 @@ good "a : b"
|
|||||||
good "a : evt.dir=>"
|
good "a : evt.dir=>"
|
||||||
good "inbound: (syscall.type=listen and evt.dir='>') or (syscall.type=accept and evt.dir='<')"
|
good "inbound: (syscall.type=listen and evt.dir='>') or (syscall.type=accept and evt.dir='<')"
|
||||||
bad "a:"
|
bad "a:"
|
||||||
|
bad "a : b | bla"
|
||||||
|
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo "All tests passed."
|
echo "All tests passed."
|
||||||
|
Loading…
Reference in New Issue
Block a user