"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/service_inspectors/wizard/wizard.cc" between
snort3-3.1.28.0.tar.gz and snort3-3.1.29.0.tar.gz

About: Snort 3 is a network intrusion prevention and detection system (IDS/IPS) combining the benefits of signature, protocol and anomaly-based inspection.

wizard.cc  (snort3-3.1.28.0):wizard.cc  (snort3-3.1.29.0)
skipping to change at line 83 skipping to change at line 83
struct CurseServiceTracker struct CurseServiceTracker
{ {
const CurseDetails* curse; const CurseDetails* curse;
CurseTracker* tracker; CurseTracker* tracker;
}; };
struct Wand struct Wand
{ {
const MagicPage* hex; const MagicPage* hex;
const MagicPage* spell; const MagicPage* spell;
const MagicPage* bookmark;
vector<CurseServiceTracker> curse_tracker; vector<CurseServiceTracker> curse_tracker;
}; };
class Wizard; class Wizard;
class MagicSplitter : public StreamSplitter class MagicSplitter : public StreamSplitter
{ {
public: public:
MagicSplitter(bool, class Wizard*); MagicSplitter(bool, class Wizard*);
~MagicSplitter() override; ~MagicSplitter() override;
skipping to change at line 128 skipping to change at line 129
if ( f->pkt_type == PktType::TCP ) if ( f->pkt_type == PktType::TCP )
++tstats.tcp_misses; ++tstats.tcp_misses;
else else
++tstats.user_misses; ++tstats.user_misses;
} }
private: private:
Wizard* wizard; Wizard* wizard;
Wand wand; Wand wand;
uint16_t wizard_processed_bytes; uint16_t wizard_processed_bytes;
const MagicPage* bookmark; // pointer to last glob
}; };
class Wizard : public Inspector class Wizard : public Inspector
{ {
public: public:
Wizard(WizardModule*); Wizard(WizardModule*);
~Wizard() override; ~Wizard() override;
void eval(Packet*) override; void eval(Packet*) override;
StreamSplitter* get_splitter(bool) override; StreamSplitter* get_splitter(bool) override;
inline bool finished(Wand& w) inline bool finished(Wand& w)
{ return !w.hex && !w.spell && w.curse_tracker.empty(); } { return !w.hex && !w.spell && w.curse_tracker.empty(); }
void reset(Wand&, bool tcp, bool c2s); void reset(Wand&, bool tcp, bool c2s);
bool cast_spell(Wand&, Flow*, const uint8_t*, unsigned, uint16_t&); bool cast_spell(Wand&, Flow*, const uint8_t*, unsigned, uint16_t&);
bool spellbind(const MagicPage*&, Flow*, const uint8_t*, unsigned); bool spellbind(const MagicPage*&, Flow*, const uint8_t*, unsigned, const Mag icPage*&);
bool cursebind(const vector<CurseServiceTracker>&, Flow*, const uint8_t*, un signed); bool cursebind(const vector<CurseServiceTracker>&, Flow*, const uint8_t*, un signed);
public: public:
MagicBook* c2s_hexes; MagicBook* c2s_hexes;
MagicBook* s2c_hexes; MagicBook* s2c_hexes;
MagicBook* c2s_spells; MagicBook* c2s_spells;
MagicBook* s2c_spells; MagicBook* s2c_spells;
CurseBook* curses; CurseBook* curses;
skipping to change at line 167 skipping to change at line 167
uint16_t max_search_depth; uint16_t max_search_depth;
}; };
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// splitter - this doesn't actually split the stream but it applies // splitter - this doesn't actually split the stream but it applies
// basic magic type logic to determine the appropriate inspector that // basic magic type logic to determine the appropriate inspector that
// will split the stream. // will split the stream.
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
MagicSplitter::MagicSplitter(bool c2s, class Wizard* w) : MagicSplitter::MagicSplitter(bool c2s, class Wizard* w) :
StreamSplitter(c2s), wizard_processed_bytes(0), bookmark(nullptr) StreamSplitter(c2s), wizard_processed_bytes(0)
{ {
wizard = w; wizard = w;
w->add_ref(); w->add_ref();
w->reset(wand, true, c2s); w->reset(wand, true, c2s);
} }
MagicSplitter::~MagicSplitter() MagicSplitter::~MagicSplitter()
{ {
wizard->rem_ref(); wizard->rem_ref();
skipping to change at line 190 skipping to change at line 190
delete wand.curse_tracker[i].tracker; delete wand.curse_tracker[i].tracker;
} }
StreamSplitter::Status MagicSplitter::scan( StreamSplitter::Status MagicSplitter::scan(
Packet* pkt, const uint8_t* data, uint32_t len, Packet* pkt, const uint8_t* data, uint32_t len,
uint32_t, uint32_t*) uint32_t, uint32_t*)
{ {
Profile profile(wizPerfStats); Profile profile(wizPerfStats);
count_scan(pkt->flow); count_scan(pkt->flow);
// setting last glob from current flow
if ( wand.spell )
wand.spell->book.set_bookmark(bookmark);
bytes_scanned += len; bytes_scanned += len;
if ( wizard->cast_spell(wand, pkt->flow, data, len, wizard_processed_bytes) ) if ( wizard->cast_spell(wand, pkt->flow, data, len, wizard_processed_bytes) )
{ {
trace_logf(wizard_trace, pkt, "%s streaming search found service %s\n", trace_logf(wizard_trace, pkt, "%s streaming search found service %s\n",
to_server() ? "c2s" : "s2c", pkt->flow->service); to_server() ? "c2s" : "s2c", pkt->flow->service);
count_hit(pkt->flow); count_hit(pkt->flow);
wizard_processed_bytes = 0; wizard_processed_bytes = 0;
return STOP; return STOP;
} }
else if ( wizard->finished(wand) || bytes_scanned >= max(pkt->flow) ) else if ( wizard->finished(wand) || bytes_scanned >= max(pkt->flow) )
{ {
count_miss(pkt->flow); count_miss(pkt->flow);
trace_logf(wizard_trace, pkt, "%s streaming search abandoned\n", to_serv er() ? "c2s" : "s2c"); trace_logf(wizard_trace, pkt, "%s streaming search abandoned\n", to_serv er() ? "c2s" : "s2c");
wizard_processed_bytes = 0; wizard_processed_bytes = 0;
if (!pkt->flow->flags.svc_event_generated) if (!pkt->flow->flags.svc_event_generated)
{ {
DataBus::publish(FLOW_NO_SERVICE_EVENT, pkt); DataBus::publish(FLOW_NO_SERVICE_EVENT, pkt);
pkt->flow->flags.svc_event_generated = true; pkt->flow->flags.svc_event_generated = true;
} }
return ABORT; return ABORT;
} }
// saving new last glob from current flow
if ( wand.spell )
bookmark = wand.spell->book.get_bookmark();
// FIXIT-L Ideally, this event should be raised after wizard aborts its sear ch. However, this // FIXIT-L Ideally, this event should be raised after wizard aborts its sear ch. However, this
// could take multiple packets because wizard needs wizard.max_search_depth payload bytes before // could take multiple packets because wizard needs wizard.max_search_depth payload bytes before
// it aborts. This is an issue for AppId which consumes this event. AppId is required to declare // it aborts. This is an issue for AppId which consumes this event. AppId is required to declare
// unknown service as soon as it can so that the flow actions (such as IPS b lock, etc) don't get // unknown service as soon as it can so that the flow actions (such as IPS b lock, etc) don't get
// delayed. Because AppId depends on wizard only for SSH detection and SSH i nspector can be // delayed. Because AppId depends on wizard only for SSH detection and SSH i nspector can be
// attached very early, event is raised here after first scan. In the future , wizard should be // attached very early, event is raised here after first scan. In the future , wizard should be
// enhanced to abort sooner if it can't detect service. // enhanced to abort sooner if it can't detect service.
if (!pkt->flow->service && !pkt->flow->flags.svc_event_generated) if (!pkt->flow->service && !pkt->flow->flags.svc_event_generated)
{ {
DataBus::publish(FLOW_NO_SERVICE_EVENT, pkt); DataBus::publish(FLOW_NO_SERVICE_EVENT, pkt);
skipping to change at line 267 skipping to change at line 259
delete s2c_hexes; delete s2c_hexes;
delete c2s_spells; delete c2s_spells;
delete s2c_spells; delete s2c_spells;
delete curses; delete curses;
} }
void Wizard::reset(Wand& w, bool tcp, bool c2s) void Wizard::reset(Wand& w, bool tcp, bool c2s)
{ {
w.bookmark = nullptr;
if ( c2s ) if ( c2s )
{ {
w.hex = c2s_hexes->page1(); w.hex = c2s_hexes->page1();
w.spell = c2s_spells->page1(); w.spell = c2s_spells->page1();
c2s_spells->set_bookmark();
} }
else else
{ {
w.hex = s2c_hexes->page1(); w.hex = s2c_hexes->page1();
w.spell = s2c_spells->page1(); w.spell = s2c_spells->page1();
s2c_spells->set_bookmark();
} }
if (w.curse_tracker.empty()) if (w.curse_tracker.empty())
{ {
vector<const CurseDetails*> pages = curses->get_curses(tcp); vector<const CurseDetails*> pages = curses->get_curses(tcp);
for ( const CurseDetails* curse : pages ) for ( const CurseDetails* curse : pages )
{ {
if (tcp) if (tcp)
w.curse_tracker.emplace_back( CurseServiceTracker{ curse, new Cu rseTracker } ); w.curse_tracker.emplace_back( CurseServiceTracker{ curse, new Cu rseTracker } );
else else
skipping to change at line 329 skipping to change at line 321
++tstats.udp_misses; ++tstats.udp_misses;
} }
} }
StreamSplitter* Wizard::get_splitter(bool c2s) StreamSplitter* Wizard::get_splitter(bool c2s)
{ {
return new MagicSplitter(c2s, this); return new MagicSplitter(c2s, this);
} }
bool Wizard::spellbind( bool Wizard::spellbind(
const MagicPage*& m, Flow* f, const uint8_t* data, unsigned len) const MagicPage*& m, Flow* f, const uint8_t* data, unsigned len, const Magic Page*& bookmark)
{ {
f->service = m->book.find_spell(data, len, m); f->service = m->book.find_spell(data, len, m, bookmark);
return f->service != nullptr; return f->service != nullptr;
} }
bool Wizard::cursebind(const vector<CurseServiceTracker>& curse_tracker, Flow* f , bool Wizard::cursebind(const vector<CurseServiceTracker>& curse_tracker, Flow* f ,
const uint8_t* data, unsigned len) const uint8_t* data, unsigned len)
{ {
for (const CurseServiceTracker& cst : curse_tracker) for (const CurseServiceTracker& cst : curse_tracker)
{ {
if (cst.curse->alg(data, len, cst.tracker)) if (cst.curse->alg(data, len, cst.tracker))
{ {
skipping to change at line 360 skipping to change at line 352
bool Wizard::cast_spell( bool Wizard::cast_spell(
Wand& w, Flow* f, const uint8_t* data, unsigned len, uint16_t& wizard_proces sed_bytes) Wand& w, Flow* f, const uint8_t* data, unsigned len, uint16_t& wizard_proces sed_bytes)
{ {
auto curse_len = len; auto curse_len = len;
len = std::min(len, static_cast<unsigned>(max_search_depth - wizard_processe d_bytes)); len = std::min(len, static_cast<unsigned>(max_search_depth - wizard_processe d_bytes));
wizard_processed_bytes += len; wizard_processed_bytes += len;
if ( w.hex && spellbind(w.hex, f, data, len) ) if ( w.hex && spellbind(w.hex, f, data, len, w.bookmark) )
return true; return true;
if ( w.spell && spellbind(w.spell, f, data, len) ) if ( w.spell && spellbind(w.spell, f, data, len, w.bookmark) )
return true; return true;
if (cursebind(w.curse_tracker, f, data, curse_len)) if (cursebind(w.curse_tracker, f, data, curse_len))
return true; return true;
// If we reach max value of wizard_processed_bytes, // If we reach max value of wizard_processed_bytes,
// but not assign any inspector - raise tcp_miss and stop // but not assign any inspector - raise tcp_miss and stop
if ( !f->service && wizard_processed_bytes >= max_search_depth ) if ( !f->service && wizard_processed_bytes >= max_search_depth )
{ {
w.spell = nullptr; w.spell = nullptr;
 End of changes. 14 change blocks. 
17 lines changed or deleted 9 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)