]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1031 in SNORT/snort3 from binder_zones to master
authorMichael Altizer (mialtize) <mialtize@cisco.com>
Fri, 6 Oct 2017 21:00:39 +0000 (17:00 -0400)
committerMichael Altizer (mialtize) <mialtize@cisco.com>
Fri, 6 Oct 2017 21:00:39 +0000 (17:00 -0400)
Squashed commit of the following:

commit 08bd025019ff9a61a035fc9f8faa99d48bc6f132
Author: Carter Waxman <cwaxman@cisco.com>
Date:   Fri Oct 6 10:46:02 2017 -0400

    fixed build issues on OSX

commit 5bb5412170ab5c01714a71fd01b762883899e71d
Author: Carter Waxman <cwaxman@cisco.com>
Date:   Tue Oct 3 15:47:59 2017 -0400

    snort2lua: removed port dce proxy bindings to fix http_inspect conflicts

commit 54a5be5daf20ce10fc404b92d897b3a4c700dd1d
Author: Carter Waxman <cwaxman@cisco.com>
Date:   Fri Sep 29 12:12:55 2017 -0400

    snort2lua: added nap.rules zone translation

commit c09df9d2a008f0e319f697de41dd86cc14396657
Author: Carter Waxman <cwaxman@cisco.com>
Date:   Thu Oct 5 08:56:05 2017 -0400

    binder: check interface on packet instead of flow

commit b6f365f960d42b97ebf7b396508699e0c2670b09
Author: Carter Waxman <cwaxman@cisco.com>
Date:   Thu Sep 28 15:37:13 2017 -0400

    binder: added zones

src/decompress/file_decomp.h
src/flow/flow.h
src/managers/so_manager.cc
src/network_inspectors/binder/bind_module.cc
src/network_inspectors/binder/binder.cc
src/network_inspectors/binder/binding.h
src/service_inspectors/http_inspect/http_stream_splitter_reassemble.cc
tools/snort2lua/helpers/util_binder.cc
tools/snort2lua/helpers/util_binder.h
tools/snort2lua/preprocessor_states/pps_dcerpc_server.cc
tools/snort2lua/preprocessor_states/pps_nap_selector.cc

index 69dc0e2b5da7a276eb80c1e2f3732d67d1b52be5..c4ad6f1bb204363d4a3398795b3bbd46ed4378e8 100644 (file)
@@ -138,7 +138,7 @@ struct fd_session_t
    of the underlying decompression engine context. */
 #ifndef SYNC_IN
 #define SYNC_IN(dest) \
-    dest->next_in = const_cast<z_const Bytef*>(SessionPtr->Next_In); \
+    dest->next_in = (Bytef*)(SessionPtr->Next_In); \
     (dest)->avail_in = SessionPtr->Avail_In; \
     (dest)->total_in = SessionPtr->Total_In; \
     (dest)->next_out = SessionPtr->Next_Out; \
index c8aa42a8cfe72769594a1acdd023496779eb8be6..135a79e125d7da9e52444ee7cdf612a5319573ab 100644 (file)
@@ -328,9 +328,6 @@ public:  // FIXIT-M privatize if possible
     unsigned ips_policy_id;
     unsigned network_policy_id;
 
-    int32_t iface_in;
-    int32_t iface_out;
-
     uint16_t client_port;
     uint16_t server_port;
 
index 078f68d36d5dc35f6ceef7980ea74c758976f38d..c02afd0844be3d08be2d71bdaffc04d0942a53ca 100644 (file)
@@ -88,7 +88,7 @@ static const uint8_t* compress(const string& text, unsigned& len)
     if ( ret != Z_OK )
         return nullptr;
 
-    stream.next_in = (z_const Bytef*)s;
+    stream.next_in = (Bytef*)s;
     stream.avail_in = text.size();
 
     stream.next_out = so_buf;
@@ -121,7 +121,7 @@ static const char* expand(const uint8_t* data, unsigned len)
     if ( inflateInit2(&stream, window_bits) != Z_OK )
         return nullptr;
 
-    stream.next_in = const_cast<z_const Bytef*>(data);
+    stream.next_in = (Bytef*)data;
     stream.avail_in = (uInt)len;
 
     stream.next_out = (Bytef*)so_buf;
index f58c973a9db0cc267d3778e82979f42de33676f7..8bf6e40de5b49a22395b8b46ce7cb1a2915936e0 100644 (file)
@@ -52,6 +52,7 @@ static const PegInfo bind_pegs[] =
 // binder module
 //-------------------------------------------------------------------------
 
+#define INT32_MAX_STR "2147483647"
 static const Parameter binder_when_params[] =
 {
     // FIXIT-L when.policy_id should be an arbitrary string auto converted
@@ -87,6 +88,12 @@ static const Parameter binder_when_params[] =
     { "dst_ports", Parameter::PT_BIT_LIST, "65535", nullptr,
       "list of destination ports" },
 
+    { "src_zone", Parameter::PT_INT, "0:" INT32_MAX_STR, nullptr,
+      "source zone" },
+
+    { "dst_zone", Parameter::PT_INT, "0:" INT32_MAX_STR, nullptr,
+      "destination zone" },
+
     { "role", Parameter::PT_ENUM, "client | server | any", "any",
       "use the given configuration on one or any end of a session" },
 
@@ -219,6 +226,12 @@ bool BinderModule::set(const char* fqn, Value& v, SnortConfig*)
         work->when.split_ports = true;
     }
 
+    else if ( v.is("src_zone") )
+        work->when.src_zone = v.get_long();
+
+    else if ( v.is("dst_zone") )
+        work->when.dst_zone = v.get_long();
+
     else if ( v.is("role") )
         work->when.role = (BindWhen::Role)v.get_long();
 
index c75bdee99818ca59a5be69e4cc08422ecd48e9b9..3269adac7657a90df85e028329a33cb3128f8fa6 100644 (file)
@@ -30,6 +30,8 @@
 #include "managers/inspector_manager.h"
 #include "profiler/profiler.h"
 #include "protocols/packet.h"
+#include "protocols/tcp.h"
+#include "protocols/udp.h"
 #include "stream/stream.h"
 #include "stream/stream_splitter.h"
 #include "target_based/sftarget_reader.h"
@@ -66,7 +68,10 @@ Binding::Binding()
 
     when.protos = (unsigned)PktType::ANY;
     when.vlans.set();
-    when.ifaces.set();
+    when.ifaces.reset();
+
+    when.src_zone = DAQ_PKTHDR_UNKNOWN;
+    when.dst_zone = DAQ_PKTHDR_UNKNOWN;
 
     when.ips_id = 0;
     when.role = BindWhen::BR_EITHER;
@@ -128,28 +133,6 @@ bool Binding::check_addr(const Flow* flow) const
     return false;
 }
 
-Binding::DirResult Binding::check_split_addr(const Flow* flow) const
-{
-    if ( !when.split_nets )
-        return Binding::DR_ANY_MATCH;
-
-    if ( !when.src_nets && !when.dst_nets )
-        return Binding::DR_ANY_MATCH;
-
-    bool client_in_src = !when.src_nets or sfvar_ip_in(when.src_nets, &flow->client_ip);
-    bool client_in_dst = !when.dst_nets or sfvar_ip_in(when.dst_nets, &flow->client_ip);
-    bool server_in_src = !when.src_nets or sfvar_ip_in(when.src_nets, &flow->server_ip);
-    bool server_in_dst = !when.dst_nets or sfvar_ip_in(when.dst_nets, &flow->server_ip);
-
-    if ( client_in_src and server_in_dst )
-        return Binding::DR_CLIENT_SRC;
-    
-    if ( server_in_src and client_in_dst )
-        return Binding::DR_SERVER_SRC;
-
-    return Binding::DR_NO_MATCH;
-}
-
 bool Binding::check_proto(const Flow* flow) const
 {
     if ( when.protos & (unsigned)flow->pkt_type )
@@ -158,16 +141,18 @@ bool Binding::check_proto(const Flow* flow) const
     return false;
 }
 
-bool Binding::check_iface(const Flow* flow) const
+bool Binding::check_iface(const Packet* p) const
 {
-    int i = flow->iface_in < 0 ? 0 : flow->iface_in;
-
-    if ( when.ifaces.test(i) )
+    if ( !p or when.ifaces.none() )
         return true;
 
-    i = flow->iface_out < 0 ? 0 : flow->iface_out;
+    auto in = p->pkth->ingress_index;
+    auto out = p->pkth->egress_index;
+
+    if ( in > 0 and when.ifaces.test(out) )
+        return true;
 
-    if ( when.ifaces.test(i) )
+    if ( out > 0 and when.ifaces.test(out) )
         return true;
 
     return false;
@@ -198,58 +183,145 @@ bool Binding::check_port(const Flow* flow) const
     return false;
 }
 
-bool Binding::check_split_port(const Flow* flow, const DirResult dr) const
+bool Binding::check_service(const Flow* flow) const
 {
-    if ( !when.split_ports )
+    if ( !flow->service )
+        return when.svc.empty();
+
+    if ( when.svc == flow->service )
         return true;
 
-    bool client_in_src = false;
-    bool client_in_dst = false;
-    bool server_in_src = false;
-    bool server_in_dst = false;
+    return false;
+}
+
+// we want to correlate src_zone to src_nets and src_ports, and dst_zone to dst_nets and
+// dst_ports. it doesn't matter if the packet is actually moving in the opposite direction as
+// binder is only evaluated once per flow and we need to capture the correct binding from
+// either side of the conversation
+template<typename When, typename Traffic, typename Compare>
+Binding::DirResult directional_match(const When& when_src, const When& when_dst,
+    const Traffic& traffic_src, const Traffic& traffic_dst,
+    const Binding::DirResult dr, const Compare& compare)
+{
+    bool src_in_src = false;
+    bool src_in_dst = false;
+    bool dst_in_src = false;
+    bool dst_in_dst = false;
+    bool forward_match = false;
+    bool reverse_match = false;
 
     switch ( dr )
     {
         case Binding::DR_ANY_MATCH:
-            client_in_src = when.src_ports.test(flow->client_port);
-            client_in_dst = when.dst_ports.test(flow->client_port);
-            server_in_src = when.src_ports.test(flow->server_port);
-            server_in_dst = when.dst_ports.test(flow->server_port);
-            return ( client_in_src and server_in_dst ) or ( server_in_src and client_in_dst );
-
-        case Binding::DR_CLIENT_SRC:
-            client_in_src = when.src_ports.test(flow->client_port);
-            server_in_dst = when.dst_ports.test(flow->server_port);
-            return client_in_src and server_in_dst;
-
-        case Binding::DR_SERVER_SRC:
-            server_in_src = when.src_ports.test(flow->server_port);
-            client_in_dst = when.dst_ports.test(flow->client_port);
-            return server_in_src and client_in_dst;
+            src_in_src = compare(when_src, traffic_src);
+            src_in_dst = compare(when_dst, traffic_src);
+            dst_in_src = compare(when_src, traffic_dst);
+            dst_in_dst = compare(when_dst, traffic_dst);
+
+            forward_match = src_in_src and dst_in_dst;
+            reverse_match = dst_in_src and src_in_dst;
+
+            if ( forward_match and reverse_match )
+                return dr;
+
+            if ( forward_match )
+                return Binding::DR_FORWARD;
+            
+            if ( reverse_match )
+                return Binding::DR_REVERSE;
+
+            return Binding::DR_NO_MATCH;
+
+        case Binding::DR_FORWARD:
+            src_in_src = compare(when_src, traffic_src);
+            dst_in_dst = compare(when_dst, traffic_dst);
+            return src_in_src and dst_in_dst ? dr : Binding::DR_NO_MATCH;
+
+        case Binding::DR_REVERSE:
+            src_in_dst = compare(when_dst, traffic_src);
+            dst_in_src = compare(when_src, traffic_dst);
+            return src_in_dst and dst_in_src ? dr : Binding::DR_NO_MATCH;
 
         default:
             break;
     }
-    return false;
+
+    return Binding::DR_NO_MATCH;
 }
 
-bool Binding::check_service(const Flow* flow) const
+Binding::DirResult Binding::check_split_addr(const Flow* flow, const Packet* p,
+    const Binding::DirResult dr) const
 {
-    if ( !flow->service )
-        return when.svc.empty();
+    if ( !when.split_nets )
+        return dr;
 
-    if ( when.svc == flow->service )
-        return true;
+    if ( !when.src_nets && !when.dst_nets )
+        return dr;
+    
+    const SfIp* src_ip = &flow->client_ip;
+    const SfIp* dst_ip = &flow->server_ip;
 
-    return false;
+    if ( p && p->ptrs.ip_api.is_ip() )
+    {
+        src_ip = p->ptrs.ip_api.get_src();
+        dst_ip = p->ptrs.ip_api.get_dst();
+    }
+
+    return directional_match(when.src_nets, when.dst_nets, src_ip, dst_ip, dr,
+        [](sfip_var_t* when_val, const SfIp* traffic_val)
+        { return when_val ? sfvar_ip_in(when_val, traffic_val) : true; });
+
+}
+
+Binding::DirResult Binding::check_split_port(const Flow* flow, const Packet* p,
+    const Binding::DirResult dr) const
+{
+    if ( !when.split_ports )
+        return dr;
+    
+    uint16_t src_port = flow->client_port; 
+    uint16_t dst_port = flow->server_port; 
+
+    if ( p )
+    {
+        if ( p->is_tcp() )
+        {
+            src_port = p->ptrs.tcph->src_port();
+            dst_port = p->ptrs.tcph->dst_port();
+        }
+        else if ( p->is_udp() )
+        {
+            src_port = p->ptrs.udph->src_port();
+            dst_port = p->ptrs.udph->dst_port();
+        }
+        else
+            return dr;
+    }
+
+    return directional_match(when.src_ports, when.dst_ports, src_port, dst_port, dr,
+        [](const PortBitSet& when_val, uint16_t traffic_val)
+        { return when_val.test(traffic_val); });
+}
+
+Binding::DirResult Binding::check_zone(const Packet* p, const Binding::DirResult dr) const
+{
+    if ( !p )
+        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; });
 }
 
-bool Binding::check_all(const Flow* flow) const
+bool Binding::check_all(const Flow* flow, Packet* p) const
 {
+    Binding::DirResult dir = Binding::DR_ANY_MATCH;
+
     if ( !check_ips_policy(flow) )
         return false;
 
-    if ( !check_iface(flow) )
+    if ( !check_iface(p) )
         return false;
 
     if ( !check_vlan(flow) )
@@ -259,7 +331,7 @@ bool Binding::check_all(const Flow* flow) const
     if ( !check_addr(flow) )
         return false;
 
-    auto dir = check_split_addr(flow);
+    dir = check_split_addr(flow, p, dir);
     if ( dir == Binding::DR_NO_MATCH )
         return false;
 
@@ -269,12 +341,17 @@ bool Binding::check_all(const Flow* flow) const
     if ( !check_port(flow) )
         return false;
 
-    if ( !check_split_port(flow, dir) )
+    dir = check_split_port(flow, 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 )
+        return false;
+
     return true;
 }
 
@@ -501,7 +578,7 @@ private:
     void apply(const Stuff&, Flow*);
 
     void set_binding(SnortConfig*, Binding*);
-    void get_bindings(Flow*, Stuff&);
+    void get_bindings(Flow*, Stuff&, Packet* = nullptr); // may be null when dealing with HA flows
     void apply(Flow*, Stuff&);
     Inspector* find_gadget(Flow*);
     int exec_handle_gadget(void*);
@@ -569,12 +646,10 @@ void Binder::update(SnortConfig*, const char* name)
 
 void Binder::eval(Packet* p)
 {
+    Stuff stuff;
     Flow* flow = p->flow;
-    flow->iface_in = p->pkth->ingress_index;
-    flow->iface_out = p->pkth->egress_index;
 
-    Stuff stuff;
-    get_bindings(flow, stuff);
+    get_bindings(flow, stuff, p);
     apply(flow, stuff);
 
     ++bstats.verdicts[stuff.action];
@@ -674,7 +749,7 @@ void Binder::set_binding(SnortConfig*, Binding* pb)
 
 // FIXIT-P this is a simple linear search until functionality is nailed
 // down.  performance should be the focus of the next iteration.
-void Binder::get_bindings(Flow* flow, Stuff& stuff)
+void Binder::get_bindings(Flow* flow, Stuff& stuff, Packet* p)
 {
     Binding* pb;
     unsigned i, sz = bindings.size();
@@ -683,7 +758,7 @@ void Binder::get_bindings(Flow* flow, Stuff& stuff)
     {
         pb = bindings[i];
 
-        if ( !pb->check_all(flow) )
+        if ( !pb->check_all(flow, p) )
             continue;
 
         if ( !pb->use.ips_index && !pb->use.inspection_index )
@@ -723,7 +798,7 @@ void Binder::get_bindings(Flow* flow, Stuff& stuff)
 
         if ( sub )
         {
-            sub->get_bindings(flow, stuff);
+            sub->get_bindings(flow, stuff, p);
             return;
         }
     }
index 69e191038d05cb8a64c0ed2f571fa739d80ab1eb..289ec15aa391cb4c00e3b0103890c1a61a733b6f 100644 (file)
@@ -26,7 +26,7 @@
 #include "sfip/sf_ipvar.h"
 
 class Flow;
-
+struct Packet;
 struct BindWhen
 {
     enum Role
@@ -47,6 +47,9 @@ struct BindWhen
     bool split_ports;
     PortBitSet src_ports;
     PortBitSet dst_ports;
+
+    int32_t src_zone;
+    int32_t dst_zone;
 };
 
 struct BindUse
@@ -72,7 +75,21 @@ struct BindUse
 struct Binding
 {
     enum DirResult
-    { DR_NO_MATCH, DR_ANY_MATCH, DR_CLIENT_SRC, DR_SERVER_SRC };
+    {
+        // Did not match
+        DR_NO_MATCH,
+
+        // Matched but direction could not be determined
+        DR_ANY_MATCH,
+
+        // On flow: src_* matched client, dst_* matched server
+        // On packet: src_* matched p->src_*, dst_* matched p->dst_*
+        DR_FORWARD,
+
+        // On flow: src_* matched server, dst_* matched client
+        // On packet: src_* matched p->dst_*, dst_* matched p->src_*
+        DR_REVERSE,
+    };
 
     BindWhen when;
     BindUse use;
@@ -80,16 +97,17 @@ struct Binding
     Binding();
     ~Binding();
 
-    bool check_all(const Flow*) const;
+    bool check_all(const Flow*, Packet*) const;
     bool check_ips_policy(const Flow*) const;
-    bool check_iface(const Flow*) const;
+    bool check_iface(const Packet*) const;
     bool check_vlan(const Flow*) const;
     bool check_addr(const Flow*) const;
-    DirResult check_split_addr(const Flow*) const;
+    DirResult check_split_addr(const Flow*, const Packet*, const DirResult) const;
     bool check_proto(const Flow*) const;
     bool check_port(const Flow*) const;
-    bool check_split_port(const Flow*, const DirResult) const;
+    DirResult check_split_port(const Flow*, const Packet*, const DirResult) const;
     bool check_service(const Flow*) const;
+    DirResult check_zone(const Packet*, const DirResult) const;
 };
 
 #endif
index 57fb53ac5a2d94c2275b43ef61a8724b4b626116..ccec9be84ee34f07c9cdaa51ccade533711761d2 100644 (file)
@@ -141,7 +141,7 @@ void HttpStreamSplitter::decompress_copy(uint8_t* buffer, uint32_t& offset, cons
 {
     if ((compression == CMP_GZIP) || (compression == CMP_DEFLATE))
     {
-        compress_stream->next_in = const_cast<z_const Bytef*>(data);
+        compress_stream->next_in = (Bytef*)data;
         compress_stream->avail_in = length;
         compress_stream->next_out = buffer + offset;
         compress_stream->avail_out = MAX_OCTETS - offset;
@@ -185,7 +185,7 @@ void HttpStreamSplitter::decompress_copy(uint8_t* buffer, uint32_t& offset, cons
             static constexpr char zlib_header[2] = { 0x78, 0x01 };
 
             inflateReset(compress_stream);
-            compress_stream->next_in = (z_const Bytef*)zlib_header;
+            compress_stream->next_in = (Bytef*)zlib_header;
             compress_stream->avail_in = sizeof(zlib_header);
             inflate(compress_stream, Z_SYNC_FLUSH);
 
index 1d5ed0ca3c1337b2daa263ac1758c07e8201de7a..c24e0fb4b0eaf4bfbb250b7d4d3167f5362a63b9 100644 (file)
@@ -24,7 +24,7 @@
 
 using namespace std;
 
-Binder::Binder(TableApi& t) : table_api(t), printed(false), when_ips_policy_id(-1)
+Binder::Binder(TableApi& t) : table_api(t)
 { }
 
 Binder::~Binder()
@@ -69,6 +69,12 @@ 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));
+
+    if ( has_dst_zone() )
+        table_api.add_option("dst_zone", std::stoi(when_dst_zone));
+
     if ( has_proto() )
         table_api.add_option("proto", when_proto);
 
@@ -122,6 +128,12 @@ void Binder::add_to_configuration()
     table_api.close_table();  // "binder"
 }
 
+void Binder::set_priority(unsigned p)
+{ priority = p; }
+
+unsigned Binder::get_priority()
+{ return priority; }
+
 void Binder::set_when_ips_policy_id(int id)
 { when_ips_policy_id = id; }
 
@@ -155,6 +167,12 @@ void Binder::add_when_dst_port(const std::string& port)
 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; }
+
+void Binder::set_when_dst_zone(const std::string& zone)
+{ when_dst_zone = zone; }
+
 void Binder::clear_ports()
 { ports.clear(); }
 
@@ -212,8 +230,16 @@ bool operator<(const shared_ptr<Binder>& left, const shared_ptr<Binder>& right)
         if ( (left) > (right) ) return true; \
     }
 
-    //By priorities of options
+    // By predetermined order
+    FIRST_IF_LT(left->get_priority(), right->get_priority());
+
+    // By priorities of options
     FIRST_IF_GT(left->has_ips_policy_id(), right->has_ips_policy_id())
+    
+    auto left_zone_specs = left->has_src_zone() + left->has_dst_zone();
+    auto right_zone_specs = right->has_src_zone() + right->has_dst_zone();
+    FIRST_IF_GT(left_zone_specs, right_zone_specs);
+
     FIRST_IF_GT(left->has_vlans(), right->has_vlans())
     FIRST_IF_GT(left->has_service(), right->has_service())
 
@@ -231,7 +257,7 @@ bool operator<(const shared_ptr<Binder>& left, const shared_ptr<Binder>& right)
     FIRST_IF_GT(left->has_proto(), right->has_proto())
     FIRST_IF_GT(left->has_role(), right->has_role())
 
-    //By values of options. Fewer specs = more specific.
+    // By values of options. Fewer specs = more specific.
     if ( left->has_vlans() && right->has_vlans() )
         FIRST_IF_LT(left->vlans.size(), right->vlans.size())
 
@@ -243,7 +269,7 @@ bool operator<(const shared_ptr<Binder>& left, const shared_ptr<Binder>& right)
     if ( left->has_ports() && right->has_ports() )
         FIRST_IF_LT(left->ports.size(), right->ports.size())
 
-    //Sorted by value for readability if all else is equal
+    // Sorted by value for readability if all else is equal
     if ( left->has_ips_policy_id() && right->has_ips_policy_id() )
         FIRST_IF_LT(left->when_ips_policy_id, right->when_ips_policy_id)
 
@@ -265,7 +291,7 @@ bool operator<(const shared_ptr<Binder>& left, const shared_ptr<Binder>& right)
 
 void print_binder_priorities()
 {
-    static unsigned const num_combos = 2 << 10
+    static unsigned const num_combos = 2 << 12
     vector<shared_ptr<Binder>> binders;
     TableApi t;
 
@@ -278,33 +304,39 @@ void print_binder_priorities()
             binders.back()->set_when_ips_policy_id(1);
 
         if ( i & (1 << 1) )
-            binders.back()->add_when_vlan("a");
+            binders.back()->set_when_src_zone("0");
 
         if ( i & (1 << 2) )
-            binders.back()->set_when_service("a");
+            binders.back()->set_when_dst_zone("0");
 
         if ( i & (1 << 3) )
-            binders.back()->add_when_src_net("a");
+            binders.back()->add_when_vlan("a");
 
         if ( i & (1 << 4) )
-            binders.back()->add_when_dst_net("a");
+            binders.back()->set_when_service("a");
 
         if ( i & (1 << 5) )
-            binders.back()->add_when_net("a");
+            binders.back()->add_when_src_net("a");
 
         if ( i & (1 << 6) )
-            binders.back()->add_when_src_port("a");
+            binders.back()->add_when_dst_net("a");
 
         if ( i & (1 << 7) )
-            binders.back()->add_when_dst_port("a");
+            binders.back()->add_when_net("a");
 
         if ( i & (1 << 8) )
-            binders.back()->add_when_port("a");
+            binders.back()->add_when_src_port("a");
 
         if ( i & (1 << 9) )
-            binders.back()->set_when_proto("a");
+            binders.back()->add_when_dst_port("a");
 
         if ( i & (1 << 10) )
+            binders.back()->add_when_port("a");
+
+        if ( i & (1 << 11) )
+            binders.back()->set_when_proto("a");
+
+        if ( i & (1 << 12) )
             binders.back()->set_when_role("a");
     }
 
@@ -318,6 +350,12 @@ void print_binder_priorities()
         if ( b->has_vlans() )
             cout << "vlan ";
 
+        if ( b->has_src_zone() )
+            cout << "src_zone ";
+
+        if ( b->has_dst_zone() )
+            cout << "dst_zone ";
+
         if ( b->has_service() )
             cout << "service ";
 
index f52bacee039554666846f5651e3bc17de763dcb5..bdf4b941c3d219e3edffdc0be1070b198da13921 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef HELPERS_PPS_BINDER_H
 #define HELPERS_PPS_BINDER_H
 
+#include <climits>
 #include <memory>
 #include <string>
 #include <vector>
@@ -50,6 +51,9 @@ public:
     void print_binding(bool should_print)
     { printed = !should_print; }
 
+    void set_priority(unsigned);
+    unsigned get_priority();
+
     void set_when_ips_policy_id(int);
     void set_when_service(const std::string&);
     void set_when_role(const std::string&);
@@ -61,6 +65,8 @@ public:
     void add_when_port(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&);
+    void set_when_dst_zone(const std::string&);
     void clear_ports();
 
     int get_when_ips_policy_id() const
@@ -99,6 +105,12 @@ public:
     bool has_ports() const
     { return !ports.empty(); }
 
+    bool has_src_zone() const
+    { return !when_src_zone.empty(); }
+
+    bool has_dst_zone() const
+    { return !when_dst_zone.empty(); }
+
     void set_use_type(const std::string& module_name);
     void set_use_name(const std::string& struct_name);
     void set_use_file(const std::string& file_name, IncludeType = IT_FILE);
@@ -122,10 +134,12 @@ public:
 
 private:
     TableApi& table_api;
-    bool printed; // ensures that the binding is added once,
-                  // by either the destructor or user
+    bool printed = false; // ensures that the binding is added once,
+                          // by either the destructor or user
 
-    int when_ips_policy_id;
+    unsigned priority = UINT_MAX;
+    
+    int when_ips_policy_id = -1;
     std::string when_service;
     std::string when_role;
     std::string when_proto;
@@ -136,6 +150,8 @@ private:
     std::vector<std::string> ports;
     std::vector<std::string> src_ports;
     std::vector<std::string> dst_ports;
+    std::string when_src_zone;
+    std::string when_dst_zone;
 
     std::string use_type;
     std::string use_name;
index 0c3a72d941f0caef38fdd857767ba9d71389b609..ebfcebcd7f955903545c7d080dd768e2e7508579 100644 (file)
@@ -653,6 +653,11 @@ bool DcerpcServer::convert(std::istringstream& data_stream)
     bind["http_proxy"] = &bind_http_proxy;
     bind["http_server"] = &bind_http_server;
 
+    // FIXIT-N add when there is a way to make this play with http_inspect bindings
+    // port 80 should not be added by default. If explicitly configured and conflicting
+    // with other bindings, punt to wizard
+    bind["http_proxy"]->print_binding(false);
+
     for (const auto& type : transport)
     {
         bind[type]->set_when_proto("tcp");
index af30d74d487780bb9676fd5067ce1d428193e593..f9c935d79226cc5134969dc40717412e9a1870fb 100644 (file)
@@ -58,10 +58,10 @@ public:
             std::string ips_policy;
 
             TRY_FIELD(action);   // ignore since nap rules don't drop
-            TRY_FIELD(src_zone); // FIXIT-M parse zones when implemented
+            TRY_FIELD(src_zone);
             TRY_FIELD(src_net);
             TRY_FIELD(src_port);
-            TRY_FIELD(dst_zone); // FIXIT-M parse zones when implemented
+            TRY_FIELD(dst_zone);
             TRY_FIELD(dst_net);
             TRY_FIELD(dst_port);
             TRY_FIELD(vlan);
@@ -100,12 +100,20 @@ public:
 
             auto& bind = cv.make_pending_binder(policy_id);
 
+            bind.set_priority(order++);
+
+            if ( src_zone != "any" )
+                bind.set_when_src_zone(src_zone);
+
             if ( src_net != "any" )
                 bind.add_when_src_net(src_net);
 
             if ( src_port != "any" )
                 bind.add_when_src_port(src_port);
 
+            if ( dst_zone != "any" )
+                bind.set_when_dst_zone(dst_zone);
+
             if ( dst_net != "any" )
                 bind.add_when_dst_net(dst_net);
 
@@ -135,6 +143,9 @@ public:
 
         return true;
     }
+
+private:
+    unsigned order = 0;
 };
 
 class NapSelectorState : public ConversionState