From: Tom Peters (thopeter) Date: Tue, 26 Mar 2019 14:56:12 +0000 (-0400) Subject: Merge pull request #1532 in SNORT/snort3 from ~NIHDESAI/snort3:snort2lua_zones to... X-Git-Tag: 3.0.0-251~8 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f0e20b8de0a0a7113b98829e11e475296d1f41fe;p=thirdparty%2Fsnort3.git Merge pull request #1532 in SNORT/snort3 from ~NIHDESAI/snort3:snort2lua_zones to master Squashed commit of the following: commit ab76f0b0b651553f40675e5d33511a968ec35a16 Author: Nihal Desai Date: Fri Mar 1 07:22:06 2019 -0500 snort2lua: combining multiple zone in one binder rule --- diff --git a/src/framework/bits.h b/src/framework/bits.h index b309eff5f..b9ba9645f 100644 --- a/src/framework/bits.h +++ b/src/framework/bits.h @@ -27,6 +27,7 @@ typedef std::bitset<65536> PortBitSet; typedef std::bitset<4096> VlanBitSet; typedef std::bitset<256> ByteBitSet; +typedef std::bitset<64> ZoneBitSet; #endif diff --git a/src/framework/value.cc b/src/framework/value.cc index 328dc3ea4..25b40b5dd 100644 --- a/src/framework/value.cc +++ b/src/framework/value.cc @@ -114,6 +114,19 @@ void Value::get_bits(PortBitSet& list) const } } +void Value::get_bits(ZoneBitSet& list) const +{ + list.reset(); + std::size_t len = str.size(); + assert(len == list.size()); + + for ( std::size_t n = 0; n < len; ++n ) + { + if ( str[n] == '1' ) + list.set(n); + } +} + void Value::get_bits(VlanBitSet& list) const { list.reset(); diff --git a/src/framework/value.h b/src/framework/value.h index 68514e4cd..6c7d3c000 100644 --- a/src/framework/value.h +++ b/src/framework/value.h @@ -140,6 +140,7 @@ public: void get_bits(PortBitSet&) const; void get_bits(VlanBitSet&) const; void get_bits(ByteBitSet&) const; + void get_bits(ZoneBitSet&) const; void lower() { std::transform(str.begin(), str.end(), str.begin(), ::tolower); } diff --git a/src/network_inspectors/binder/bind_module.cc b/src/network_inspectors/binder/bind_module.cc index a3aa25b59..45c859115 100644 --- a/src/network_inspectors/binder/bind_module.cc +++ b/src/network_inspectors/binder/bind_module.cc @@ -89,10 +89,13 @@ static const Parameter binder_when_params[] = { "dst_ports", Parameter::PT_BIT_LIST, "65535", nullptr, "list of destination ports" }, - { "src_zone", Parameter::PT_INT, "0:max31", nullptr, + { "zones", Parameter::PT_BIT_LIST, "63", nullptr, + "zones" }, + + { "src_zone", Parameter::PT_BIT_LIST, "63", nullptr, "source zone" }, - { "dst_zone", Parameter::PT_INT, "0:max31", nullptr, + { "dst_zone", Parameter::PT_BIT_LIST, "63", nullptr, "destination zone" }, { "role", Parameter::PT_ENUM, "client | server | any", "any", @@ -230,11 +233,21 @@ bool BinderModule::set(const char* fqn, Value& v, SnortConfig*) work->when.split_ports = true; } + else if ( v.is("zones") ) + { + v.get_bits(work->when.src_zones); + unsplit_zones = true; + } else if ( v.is("src_zone") ) - work->when.src_zone = v.get_int32(); - + { + v.get_bits(work->when.src_zones); + work->when.split_zones = true; + } else if ( v.is("dst_zone") ) - work->when.dst_zone = v.get_int32(); + { + v.get_bits(work->when.dst_zones); + work->when.split_zones = true; + } else if ( v.is("role") ) work->when.role = (BindWhen::Role)v.get_uint8(); @@ -281,6 +294,7 @@ bool BinderModule::begin(const char* fqn, int idx, SnortConfig*) work = new Binding; unsplit_nets = false; unsplit_ports = false; + unsplit_zones = false; use_name_count = 0; use_type_count = 0; } @@ -297,6 +311,9 @@ static void split_nets_warning() static void split_ports_warning() { ParseWarning(WARN_CONF, "src_ports and dst_ports override ports"); } +static void split_zones_warning() +{ ParseWarning(WARN_CONF, "src_zones and dst_zones override zones"); } + bool BinderModule::end(const char* fqn, int idx, SnortConfig* sc) { if ( idx && !strcmp(fqn, BIND_NAME) ) @@ -313,6 +330,9 @@ bool BinderModule::end(const char* fqn, int idx, SnortConfig* sc) if ( unsplit_ports && work->when.split_ports ) split_ports_warning(); + if ( unsplit_zones && work->when.split_zones ) + split_zones_warning(); + if ( use_type_count > 1 || use_name_count > 1 ) file_name_type_error(); diff --git a/src/network_inspectors/binder/bind_module.h b/src/network_inspectors/binder/bind_module.h index eaa198db8..ad9da623f 100644 --- a/src/network_inspectors/binder/bind_module.h +++ b/src/network_inspectors/binder/bind_module.h @@ -66,6 +66,7 @@ private: std::vector bindings; bool unsplit_nets; bool unsplit_ports; + bool unsplit_zones; unsigned use_name_count; unsigned use_type_count; diff --git a/src/network_inspectors/binder/binder.cc b/src/network_inspectors/binder/binder.cc index a7968aeae..df0e150dd 100644 --- a/src/network_inspectors/binder/binder.cc +++ b/src/network_inspectors/binder/binder.cc @@ -66,13 +66,14 @@ Binding::Binding() when.src_ports.set(); when.dst_ports.set(); + when.split_zones = false; + when.src_zones.set(); + when.dst_zones.set(); + when.protos = PROTO_BIT__ANY_TYPE; when.vlans.set(); when.ifaces.reset(); - when.src_zone = DAQ_PKTHDR_UNKNOWN; - when.dst_zone = DAQ_PKTHDR_UNKNOWN; - when.ips_id = 0; when.ips_id_user = 0; when.role = BindWhen::BR_EITHER; @@ -310,16 +311,43 @@ inline Binding::DirResult Binding::check_split_port( { return when_val.test(traffic_val); }); } -inline Binding::DirResult Binding::check_zone( - const Packet* p, const Binding::DirResult dr) const +inline bool Binding::check_zone(const Packet* p) const { - if ( !p ) + if ( when.split_zones or !p ) + return true; + + if (p->pkth->egress_group == DAQ_PKTHDR_UNKNOWN or + p->pkth->ingress_group == DAQ_PKTHDR_UNKNOWN) + return true; + + assert(((unsigned)p->pkth->ingress_group) < when.src_zones.size()); + assert(((unsigned)p->pkth->egress_group) < when.dst_zones.size()); + + if (when.src_zones.test((unsigned)p->pkth->ingress_group) or + when.dst_zones.test((unsigned)p->pkth->egress_group)) + return true; + return false; +} + +inline Binding::DirResult Binding::check_split_zone(const Packet* p, const Binding::DirResult dr) const +{ + if ( !when.split_zones ) return dr; - return directional_match(when.src_zone, when.dst_zone, - p->pkth->ingress_group, p->pkth->egress_group, dr, - [](int32_t when_val, int32_t zone) - { return when_val == DAQ_PKTHDR_UNKNOWN or when_val == zone; }); + int src_zone; + int dst_zone; + + if ( p ) + { + src_zone = p->pkth->ingress_group; + dst_zone = p->pkth->egress_group; + } + else + return dr; + + return directional_match(when.src_zones, when.dst_zones, src_zone, dst_zone, dr, + [](const ZoneBitSet& when_val, int traffic_val) + { return traffic_val == DAQ_PKTHDR_UNKNOWN ? true : when_val.test(traffic_val); }); } bool Binding::check_all(const Flow* flow, Packet* p) const @@ -353,11 +381,14 @@ bool Binding::check_all(const Flow* flow, Packet* p) const if ( dir == Binding::DR_NO_MATCH ) return false; + dir = check_split_zone(p, dir); + if ( dir == Binding::DR_NO_MATCH ) + return false; + if ( !check_service(flow) ) return false; - dir = check_zone(p, dir); - if ( dir == Binding::DR_NO_MATCH ) + if ( !check_zone(p) ) return false; return true; diff --git a/src/network_inspectors/binder/binding.h b/src/network_inspectors/binder/binding.h index 4f00ed7db..8e31dc1f4 100644 --- a/src/network_inspectors/binder/binding.h +++ b/src/network_inspectors/binder/binding.h @@ -54,8 +54,9 @@ struct BindWhen PortBitSet src_ports; PortBitSet dst_ports; - int32_t src_zone; - int32_t dst_zone; + bool split_zones; + ZoneBitSet src_zones; + ZoneBitSet dst_zones; }; struct BindUse @@ -112,8 +113,9 @@ struct Binding bool check_proto(const snort::Flow*) const; bool check_port(const snort::Flow*) const; DirResult check_split_port(const snort::Flow*, const snort::Packet*, const DirResult) const; + bool check_zone(const snort::Packet*) const; + DirResult check_split_zone(const snort::Packet*, const DirResult) const; bool check_service(const snort::Flow*) const; - DirResult check_zone(const snort::Packet*, const DirResult) const; }; #endif diff --git a/tools/snort2lua/helpers/util_binder.cc b/tools/snort2lua/helpers/util_binder.cc index 8f4b4eee9..796483520 100644 --- a/tools/snort2lua/helpers/util_binder.cc +++ b/tools/snort2lua/helpers/util_binder.cc @@ -75,11 +75,14 @@ void Binder::add_to_configuration() for ( const auto& p : ports ) table_api.add_list("ports", p); - if ( has_src_zone() ) - table_api.add_option("src_zone", std::stoi(when_src_zone)); + for ( const auto& p : when_src_zone ) + table_api.add_list("src_zone", p); - if ( has_dst_zone() ) - table_api.add_option("dst_zone", std::stoi(when_dst_zone)); + for ( const auto& p : when_dst_zone ) + table_api.add_list("dst_zone", p); + + for ( const auto& p : zones ) + table_api.add_list("zones", p); if ( has_proto() ) table_api.add_option("proto", when_proto); @@ -178,10 +181,13 @@ void Binder::add_when_port(const std::string& port) { ports.push_back(port); } void Binder::set_when_src_zone(const std::string& zone) -{ when_src_zone = zone; } +{ when_src_zone.push_back(zone); } void Binder::set_when_dst_zone(const std::string& zone) -{ when_dst_zone = zone; } +{ when_dst_zone.push_back(zone); } + +void Binder::add_when_zone(const std::string& zone) +{ zones.push_back(zone); } void Binder::clear_ports() { ports.clear(); } @@ -344,9 +350,12 @@ void print_binder_priorities() binders.back()->add_when_port("a"); if ( i & (1 << 11) ) - binders.back()->set_when_proto("a"); + binders.back()->add_when_zone("a"); if ( i & (1 << 12) ) + binders.back()->set_when_proto("a"); + + if ( i & (1 << 13) ) binders.back()->set_when_role("a"); } diff --git a/tools/snort2lua/helpers/util_binder.h b/tools/snort2lua/helpers/util_binder.h index 63af34891..73263eb8b 100644 --- a/tools/snort2lua/helpers/util_binder.h +++ b/tools/snort2lua/helpers/util_binder.h @@ -65,6 +65,7 @@ public: void add_when_src_net(const std::string&); void add_when_dst_net(const std::string&); void add_when_port(const std::string&); + void add_when_zone(const std::string&); void add_when_src_port(const std::string&); void add_when_dst_port(const std::string&); void set_when_src_zone(const std::string&); @@ -152,8 +153,9 @@ private: std::vector ports; std::vector src_ports; std::vector dst_ports; - std::string when_src_zone; - std::string when_dst_zone; + std::vector when_src_zone; + std::vector when_dst_zone; + std::vector zones; std::string use_type; std::string use_name;