mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Move logic to execute HookLoadFile
for signatures into rule matcher code.
This (1) fixes an issue where signature files supplied on the command line wouldn't pass through the hooks, and (2) prepares for allowing hooks to supply the content of a signature file directly.
This commit is contained in:
parent
f080a814c4
commit
1efaf8d7a4
9 changed files with 94 additions and 40 deletions
|
@ -24,6 +24,7 @@
|
|||
#include "zeek/ZeekString.h"
|
||||
#include "zeek/analyzer/Analyzer.h"
|
||||
#include "zeek/module_util.h"
|
||||
#include "zeek/plugin/Manager.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -248,7 +249,7 @@ void RuleMatcher::Delete(RuleHdrTest* node)
|
|||
delete node;
|
||||
}
|
||||
|
||||
bool RuleMatcher::ReadFiles(const std::vector<std::string>& files)
|
||||
bool RuleMatcher::ReadFiles(const std::vector<SignatureFile>& files)
|
||||
{
|
||||
#ifdef USE_PERFTOOLS_DEBUG
|
||||
HeapLeakChecker::Disabler disabler;
|
||||
|
@ -256,18 +257,54 @@ bool RuleMatcher::ReadFiles(const std::vector<std::string>& files)
|
|||
|
||||
parse_error = false;
|
||||
|
||||
for ( const auto& f : files )
|
||||
for ( auto f : files )
|
||||
{
|
||||
rules_in = util::open_file(util::find_file(f, util::zeek_path(), ".sig"));
|
||||
if ( ! f.full_path )
|
||||
f.full_path = util::find_file(f.file, util::zeek_path(), ".sig");
|
||||
|
||||
int rc = PLUGIN_HOOK_WITH_RESULT(
|
||||
HOOK_LOAD_FILE, HookLoadFile(zeek::plugin::Plugin::SIGNATURES, f.file, *f.full_path),
|
||||
-1);
|
||||
|
||||
switch ( rc )
|
||||
{
|
||||
case -1:
|
||||
// No plugin in charge of this file.
|
||||
if ( f.full_path->empty() )
|
||||
{
|
||||
zeek::reporter->Error("failed to find file associated with @load-sigs %s",
|
||||
f.file.c_str());
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0:
|
||||
if ( ! zeek::reporter->Errors() )
|
||||
zeek::reporter->Error("Plugin reported error loading signatures %s",
|
||||
f.file.c_str());
|
||||
|
||||
exit(1);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// A plugin took care of it, just skip.
|
||||
continue;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
rules_in = util::open_file(*f.full_path);
|
||||
|
||||
if ( ! rules_in )
|
||||
{
|
||||
reporter->Error("Can't open signature file %s", f.data());
|
||||
reporter->Error("Can't open signature file %s", f.file.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
rules_line_number = 0;
|
||||
current_rule_file = f.data();
|
||||
current_rule_file = f.full_path->c_str();
|
||||
rules_parse();
|
||||
fclose(rules_in);
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "zeek/CCL.h"
|
||||
#include "zeek/RE.h"
|
||||
#include "zeek/Rule.h"
|
||||
#include "zeek/ScannedFile.h"
|
||||
|
||||
//#define MATCHER_PRINT_STATS
|
||||
|
||||
|
@ -259,7 +260,7 @@ public:
|
|||
~RuleMatcher();
|
||||
|
||||
// Parse the given files and built up data structures.
|
||||
bool ReadFiles(const std::vector<std::string>& files);
|
||||
bool ReadFiles(const std::vector<SignatureFile>& files);
|
||||
|
||||
/**
|
||||
* Inititialize a state object for matching file magic signatures.
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace zeek::detail
|
|||
{
|
||||
|
||||
std::list<ScannedFile> files_scanned;
|
||||
std::vector<std::string> sig_files;
|
||||
std::vector<SignatureFile> sig_files;
|
||||
|
||||
ScannedFile::ScannedFile(int arg_include_level, std::string arg_name, bool arg_skipped,
|
||||
bool arg_prefixes_checked)
|
||||
|
@ -47,4 +47,14 @@ bool ScannedFile::AlreadyScanned() const
|
|||
return rval;
|
||||
}
|
||||
|
||||
SignatureFile::SignatureFile(std::string file)
|
||||
: file(std::move(file))
|
||||
{
|
||||
}
|
||||
|
||||
SignatureFile::SignatureFile(std::string file, std::string full_path)
|
||||
: file(std::move(file)), full_path(std::move(full_path))
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace zeek::detail
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <list>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -34,6 +35,16 @@ public:
|
|||
};
|
||||
|
||||
extern std::list<ScannedFile> files_scanned;
|
||||
extern std::vector<std::string> sig_files;
|
||||
|
||||
struct SignatureFile
|
||||
{
|
||||
std::string file;
|
||||
std::optional<std::string> full_path;
|
||||
|
||||
SignatureFile(std::string file);
|
||||
SignatureFile(std::string file, std::string full_path);
|
||||
};
|
||||
|
||||
extern std::vector<SignatureFile> sig_files;
|
||||
|
||||
} // namespace zeek::detail
|
||||
|
|
28
src/scan.l
28
src/scan.l
|
@ -348,33 +348,7 @@ when return TOK_WHEN;
|
|||
@load-sigs{WS}{FILE} {
|
||||
const char* file = zeek::util::skip_whitespace(yytext + 10);
|
||||
std::string path = find_relative_file(file, ".sig");
|
||||
int rc = PLUGIN_HOOK_WITH_RESULT(HOOK_LOAD_FILE, HookLoadFile(zeek::plugin::Plugin::SIGNATURES, file, path), -1);
|
||||
|
||||
switch ( rc ) {
|
||||
case -1:
|
||||
// No plugin in charge of this file.
|
||||
if ( path.empty() )
|
||||
zeek::reporter->Error("failed to find file associated with @load-sigs %s",
|
||||
file);
|
||||
else
|
||||
zeek::detail::sig_files.push_back(std::move(path));
|
||||
break;
|
||||
|
||||
case 0:
|
||||
if ( ! zeek::reporter->Errors() )
|
||||
zeek::reporter->Error("Plugin reported error loading signatures %s", file);
|
||||
|
||||
exit(1);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// A plugin took care of it, just skip.
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
sig_files.emplace_back(file, path);
|
||||
}
|
||||
|
||||
@load-plugin{WS}{ID} {
|
||||
|
|
|
@ -737,15 +737,19 @@ SetupResult setup(int argc, char** argv, Options* zopts)
|
|||
id->SetVal(make_intrusive<StringVal>(*options.pcap_filter));
|
||||
}
|
||||
|
||||
auto all_signature_files = options.signature_files;
|
||||
std::vector<SignatureFile> all_signature_files;
|
||||
|
||||
// Append signature files given on the command line
|
||||
for ( const auto& sf : options.signature_files )
|
||||
all_signature_files.push_back(sf);
|
||||
|
||||
// Append signature files defined in "signature_files" script option
|
||||
for ( auto&& sf : get_script_signature_files() )
|
||||
all_signature_files.emplace_back(std::move(sf));
|
||||
all_signature_files.push_back(std::move(sf));
|
||||
|
||||
// Append signature files defined in @load-sigs
|
||||
for ( const auto& sf : zeek::detail::sig_files )
|
||||
all_signature_files.emplace_back(sf);
|
||||
all_signature_files.push_back(sf);
|
||||
|
||||
if ( ! all_signature_files.empty() )
|
||||
{
|
||||
|
|
|
@ -1034,6 +1034,7 @@
|
|||
0.000000 MetaHookPost LoadFile(0, base<...>/zeek.bif, <...>/zeek.bif.zeek) -> -1
|
||||
0.000000 MetaHookPost LoadFile(0, builtin-plugins/__load__.zeek, <...>/__load__.zeek) -> -1
|
||||
0.000000 MetaHookPost LoadFile(0, builtin-plugins/__preload__.zeek, <...>/__preload__.zeek) -> -1
|
||||
0.000000 MetaHookPost LoadFile(0, s1.sig, ./s1.sig) -> -1
|
||||
0.000000 MetaHookPost LoadFile(1, ./archive, <...>/archive.sig) -> -1
|
||||
0.000000 MetaHookPost LoadFile(1, ./audio, <...>/audio.sig) -> -1
|
||||
0.000000 MetaHookPost LoadFile(1, ./dpd.sig, <...>/dpd.sig) -> -1
|
||||
|
@ -1046,6 +1047,7 @@
|
|||
0.000000 MetaHookPost LoadFile(1, ./office, <...>/office.sig) -> -1
|
||||
0.000000 MetaHookPost LoadFile(1, ./programming, <...>/programming.sig) -> -1
|
||||
0.000000 MetaHookPost LoadFile(1, ./video, <...>/video.sig) -> -1
|
||||
0.000000 MetaHookPost LoadFile(1, s2, ./s2.sig) -> -1
|
||||
0.000000 MetaHookPost LogInit(Log::WRITER_ASCII, default, true, true, packet_filter(0.0,0.0,0.0), 5, {ts (time), node (string), filter (string), init (bool), success (bool)}) -> <void>
|
||||
0.000000 MetaHookPost LogWrite(Log::WRITER_ASCII, default, packet_filter(0.0,0.0,0.0), 5, {ts (time), node (string), filter (string), init (bool), success (bool)}, <void ptr>) -> true
|
||||
0.000000 MetaHookPost QueueEvent(NetControl::init()) -> false
|
||||
|
@ -2086,6 +2088,7 @@
|
|||
0.000000 MetaHookPre LoadFile(0, base<...>/zeek.bif, <...>/zeek.bif.zeek)
|
||||
0.000000 MetaHookPre LoadFile(0, builtin-plugins/__load__.zeek, <...>/__load__.zeek)
|
||||
0.000000 MetaHookPre LoadFile(0, builtin-plugins/__preload__.zeek, <...>/__preload__.zeek)
|
||||
0.000000 MetaHookPre LoadFile(0, s1.sig, ./s1.sig)
|
||||
0.000000 MetaHookPre LoadFile(1, ./archive, <...>/archive.sig)
|
||||
0.000000 MetaHookPre LoadFile(1, ./audio, <...>/audio.sig)
|
||||
0.000000 MetaHookPre LoadFile(1, ./dpd.sig, <...>/dpd.sig)
|
||||
|
@ -2098,6 +2101,7 @@
|
|||
0.000000 MetaHookPre LoadFile(1, ./office, <...>/office.sig)
|
||||
0.000000 MetaHookPre LoadFile(1, ./programming, <...>/programming.sig)
|
||||
0.000000 MetaHookPre LoadFile(1, ./video, <...>/video.sig)
|
||||
0.000000 MetaHookPre LoadFile(1, s2, ./s2.sig)
|
||||
0.000000 MetaHookPre LogInit(Log::WRITER_ASCII, default, true, true, packet_filter(0.0,0.0,0.0), 5, {ts (time), node (string), filter (string), init (bool), success (bool)})
|
||||
0.000000 MetaHookPre LogWrite(Log::WRITER_ASCII, default, packet_filter(0.0,0.0,0.0), 5, {ts (time), node (string), filter (string), init (bool), success (bool)}, <void ptr>)
|
||||
0.000000 MetaHookPre QueueEvent(NetControl::init())
|
||||
|
@ -3149,6 +3153,8 @@
|
|||
0.000000 | HookLoadFile base<...>/zeek.bif <...>/zeek.bif.zeek
|
||||
0.000000 | HookLoadFile builtin-plugins/__load__.zeek <...>/__load__.zeek
|
||||
0.000000 | HookLoadFile builtin-plugins/__preload__.zeek <...>/__preload__.zeek
|
||||
0.000000 | HookLoadFile s1.sig ./s1.sig
|
||||
0.000000 | HookLoadFile s2 ./s2.sig
|
||||
0.000000 | HookLogInit packet_filter 1/1 {ts (time), node (string), filter (string), init (bool), success (bool)}
|
||||
0.000000 | HookLogWrite packet_filter [ts=XXXXXXXXXX.XXXXXX, node=zeek, filter=ip or not ip, init=T, success=T]
|
||||
0.000000 | HookQueueEvent NetControl::init()
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||
error: Error in signature (udp-established.sig:5): 'established' is not a valid 'udp-state'
|
||||
error: Error in signature (./udp-established.sig:5): 'established' is not a valid 'udp-state'
|
||||
|
||||
|
|
|
@ -1,8 +1,19 @@
|
|||
# @TEST-EXEC: ${DIST}/auxil/zeek-aux/plugin-support/init-plugin -u . Demo Hooks
|
||||
# @TEST-EXEC: cp -r %DIR/hooks-plugin/* .
|
||||
# @TEST-EXEC: ./configure --zeek-dist=${DIST} && make
|
||||
# @TEST-EXEC: ZEEK_PLUGIN_ACTIVATE="Demo::Hooks" ZEEK_PLUGIN_PATH=`pwd` zeek -b -r $TRACES/http/get.trace %INPUT 2>&1 | $SCRIPTS/diff-remove-abspath | sort | uniq >output
|
||||
# @TEST-EXEC: ZEEK_PLUGIN_ACTIVATE="Demo::Hooks" ZEEK_PLUGIN_PATH=`pwd` zeek -b -r $TRACES/http/get.trace %INPUT s1.sig 2>&1 | $SCRIPTS/diff-remove-abspath | sort | uniq >output
|
||||
# @TEST-EXEC: btest-diff output
|
||||
|
||||
@unload base/misc/version
|
||||
@load base/init-default
|
||||
|
||||
@load-sigs s2
|
||||
|
||||
@TEST-START-FILE s1.sig
|
||||
# Just empty.
|
||||
@TEST-END-FILE
|
||||
|
||||
@TEST-START-FILE s2.sig
|
||||
# Just empty.
|
||||
@TEST-END-FILE
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue