"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/service_inspectors/wizard/wizard.cc" between
snort3-3.1.29.0.tar.gz and snort3-3.1.30.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.29.0):wizard.cc  (snort3-3.1.30.0)
skipping to change at line 142 skipping to change at line 142
{ {
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 and !w.spell and w.curse_tracker.empty(); }
void reset(Wand&, bool tcp, bool c2s);
void reset(Wand&, bool, bool);
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, const Mag icPage*&); 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;
skipping to change at line 179 skipping to change at line 181
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();
// release trackers // release trackers
for (unsigned i = 0; i < wand.curse_tracker.size(); i++) for ( unsigned i = 0; i < wand.curse_tracker.size(); i++ )
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);
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) or 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;
} }
// 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 and !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;
} }
// ostensibly continue but splitter will be swapped out upon hit // ostensibly continue but splitter will be swapped out upon hit
return SEARCH; return SEARCH;
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
skipping to change at line 272 skipping to change at line 277
{ {
w.hex = c2s_hexes->page1(); w.hex = c2s_hexes->page1();
w.spell = c2s_spells->page1(); w.spell = c2s_spells->page1();
} }
else else
{ {
w.hex = s2c_hexes->page1(); w.hex = s2c_hexes->page1();
w.spell = s2c_spells->page1(); w.spell = s2c_spells->page1();
} }
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
w.curse_tracker.emplace_back( CurseServiceTracker{ curse, nullpt r } ); w.curse_tracker.emplace_back( CurseServiceTracker{ curse, nullpt r } );
} }
} }
} }
void Wizard::eval(Packet* p) void Wizard::eval(Packet* p)
{ {
Profile profile(wizPerfStats); Profile profile(wizPerfStats);
if ( !p->is_udp() ) if ( !p->is_udp() )
return; return;
if ( !p->data || !p->dsize ) if ( !p->data or !p->dsize )
return; return;
bool c2s = p->is_from_client(); bool c2s = p->is_from_client();
Wand wand; Wand wand;
reset(wand, false, c2s); reset(wand, false, c2s);
uint16_t udp_processed_bytes = 0; uint16_t udp_processed_bytes = 0;
++tstats.udp_scans; ++tstats.udp_scans;
if ( cast_spell(wand, p->flow, p->data, p->dsize, udp_processed_bytes) ) if ( cast_spell(wand, p->flow, p->data, p->dsize, udp_processed_bytes) )
{ {
trace_logf(wizard_trace, p, "%s datagram search found service %s\n", trace_logf(wizard_trace, p, "%s datagram search found service %s\n",
c2s ? "c2s" : "s2c", p->flow->service); c2s ? "c2s" : "s2c", p->flow->service);
++tstats.udp_hits; ++tstats.udp_hits;
} }
else else
{ {
p->flow->clear_clouseau(); p->flow->clear_clouseau();
trace_logf(wizard_trace, p, "%s datagram search abandoned\n", c2s ? "c2s " : "s2c"); trace_logf(wizard_trace, p, "%s datagram search abandoned\n", c2s ? "c2s " : "s2c");
skipping to change at line 324 skipping to change at line 331
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 Magic Page*& bookmark) const MagicPage*& m, Flow* f, const uint8_t* data, unsigned len, const Magic Page*& bookmark)
{ {
f->service = m->book.find_spell(data, len, m, bookmark); 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) )
{ {
f->service = cst.curse->service; f->service = cst.curse->service;
if ( f->service ) if ( f->service )
return true; return true;
} }
} }
return false; return false;
} }
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, w.bookmark) ) if ( w.hex and spellbind(w.hex, f, data, len, w.bookmark) )
return true; return true;
if ( w.spell && spellbind(w.spell, f, data, len, w.bookmark) ) if ( w.spell and 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 and wizard_processed_bytes >= max_search_depth )
{ {
w.spell = nullptr; w.spell = nullptr;
w.hex = nullptr; w.hex = nullptr;
for ( const CurseServiceTracker& cst : w.curse_tracker ) for ( const CurseServiceTracker& cst : w.curse_tracker )
delete cst.tracker; delete cst.tracker;
w.curse_tracker.clear(); w.curse_tracker.clear();
} }
 End of changes. 22 change blocks. 
17 lines changed or deleted 24 lines changed or added

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