From 85ce48eb1e1cb1cb61cf4f15560b445acd651c5b Mon Sep 17 00:00:00 2001 From: Arne Welzel Date: Fri, 2 Dec 2022 15:36:49 +0100 Subject: [PATCH] analyzer/files: handle non-analyzer names in describe_file() When a fa_file object is created through the use of Input::add_analysis(), the fa_file's source is likely not valid representation of an analyzer's tag and a Files::describe() should not error and instead return an empty description. Add a new Analyzer::is_tag() helper that can be used to pre-check `f$source`. --- scripts/base/frameworks/analyzer/main.zeek | 15 ++++++++ scripts/base/frameworks/files/main.zeek | 3 ++ src/analyzer/analyzer.bif | 28 ++++++++++----- .../files.log | 10 ++++++ .../notice.log | 10 ++++++ .../output | 3 ++ .../frameworks/notice/file-info-no-conns.zeek | 36 +++++++++++++++++++ 7 files changed, 97 insertions(+), 8 deletions(-) create mode 100644 testing/btest/Baseline/scripts.base.frameworks.notice.file-info-no-conns/files.log create mode 100644 testing/btest/Baseline/scripts.base.frameworks.notice.file-info-no-conns/notice.log create mode 100644 testing/btest/Baseline/scripts.base.frameworks.notice.file-info-no-conns/output create mode 100644 testing/btest/scripts/base/frameworks/notice/file-info-no-conns.zeek diff --git a/scripts/base/frameworks/analyzer/main.zeek b/scripts/base/frameworks/analyzer/main.zeek index ad8d70fb1b..39932a56ad 100644 --- a/scripts/base/frameworks/analyzer/main.zeek +++ b/scripts/base/frameworks/analyzer/main.zeek @@ -88,6 +88,16 @@ export { ## Returns: The analyzer name corresponding to the tag. global name: function(tag: Analyzer::Tag) : string; + ## Check whether the given analyzer name exists. + ## + ## This can be used before calling :zeek:see:`Analyzer::get_tag` to + ## verify that the given name as string is a valid analyzer name. + ## + ## name: The analyzer name. + ## + ## Returns: True if the given name is a valid analyzer, else false. + global has_tag: function(name: string): bool; + ## Translates an analyzer's name to a tag enum value. ## ## name: The analyzer name. @@ -216,6 +226,11 @@ function name(atype: AllAnalyzers::Tag) : string return __name(atype); } +function has_tag(name: string): bool + { + return __has_tag(name); + } + function get_tag(name: string): AllAnalyzers::Tag { return __tag(name); diff --git a/scripts/base/frameworks/files/main.zeek b/scripts/base/frameworks/files/main.zeek index 315386c501..da5ef00fc9 100644 --- a/scripts/base/frameworks/files/main.zeek +++ b/scripts/base/frameworks/files/main.zeek @@ -499,6 +499,9 @@ function all_registered_mime_types(): table[Files::Tag] of set[string] function describe(f: fa_file): string { + if ( ! Analyzer::has_tag(f$source) ) + return ""; + local tag = Analyzer::get_tag(f$source); if ( tag !in registered_protocols ) return ""; diff --git a/src/analyzer/analyzer.bif b/src/analyzer/analyzer.bif index 1252a352a2..af785de238 100644 --- a/src/analyzer/analyzer.bif +++ b/src/analyzer/analyzer.bif @@ -53,16 +53,28 @@ function __name%(atype: AllAnalyzers::Tag%) : string return component->CanonicalNameVal(); %} +%%{ +static zeek::plugin::Component* component_for_name(const char* name) + { + zeek::plugin::Component* component = zeek::analyzer_mgr->Lookup(name); + if ( ! component ) + component = zeek::packet_mgr->Lookup(name); + if ( ! component ) + component = zeek::file_mgr->Lookup(name); + + return component; + } +%%} + function __tag%(name: string%) : AllAnalyzers::Tag %{ - auto val = name->CheckString(); - - plugin::Component* component = zeek::analyzer_mgr->Lookup(val); - if ( ! component ) - component = zeek::packet_mgr->Lookup(val); - if ( ! component ) - component = zeek::file_mgr->Lookup(val); - + plugin::Component* component = component_for_name(name->CheckString()); zeek::Tag t = component ? component->Tag() : zeek::Tag(); return t.AsVal(); %} + +function __has_tag%(name: string%) : bool + %{ + plugin::Component* component = component_for_name(name->CheckString()); + return zeek::val_mgr->Bool(component != nullptr); + %} diff --git a/testing/btest/Baseline/scripts.base.frameworks.notice.file-info-no-conns/files.log b/testing/btest/Baseline/scripts.base.frameworks.notice.file-info-no-conns/files.log new file mode 100644 index 0000000000..f56077505d --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.notice.file-info-no-conns/files.log @@ -0,0 +1,10 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path files +#open XXXX-XX-XX-XX-XX-XX +#fields ts fuid uid id.orig_h id.orig_p id.resp_h id.resp_p source depth analyzers mime_type filename duration local_orig is_orig seen_bytes total_bytes missing_bytes overflow_bytes timedout parent_fuid +#types time string string addr port addr port string count set[string] string string interval bool bool count count count count bool string +XXXXXXXXXX.XXXXXX F6EpcI3V7f021PQMmh - - - - - ./myfile 0 SHA1 application/pdf - 0.000000 - - 73 - 0 0 F - diff --git a/testing/btest/Baseline/scripts.base.frameworks.notice.file-info-no-conns/notice.log b/testing/btest/Baseline/scripts.base.frameworks.notice.file-info-no-conns/notice.log new file mode 100644 index 0000000000..ed525b8033 --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.notice.file-info-no-conns/notice.log @@ -0,0 +1,10 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path notice +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p fuid file_mime_type file_desc proto note msg sub src dst p n peer_descr actions email_dest suppress_for +#types time string addr port addr port string string string enum enum string string addr addr port count string set[enum] set[string] interval +XXXXXXXXXX.XXXXXX - - - - - F6EpcI3V7f021PQMmh application/pdf (empty) - NoticeTestType test - - - - - - Notice::ACTION_LOG (empty) 3600.000000 diff --git a/testing/btest/Baseline/scripts.base.frameworks.notice.file-info-no-conns/output b/testing/btest/Baseline/scripts.base.frameworks.notice.file-info-no-conns/output new file mode 100644 index 0000000000..7eea8fd69a --- /dev/null +++ b/testing/btest/Baseline/scripts.base.frameworks.notice.file-info-no-conns/output @@ -0,0 +1,3 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +file_hash, sha1, 0 +[fuid=F6EpcI3V7f021PQMmh, desc=, mime=application/pdf, cid=, cuid=] diff --git a/testing/btest/scripts/base/frameworks/notice/file-info-no-conns.zeek b/testing/btest/scripts/base/frameworks/notice/file-info-no-conns.zeek new file mode 100644 index 0000000000..ed8b4309e1 --- /dev/null +++ b/testing/btest/scripts/base/frameworks/notice/file-info-no-conns.zeek @@ -0,0 +1,36 @@ +# @TEST-DOC: Call create_file_info() and populate_file_info2() when a file has been added through Input::add_analysis() + +# @TEST-EXEC: zeek -b %INPUT > output +# @TEST-EXEC: btest-diff output +# @TEST-EXEC: btest-diff files.log +# @TEST-EXEC: btest-diff notice.log + +@load base/protocols/http +@load base/frameworks/files + +redef enum Notice::Type += { NoticeTestType }; + +event file_new(f: fa_file) + { + Files::add_analyzer(f, Files::ANALYZER_SHA1); + } + +event file_hash(f: fa_file, kind: string, hash: string) + { + print "file_hash", kind, f?$conns ? |f$conns| : 0; + local fi = Notice::create_file_info(f); + print fi; + local n: Notice::Info = Notice::Info($note=NoticeTestType, $msg="test"); + Notice::populate_file_info2(fi, n); + NOTICE(n); + } + +event zeek_init() + { + Input::add_analysis([$source="./myfile", $name="./myfile"]); + } + +@TEST-START-FILE ./myfile +%PDF-1.5 +This isn't an actual pdf, but it shows in files.log as such :-) +@TEST-END-FILE