diff --git a/CHANGES b/CHANGES index 7e1d10bd95..e1702a1563 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,11 @@ +7.0.0-dev.302 | 2024-05-31 09:37:21 -0700 + + * More precise error reporting for the disable_analyzer() BiF (Christian Kreibich, Corelight) + + * Add btests for the lookup_connection_analyzer_id() BiF. (Christian Kreibich, Corelight) + + * Add BiF for looking up a connection's numeric protocol analyzer IDs (Christian Kreibich, Corelight) + 7.0.0-dev.298 | 2024-05-29 13:49:00 -0700 * removing now-vestigial "add" and "delete" statements (Vern Paxson, Corelight) diff --git a/NEWS b/NEWS index eb0ee24ea6..663de15ebb 100644 --- a/NEWS +++ b/NEWS @@ -39,6 +39,26 @@ New Functionality - SMB2 packets containing multiple PDUs now correctly parse all of the headers, instead of just the first one and ignoring the rest. +- The new built-in function ``lookup_connection_analyzer_id()`` retrieves the + numeric identifier of an analyzer associated with a connection. This enables + the use of the ``disable_analyzer()`` BiF outside of the analyzer + confirmation/violation events that have so far been the only providers of + those identifiers. For example, this allows the suppression of an analyzer + from the outset for specific connections: + + event connection_established(c: connection): + { + if ( no_http_for_this_conn_wanted(c) ) + { + local aid = lookup_connection_analyzer_id(c$id, Analyzer::ANALYZER_HTTP); + if ( aid > 0 ) + disable_analyzer(c$id, aid, T, T); + } + } + + Use ``Analyzer::get_tag()`` if you need to obtain an analyzer's tag from its + name (such as "HTTP"). + Changed Functionality --------------------- diff --git a/VERSION b/VERSION index ac2e2bc370..a129a27ca3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -7.0.0-dev.298 +7.0.0-dev.302 diff --git a/src/zeek.bif b/src/zeek.bif index 4134e72847..2d3d73fcda 100644 --- a/src/zeek.bif +++ b/src/zeek.bif @@ -4121,6 +4121,34 @@ function file_mode%(mode: count%): string #include "zeek/analyzer/Manager.h" %%} +## Returns the numeric ID of the requested protocol analyzer for the given +## connection. +## +## cid: The connection identifier. +## +## atype: The analyzer tag, such as ``Analyzer::ANALYZER_HTTP``. +## +## Returns: a numeric identifier for the analyzer, valid for the given +## connection. When no such analyzer exists the function returns +## 0, which is never a valid analyzer ID value. +## +## .. zeek:see:: disable_analyzer Analyzer::disabling_analyzer +function lookup_connection_analyzer_id%(cid: conn_id, atype: AllAnalyzers::Tag%): count + %{ + Connection* c = session_mgr->FindConnection(cid); + if ( ! c ) + { + zeek::emit_builtin_error("connection ID not a known connection", cid); + return zeek::val_mgr->Count(0); + } + + analyzer::Analyzer* a = c->FindAnalyzer(analyzer_mgr->GetComponentTag(atype)); + if ( ! a ) + return zeek::val_mgr->Count(0); + + return zeek::val_mgr->Count(a->GetID()); + %} + ## Disables the analyzer which raised the current event (if the analyzer ## belongs to the given connection). ## @@ -4144,7 +4172,7 @@ function disable_analyzer%(cid: conn_id, aid: count, err_if_no_conn: bool &defau Connection* c = session_mgr->FindConnection(cid); if ( ! c ) { - zeek::reporter->Error("cannot find connection"); + zeek::emit_builtin_error("connection ID not a known connection", cid); return zeek::val_mgr->False(); } @@ -4152,7 +4180,7 @@ function disable_analyzer%(cid: conn_id, aid: count, err_if_no_conn: bool &defau if ( ! a ) { if ( err_if_no_conn ) - zeek::reporter->Error("connection does not have analyzer specified to disable"); + zeek::emit_builtin_error("connection does not have analyzer specified to disable"); return zeek::val_mgr->False(); } @@ -4162,7 +4190,7 @@ function disable_analyzer%(cid: conn_id, aid: count, err_if_no_conn: bool &defau // of a root analyzer without probing for it. if ( ! a->Parent() ) { - zeek::reporter->Error("root analyzer %s cannot be removed", a->GetAnalyzerName()); + zeek::emit_builtin_error(zeek::util::fmt("root analyzer %s cannot be removed", a->GetAnalyzerName())); return zeek::val_mgr->False(); } diff --git a/testing/btest/Baseline/bifs.disable_analyzer-for-conn-2/output b/testing/btest/Baseline/bifs.disable_analyzer-for-conn-2/output new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/bifs.disable_analyzer-for-conn-2/output @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/Baseline/bifs.disable_analyzer-for-conn-3/output b/testing/btest/Baseline/bifs.disable_analyzer-for-conn-3/output new file mode 100644 index 0000000000..49d861c74c --- /dev/null +++ b/testing/btest/Baseline/bifs.disable_analyzer-for-conn-3/output @@ -0,0 +1 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. diff --git a/testing/btest/Baseline/bifs.disable_analyzer-for-conn/output b/testing/btest/Baseline/bifs.disable_analyzer-for-conn/output new file mode 100644 index 0000000000..bb88a2d5b0 --- /dev/null +++ b/testing/btest/Baseline/bifs.disable_analyzer-for-conn/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. +Analyzer::ANALYZER_HTTP +Analyzer::ANALYZER_HTTP diff --git a/testing/btest/Baseline/bifs.disable_analyzer-invalid-aid/out b/testing/btest/Baseline/bifs.disable_analyzer-invalid-aid/out index 13952f2a52..1777b67d52 100644 --- a/testing/btest/Baseline/bifs.disable_analyzer-invalid-aid/out +++ b/testing/btest/Baseline/bifs.disable_analyzer-invalid-aid/out @@ -1,35 +1,35 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer TCP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer TCP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer TCP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer TCP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer TCP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer TCP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer TCP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer TCP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer TCP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer TCP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed -XXXXXXXXXX.XXXXXX error: root analyzer UDP cannot be removed +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer TCP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer TCP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer TCP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer TCP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer TCP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer TCP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer TCP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer TCP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer TCP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer TCP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) +XXXXXXXXXX.XXXXXX error in <...>/disable_analyzer-invalid-aid.zeek, line 12: root analyzer UDP cannot be removed (disable_analyzer(c$id, i, F, T)) diff --git a/testing/btest/bifs/disable_analyzer-for-conn.zeek b/testing/btest/bifs/disable_analyzer-for-conn.zeek new file mode 100644 index 0000000000..18143e9030 --- /dev/null +++ b/testing/btest/bifs/disable_analyzer-for-conn.zeek @@ -0,0 +1,51 @@ +# Verifies analyzer ID retrieval from a connection. +# +# @TEST-EXEC: zeek -b -r ${TRACES}/ssh/ssh-on-port-80.trace %INPUT >output +# @TEST-EXEC: btest-diff output + +# This first test should trigger two analyzer violations since the given pcap +# has non-HTTP content on port 80, which triggers one violation each for the +# missing request and response lines. + +@load base/protocols/http + +event analyzer_violation_info(atype: AllAnalyzers::Tag, info: AnalyzerViolationInfo) + { + print atype; + } + +# @TEST-START-NEXT + +# This one should not trigger violations since we suppress HTTP analysis when +# the TCP connection establishes. + +@load base/protocols/http + +event analyzer_violation_info(atype: AllAnalyzers::Tag, info: AnalyzerViolationInfo) + { + print atype; + } + +event connection_established(c: connection) + { + local aid = lookup_connection_analyzer_id(c$id, Analyzer::ANALYZER_HTTP); + if ( aid > 0 ) + disable_analyzer(c$id, aid, T, T); + } + +# @TEST-START-NEXT + +# This one validates the return values of analyzer ID lookup calls for valid & +# invalid connection IDs and analyzers. + +@load base/protocols/http + +event connection_established(c: connection) + { + assert lookup_connection_analyzer_id(c$id, Analyzer::ANALYZER_HTTP) != 0; + + local wrong_cid = copy(c$id); + wrong_cid$orig_h = 1.2.3.4; + + assert lookup_connection_analyzer_id(wrong_cid, Analyzer::ANALYZER_HTTP) == 0; + } diff --git a/testing/btest/bifs/disable_analyzer-invalid-aid.zeek b/testing/btest/bifs/disable_analyzer-invalid-aid.zeek index 5738a80575..9643cfa6d1 100644 --- a/testing/btest/bifs/disable_analyzer-invalid-aid.zeek +++ b/testing/btest/bifs/disable_analyzer-invalid-aid.zeek @@ -1,5 +1,5 @@ # @TEST-EXEC: zeek -b -r $TRACES/wikipedia.trace %INPUT >out 2>&1 -# @TEST-EXEC: btest-diff out +# @TEST-EXEC: TEST_DIFF_CANONIFIER='$SCRIPTS/diff-canonifier | $SCRIPTS/diff-remove-abspath' btest-diff out # @TEST-DOC: Validates that one can use disable_analyzer even for analyzers without parent. This is a regression test for #3071. event new_connection(c: connection)