Add analyzer_confirmation and analyzer_violation events

This commit is contained in:
Tim Wojtulewicz 2021-10-25 09:03:15 -07:00
parent 7bffd2eccd
commit 612212568a
96 changed files with 432 additions and 235 deletions

View file

@ -4,6 +4,7 @@
#include "zeek/DebugLogger.h"
#include "zeek/Dict.h"
#include "zeek/Event.h"
#include "zeek/RunState.h"
#include "zeek/session/Manager.h"
#include "zeek/util.h"
@ -166,4 +167,42 @@ void Analyzer::Weird(const char* name, Packet* packet, const char* addl) const
session_mgr->Weird(name, packet, addl, GetAnalyzerName());
}
void Analyzer::AnalyzerConfirmation(session::Session* session, zeek::Tag arg_tag)
{
if ( session->AnalyzerState(arg_tag) == session::AnalyzerConfirmationState::CONFIRMED )
return;
session->SetAnalyzerState(GetAnalyzerTag(), session::AnalyzerConfirmationState::CONFIRMED);
if ( ! analyzer_confirmation )
return;
const auto& tval = arg_tag ? arg_tag.AsVal() : tag.AsVal();
event_mgr.Enqueue(analyzer_confirmation, session->GetVal(), tval, val_mgr->Count(0));
}
void Analyzer::AnalyzerViolation(const char* reason, session::Session* session, const char* data,
int len)
{
if ( ! analyzer_violation )
return;
session->SetAnalyzerState(GetAnalyzerTag(), session::AnalyzerConfirmationState::VIOLATED);
StringValPtr r;
if ( data && len )
{
const char* tmp = util::copy_string(reason);
r = make_intrusive<StringVal>(util::fmt(
"%s [%s%s]", tmp, util::fmt_bytes(data, std::min(40, len)), len > 40 ? "..." : ""));
delete[] tmp;
}
else
r = make_intrusive<StringVal>(reason);
const auto& tval = tag.AsVal();
event_mgr.Enqueue(analyzer_violation, session->GetVal(), tval, val_mgr->Count(0), std::move(r));
}
} // namespace zeek::packet_analysis

View file

@ -6,6 +6,7 @@
#include "zeek/Tag.h"
#include "zeek/iosource/Packet.h"
#include "zeek/packet_analysis/Manager.h"
#include "zeek/session/Session.h"
namespace zeek::packet_analysis
{
@ -126,6 +127,52 @@ public:
*/
virtual bool DetectProtocol(size_t len, const uint8_t* data, Packet* packet) { return false; }
/**
* Signals Zeek's protocol detection that the analyzer has recognized
* the input to indeed conform to the expected protocol. This should
* be called as early as possible during a connection's life-time. It
* may turn into \c analyzer_confirmed event at the script-layer (but
* only once per analyzer for each connection, even if the method is
* called multiple times).
*
* If tag is given, it overrides the analyzer tag passed to the
* scripting layer; the default is the one of the analyzer itself.
*/
virtual void AnalyzerConfirmation(session::Session* session, zeek::Tag tag = zeek::Tag());
/**
* Signals Bro's protocol detection that the analyzer has found a
* severe protocol violation that could indicate that it's not
* parsing the expected protocol. This turns into \c
* analyzer_violation events at the script-layer (one such event is
* raised for each call to this method so that the script-layer can
* built up a notion of how prevalent protocol violations are; the
* more, the less likely it's the right protocol).
*
* @param reason A textual description of the error encountered.
*
* @param data An optional pointer to the malformed data.
*
* @param len If \a data is given, the length of it.
*/
virtual void AnalyzerViolation(const char* reason, session::Session* session,
const char* data = nullptr, int len = 0);
/**
* Returns true if ProtocolConfirmation() has been called at least
* once.
*/
bool AnalyzerConfirmed(session::Session* session) const
{
return session->AnalyzerState(GetAnalyzerTag()) ==
session::AnalyzerConfirmationState::CONFIRMED;
}
bool AnalyzerViolated(session::Session* session) const
{
return session->AnalyzerState(GetAnalyzerTag()) ==
session::AnalyzerConfirmationState::VIOLATED;
}
protected:
friend class Manager;