]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
added wizard and binder inspectors
authorRuss Combs <rucombs@cisco.com>
Fri, 27 Jun 2014 03:37:12 +0000 (23:37 -0400)
committerRuss Combs <rucombs@cisco.com>
Fri, 27 Jun 2014 03:37:12 +0000 (23:37 -0400)
30 files changed:
ChangeLog
configure.ac
src/Makefile.am
src/flow/flow_control.cc
src/flow/flow_control.h
src/framework/inspector.h
src/main/CMakeLists.txt
src/main/Makefile.am
src/main/modules.cc
src/main/snort.cc
src/managers/inspector_manager.cc
src/managers/inspector_manager.h
src/managers/module_manager.cc
src/network_inspectors/Makefile.am
src/network_inspectors/binder/Makefile.am [new file with mode: 0644]
src/network_inspectors/binder/bind_module.cc [new file with mode: 0644]
src/network_inspectors/binder/bind_module.h [new file with mode: 0644]
src/network_inspectors/binder/binder.cc [moved from src/main/binder.cc with 54% similarity]
src/network_inspectors/binder/binder.h [moved from src/main/binder.h with 88% similarity]
src/network_inspectors/network_inspectors.cc
src/service_inspectors/Makefile.am
src/service_inspectors/service_inspectors.cc
src/service_inspectors/wizard/Makefile.am [new file with mode: 0644]
src/service_inspectors/wizard/wiz_module.cc [new file with mode: 0644]
src/service_inspectors/wizard/wiz_module.h [new file with mode: 0644]
src/service_inspectors/wizard/wizard.cc [new file with mode: 0644]
src/service_inspectors/wizard/wizard.h [new file with mode: 0644]
src/stream/base/stream_base.cc
src/stream/stream_splitter.h
src/time/profiler.h

index 1fa8a89e8560ec3c2560a991117fc32411f305fd..3aeb753f0a71eea75da8ac47e99c7ecc4cc5513d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,9 @@
 93
 -- updated example inspector dpx.cc api
 -- misc tweaks
+-- changed binder to inspector with designated type
+-- added prototype wizard inspector for service selection magic
+-- fixed plugin instantiation when top level table is a list
 
 92
 -- fixed fast_pattern only auto configuration
index f43ab089479c7ab9a78191ba78fbd3436006bae7..816f97164d23ef9e10d154ed6812ed2456660e08 100644 (file)
@@ -842,6 +842,7 @@ src/stream/tcp/Makefile \
 src/stream/udp/Makefile \
 src/network_inspectors/Makefile \
 src/network_inspectors/arp_spoof/Makefile \
+src/network_inspectors/binder/Makefile \
 src/network_inspectors/normalize/Makefile \
 src/network_inspectors/perf_monitor/Makefile \
 src/network_inspectors/port_scan/Makefile \
@@ -853,6 +854,7 @@ src/service_inspectors/ftp_telnet/Makefile \
 src/service_inspectors/http_inspect/Makefile \
 src/service_inspectors/nhttp_inspect/Makefile \
 src/service_inspectors/rpc_decode/Makefile \
+src/service_inspectors/wizard/Makefile \
 src/protocols/Makefile \
 src/search_engines/Makefile \
 src/sfip/Makefile \
index b27e7cff079e6f6fc5e3d0a5d15f59b1a924f117..e9ad6f03835180b880eedf09746812224ac584b6 100644 (file)
@@ -9,11 +9,13 @@ main.h
 if STATIC_INSPECTORS
 lib_list = \
 network_inspectors/arp_spoof/libarp_spoof.a \
+network_inspectors/binder/libbinder.a \
 network_inspectors/port_scan/libport_scan.a \
 service_inspectors/back_orifice/libback_orifice.a \
 service_inspectors/ftp_telnet/libftp_telnet.a \
+service_inspectors/nhttp_inspect/libnhttp_inspect.a \
 service_inspectors/rpc_decode/librpc_decode.a \
-service_inspectors/nhttp_inspect/libnhttp_inspect.a
+service_inspectors/wizard/libwizard.a
 endif
 
 # order libs to avoid undefined symbols
index 621eeb3a7301c297583f694c11aa1552aa8089f0..56f228ff89f909fe3f7b12d083160c37cdce58f7 100644 (file)
 #include "flow/session.h"
 #include "packet_io/active.h"
 #include "packet_io/sfdaq.h"
-#include "main/binder.h"
 #include "utils/stats.h"
 #include "protocols/layer.h"
 #include "protocols/vlan.h"
+#include "managers/inspector_manager.h"
 
-FlowControl::FlowControl()
+FlowControl::FlowControl(Inspector* pi)
 {
     ip_cache = nullptr;
     icmp_cache = nullptr;
     tcp_cache = nullptr;
     udp_cache = nullptr;
     exp_cache = nullptr;
+    binder = pi;
 }
 
 FlowControl::~FlowControl()
@@ -264,9 +265,11 @@ unsigned FlowControl::process(FlowCache* cache, Packet* p)
     if ( !flow )
         return 0;
 
+    p->flow = flow;
+
     if ( !flow->ssn_client )
     {
-        Binder::init_flow(flow);
+        binder->eval(p);
 
         if ( !flow->session->setup(p) )
             return 0;
@@ -274,11 +277,10 @@ unsigned FlowControl::process(FlowCache* cache, Packet* p)
         news = 1;
     }
 
-    p->flow = flow;
     flow->session->process(p);
 
     if ( news )
-        Binder::init_flow(flow, p);
+        binder->eval(p);
 
     if ( flow->next && is_bidirectional(flow) )
         cache->unlink_uni(flow);
index e213936c6bf1f2dd31187f7a97e75b405288e678..9a444b4e39d0e458560ae3ebaf37d62cc6e232e4 100644 (file)
@@ -37,7 +37,7 @@ struct FlowConfig
 class FlowControl
 {
 public:
-    FlowControl();
+    FlowControl(class Inspector*);
     ~FlowControl();
 
 public:
@@ -94,7 +94,9 @@ private:
     FlowCache* udp_cache;
     FlowCache* icmp_cache;
     FlowCache* ip_cache;
+
     class ExpectCache* exp_cache;
+    class Inspector* binder;
 };
 
 #endif
index 98ea49e1072ca9028eccb7e98a1f0b08799abc9d..eaa734a928c301f8b4d8a4da79e7e38c3ea00eca 100644 (file)
@@ -100,6 +100,9 @@ public:
     void set_api(const InspectApi* p)
     { api = p; };
 
+    const InspectApi* get_api()
+    { return api; };
+
 public:
     static unsigned max_slots;
     static THREAD_LOCAL unsigned slot;
@@ -116,6 +119,8 @@ private:
 
 enum InspectorType
 {
+    IT_BINDER,
+    IT_WIZARD,
     IT_PACKET,
     IT_PROTOCOL,
     IT_STREAM,
index e0fcca3010563704a5b8313d788644e468829c76..1b94369420b3589d5b212944976a0eb3b87160a2 100644 (file)
@@ -8,8 +8,6 @@ set (INCLUDES
 add_library (main STATIC
     analyzer.h
     analyzer.cc 
-    binder.cc
-    binder.h
     build.h
     modules.cc
     modules.h
index cda8f3d41c5a3d790f89e722900fcf125c22c7c5..270bff5ae7b9927144e650e5b0f5f10cd3413dab 100644 (file)
@@ -12,8 +12,6 @@ thread.h
 libmain_a_SOURCES = \
 analyzer.cc \
 analyzer.h \
-binder.cc \
-binder.h \
 build.h \
 modules.cc \
 modules.h \
index a915d7c5700c71e61cff70a3dc66e0d23d485ff9..cc9f33efbd6e93063067563651e6fdd6ae4e87da 100644 (file)
@@ -33,11 +33,9 @@ using namespace std;
 
 #include "framework/module.h"
 #include "managers/module_manager.h"
-#include "main/binder.h"
 #include "main.h"
 #include "snort.h"
 #include "snort_config.h"
-#include "binder.h"
 #include "parser/parser.h"
 #include "parser/parse_conf.h"
 #include "parser/config_file.h"
@@ -1636,150 +1634,6 @@ public:
     bool set(const char*, Value&, SnortConfig*) { return false; };
 };
 
-//-------------------------------------------------------------------------
-// binder module
-//-------------------------------------------------------------------------
-
-static const Parameter binder_when_params[] =
-{
-    { "policy_id", Parameter::PT_STRING, nullptr, nullptr,
-      "unique ID for selection of this config by external logic" },
-
-    { "vlans", Parameter::PT_BIT_LIST, "4095", nullptr,
-      "list of VLAN IDs" },
-
-    { "nets", Parameter::PT_ADDR_LIST, nullptr, nullptr,
-      "list of networks" },
-
-    { "proto", Parameter::PT_ENUM, "any | ip | icmp | tcp | udp", nullptr,
-      "protocol" },
-
-    { "ports", Parameter::PT_BIT_LIST, "65535", nullptr,
-      "list of ports" },
-
-    { "role", Parameter::PT_ENUM, "client | server | any", "any",
-      "use the given configuration on one or any end of a session" },
-
-    { "service", Parameter::PT_STRING, nullptr, nullptr,
-      "override default configuration" },
-
-    { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
-};
-
-static const Parameter binder_use_params[] =
-{
-    { "action", Parameter::PT_ENUM, "inspect | allow | block", "inspect",
-      "what to do with matching traffic" },
-
-    { "file", Parameter::PT_STRING, nullptr, nullptr,
-      "use configuration in given file" },
-
-    { "policy_id", Parameter::PT_STRING, nullptr, nullptr,
-      "use configuration in given policy" },
-
-    { "service", Parameter::PT_STRING, nullptr, nullptr,
-      "override automatic service identification" },
-
-    { "type", Parameter::PT_STRING, nullptr, nullptr,
-      "select module for binding" },
-
-    { "name", Parameter::PT_STRING, nullptr, "defaults to type",
-      "symbol name" },
-
-    { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
-};
-
-static const Parameter binder_params[] =
-{
-    { "when", Parameter::PT_TABLE, binder_when_params, nullptr,
-      "match criteria" },
-
-    { "use", Parameter::PT_TABLE, binder_use_params, nullptr,
-      "target configuration" },
-
-    { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
-};
-
-class BinderModule : public Module
-{
-public:
-    BinderModule() : Module("binder", binder_params) { work = nullptr; };
-    bool set(const char*, Value&, SnortConfig*);
-    bool begin(const char*, int, SnortConfig*);
-    bool end(const char*, int, SnortConfig*);
-
-private:
-    Binding* work;
-};
-
-bool BinderModule::set(const char* fqn, Value& v, SnortConfig*)
-{
-    // both
-    if ( !strcmp(fqn, "binder.when.policy_id") )
-        work->when_id = v.get_string();
-
-    else if ( !strcmp(fqn, "binder.use.policy_id") )
-        work->use_id = v.get_string();
-
-    else if ( !strcmp(fqn, "binder.when.service") )
-        work->when_svc = v.get_string();
-
-    else if ( !strcmp(fqn, "binder.use.service") )
-        work->use_svc = v.get_string();
-
-    // when
-    else if ( v.is("nets") )
-        work->nets = v.get_string();
-
-    else if ( v.is("proto") )
-        work->proto = (BindProto)v.get_long();
-
-    else if ( v.is("ports") )
-        v.get_bits(work->ports);
-
-    else if ( v.is("role") )
-        work->role = (BindRole)v.get_long();
-
-    else if ( v.is("vlans") )
-        v.get_bits(work->vlans);
-
-    // use
-    else if ( v.is("action") )
-        work->action = (BindAction)v.get_long();
-
-    else if ( v.is("file") )
-        work->file = v.get_string();
-
-    else if ( v.is("name") )
-        work->name = v.get_string();
-
-    else if ( v.is("type") )
-        work->type = v.get_string();
-
-    else
-        return false;
-
-    return true;
-}
-
-bool BinderModule::begin(const char* fqn, int idx, SnortConfig*)
-{
-    if ( idx && !strcmp(fqn, "binder") )
-        work = new Binding;
-
-    return true;
-}
-
-bool BinderModule::end(const char* fqn, int idx, SnortConfig*)
-{
-    if ( idx && !strcmp(fqn, "binder") )
-    {
-        Binder::add(work);
-        work = nullptr;
-    }
-    return true;
-}
-
 //-------------------------------------------------------------------------
 // hosts module
 //-------------------------------------------------------------------------
@@ -2008,8 +1862,5 @@ void module_init()
     // these modules replace config and hosts.xml
     ModuleManager::add_module(new AttributeTableModule);
     ModuleManager::add_module(new HostsModule);
-
-    // and this one ties it all together
-    ModuleManager::add_module(new BinderModule);
 }
 
index 696ccb67ee226844ec137208c9e8d2404d67574f..9f2705d6c201715665070a81d8001a25900f6a01 100644 (file)
@@ -99,7 +99,6 @@ using namespace std;
 #include "file_api/file_service.h"
 #include "flow/flow_control.h"
 #include "main/analyzer.h"
-#include "main/binder.h"
 #include "log/sf_textlog.h"
 #include "log/log_text.h"
 #include "time/periodic.h"
@@ -390,7 +389,6 @@ static void SnortInit(int argc, char **argv)
 
     /* Need to do this after dynamic detection stuff is initialized, too */
     IpsManager::verify();
-    Binder::init();
 
     if (snort_conf->file_mask != 0)
         umask(snort_conf->file_mask);
index a64577f4876fe41b54ccef0843714c16fe8ab66f..0be293e255480930551c73a658d8c098506ff707 100644 (file)
@@ -26,7 +26,6 @@
 #include <mutex>
 
 #include "module_manager.h"
-#include "main/binder.h"
 #include "flow/flow.h"
 #include "framework/inspector.h"
 #include "detection/detection_util.h"
@@ -141,20 +140,31 @@ struct FrameworkPolicy
 
         for ( auto* p : ph_list )
         {
-            if ( p->pp_class.api.ssn )
-                continue;
-
-            else if ( p->pp_class.api.type == IT_STREAM )
-                session.add(p);
+            switch ( p->pp_class.api.type )
+            {
+            case IT_STREAM:
+                if ( !p->pp_class.api.ssn )
+                    session.add(p);
+                break;
 
-            else if ( p->pp_class.api.type < IT_STREAM )
+            case IT_PACKET:
+            case IT_PROTOCOL:
                 network.add(p);
+                break;
 
-            else if ( p->pp_class.api.type < IT_SERVICE )
+            case IT_SESSION:
                 generic.add(p);
+                break;
 
-            else
+            case IT_SERVICE:
                 service.add(p);
+                break;
+
+            case IT_BINDER:
+            case IT_WIZARD:
+            case IT_MAX:
+                break;
+            }
         }
     };
 };
@@ -210,6 +220,7 @@ void InspectorManager::release_plugins ()
     {
         if ( !p->init && p->api.term )
             p->api.term();
+
         delete p;
     }
 }
@@ -223,15 +234,7 @@ void InspectorManager::empty_trash()
         if ( !p->is_inactive() )
             return;
 
-#if 0
-        // FIXIT add name to Inspector to enable proper call to dtor
-        InspectApi* api = (InspectApi*)get_api(PT_INSPECTOR, p->get_name());
-
-        if ( api )
-            api->dtor(p);
-#else
-        delete p;
-#endif
+        free_inspector(p);
         s_trash.pop_front();
     }
 }
@@ -310,6 +313,11 @@ Inspector* InspectorManager::get_inspector(const char* key)
     return p->handler;
 } 
 
+void InspectorManager::free_inspector(Inspector* p)
+{
+    p->get_api()->dtor(p);
+}
+
 InspectSsnFunc InspectorManager::get_session(const char* key)
 {
     const InspectApi* api = get_plugin(key);
index 8be2fd251914fff87da3ebd82947e9e25d73b886..9f1ff4939521417941cdb41b4d81263ed8f60466 100644 (file)
@@ -52,6 +52,7 @@ public:
 
     static void instantiate(const InspectApi*, Module*, SnortConfig*);
     static Inspector* get_inspector(const char* key);
+    static void free_inspector(Inspector*);
     static InspectSsnFunc get_session(const char* key);
 
     static bool configure(SnortConfig*);
index 379dbc2f6ad039e0cd72c45cc49c23cf4e014e7e..28cf98a02010444884be221b639096450d300097 100644 (file)
@@ -387,7 +387,7 @@ void close_table(const char* s, int idx)
     {
         h->mod->end(s, idx, s_config);
 
-        if ( h->api && (key == s) )
+        if ( !idx && h->api && (key == s) )
             PluginManager::instantiate(h->api, h->mod, s_config);
     }
 }
index 5b52e80008b976a4e70be1d9cd11c005a43a1ffb..6df016ab3939cc162b6a96d6824f138b9059cd5f 100644 (file)
@@ -10,12 +10,14 @@ network_inspectors.h
 # FIXIT LIBADD here causes undefineds
 #libnetwork_inspectors_a_LIBADD = \
 #arp_spoof/libarp_spoof.a \
+#binder/libbinder.a \
 #normalize/libnormalize.a \
 #perf_monitor/libperf_monitor.a \
 #port_scan/libport_scan.a
 
 SUBDIRS = \
 arp_spoof \
+binder \
 normalize \
 perf_monitor \
 port_scan
diff --git a/src/network_inspectors/binder/Makefile.am b/src/network_inspectors/binder/Makefile.am
new file mode 100644 (file)
index 0000000..ee67ee1
--- /dev/null
@@ -0,0 +1,20 @@
+AUTOMAKE_OPTIONS=foreign no-dependencies
+
+file_list = \
+binder.cc binder.h \
+bind_module.cc bind_module.h
+
+#if STATIC_INSPECTORS
+noinst_LIBRARIES = libbinder.a
+libbinder_a_SOURCES = $(file_list)
+#else
+# need to fix undefineds first :(
+#shlibdir = $(pkglibdir)/inspectors
+#shlib_LTLIBRARIES = libbinder.la
+#libbinder_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
+#libbinder_la_LDFLAGS = -export-dynamic -shared
+#libbinder_la_SOURCES = $(file_list)
+#endif
+
+AM_CXXFLAGS = @AM_CXXFLAGS@
+
diff --git a/src/network_inspectors/binder/bind_module.cc b/src/network_inspectors/binder/bind_module.cc
new file mode 100644 (file)
index 0000000..8e71243
--- /dev/null
@@ -0,0 +1,177 @@
+/*
+** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License Version 2 as
+** published by the Free Software Foundation.  You may not use, modify or
+** distribute this program under any other version of the GNU General
+** Public License.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+// bind_module.cc author Russ Combs <rucombs@cisco.com>
+
+#include "bind_module.h"
+
+#include <assert.h>
+#include <string.h>
+
+#include <string>
+using namespace std;
+
+#include "binder.h"
+
+//-------------------------------------------------------------------------
+// binder module
+//-------------------------------------------------------------------------
+
+static const Parameter binder_when_params[] =
+{
+    { "policy_id", Parameter::PT_STRING, nullptr, nullptr,
+      "unique ID for selection of this config by external logic" },
+
+    { "vlans", Parameter::PT_BIT_LIST, "4095", nullptr,
+      "list of VLAN IDs" },
+
+    { "nets", Parameter::PT_ADDR_LIST, nullptr, nullptr,
+      "list of networks" },
+
+    { "proto", Parameter::PT_ENUM, "any | ip | icmp | tcp | udp", nullptr,
+      "protocol" },
+
+    { "ports", Parameter::PT_BIT_LIST, "65535", nullptr,
+      "list of ports" },
+
+    { "role", Parameter::PT_ENUM, "client | server | any", "any",
+      "use the given configuration on one or any end of a session" },
+
+    { "service", Parameter::PT_STRING, nullptr, nullptr,
+      "override default configuration" },
+
+    { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
+};
+
+static const Parameter binder_use_params[] =
+{
+    { "action", Parameter::PT_ENUM, "inspect | allow | block", "inspect",
+      "what to do with matching traffic" },
+
+    { "file", Parameter::PT_STRING, nullptr, nullptr,
+      "use configuration in given file" },
+
+    { "policy_id", Parameter::PT_STRING, nullptr, nullptr,
+      "use configuration in given policy" },
+
+    { "service", Parameter::PT_STRING, nullptr, nullptr,
+      "override automatic service identification" },
+
+    { "type", Parameter::PT_STRING, nullptr, nullptr,
+      "select module for binding" },
+
+    { "name", Parameter::PT_STRING, nullptr, "defaults to type",
+      "symbol name" },
+
+    { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
+};
+
+static const Parameter binder_params[] =
+{
+    { "when", Parameter::PT_TABLE, binder_when_params, nullptr,
+      "match criteria" },
+
+    { "use", Parameter::PT_TABLE, binder_use_params, nullptr,
+      "target configuration" },
+
+    { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
+};
+
+BinderModule::BinderModule() : Module("binder", binder_params)
+{ work = nullptr; }
+
+BinderModule::~BinderModule()
+{
+    if ( work )
+        delete work;
+}
+
+bool BinderModule::set(const char* fqn, Value& v, SnortConfig*)
+{
+    // both
+    if ( !strcmp(fqn, "binder.when.policy_id") )
+        work->when_id = v.get_string();
+
+    else if ( !strcmp(fqn, "binder.use.policy_id") )
+        work->use_id = v.get_string();
+
+    else if ( !strcmp(fqn, "binder.when.service") )
+        work->when_svc = v.get_string();
+
+    else if ( !strcmp(fqn, "binder.use.service") )
+        work->use_svc = v.get_string();
+
+    // when
+    else if ( v.is("nets") )
+        work->nets = v.get_string();
+
+    else if ( v.is("proto") )
+        work->proto = (BindProto)v.get_long();
+
+    else if ( v.is("ports") )
+        v.get_bits(work->ports);
+
+    else if ( v.is("role") )
+        work->role = (BindRole)v.get_long();
+
+    else if ( v.is("vlans") )
+        v.get_bits(work->vlans);
+
+    // use
+    else if ( v.is("action") )
+        work->action = (BindAction)v.get_long();
+
+    else if ( v.is("file") )
+        work->file = v.get_string();
+
+    else if ( v.is("name") )
+        work->name = v.get_string();
+
+    else if ( v.is("type") )
+        work->type = v.get_string();
+
+    else
+        return false;
+
+    return true;
+}
+
+bool BinderModule::begin(const char* fqn, int idx, SnortConfig*)
+{
+    if ( idx && !strcmp(fqn, "binder") )
+        work = new Binding;
+
+    return true;
+}
+
+bool BinderModule::end(const char* fqn, int idx, SnortConfig*)
+{
+    if ( idx && !strcmp(fqn, "binder") )
+    {
+        bindings.push_back(work);
+        work = nullptr;
+    }
+    return true;
+}
+
+vector<Binding*> BinderModule::get_data()
+{
+    return bindings;  // move semantics
+}
+
diff --git a/src/network_inspectors/binder/bind_module.h b/src/network_inspectors/binder/bind_module.h
new file mode 100644 (file)
index 0000000..bd4e8ce
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License Version 2 as
+** published by the Free Software Foundation.  You may not use, modify or
+** distribute this program under any other version of the GNU General
+** Public License.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+// bind_module.cc author Russ Combs <rucombs@cisco.com>
+
+#ifndef BIND_MODULE_H
+#define BIND_MODULE_H
+
+#include <vector>
+
+#include "framework/module.h"
+
+struct Binding;
+
+class BinderModule : public Module
+{
+public:
+    BinderModule();
+    ~BinderModule();
+
+    bool set(const char*, Value&, SnortConfig*);
+    bool begin(const char*, int, SnortConfig*);
+    bool end(const char*, int, SnortConfig*);
+
+    std::vector<Binding*> get_data();
+private:
+    Binding* work;
+    std::vector<Binding*> bindings;
+};
+
+#endif
+
similarity index 54%
rename from src/main/binder.cc
rename to src/network_inspectors/binder/binder.cc
index c896609d358ac2a02d96bdecc32b3fed77d487e9..92be6ed743084b50669413d9935bee3df09ce0ab 100644 (file)
 // binder.cc author Russ Combs <rucombs@cisco.com>
 
 #include "binder.h"
-using namespace std;
 
 #include <vector>
+using namespace std;
+
+#include "bind_module.h"
 #include "flow/flow.h"
 #include "framework/inspector.h"
 #include "stream/stream_splitter.h"
 #include "managers/inspector_manager.h"
 #include "protocols/packet.h"
 #include "stream/stream_api.h"
+#include "time/profiler.h"
+#include "utils/stats.h"
+#include "log/messages.h"
 
-static vector<Binding*> bindings;
+static const char* mod_name = "binder";
 
-void Binder::init()
-{
-}
+#ifdef PERF_PROFILING
+static THREAD_LOCAL PreprocStats bindPerfStats;
 
-void Binder::term()
+static PreprocStats* bind_get_profile(const char* key)
 {
-    for ( auto* p : bindings )
-        delete p;
-}
+    if ( !strcmp(key, mod_name) )
+        return &bindPerfStats;
 
-void Binder::add(Binding* b)
-{
-    bindings.push_back(b);
+    return nullptr;
 }
+#endif
+
+static THREAD_LOCAL SimpleStats tstats;
+static SimpleStats gstats;
+
+//-------------------------------------------------------------------------
+// helpers
+//-------------------------------------------------------------------------
 
 // FIXIT bind this is a temporary hack. note that both ends must be set
 // independently and that we must ref count inspectors.
@@ -77,10 +86,61 @@ static bool check_proto(const Flow* flow, BindProto bp)
     return false;
 }
 
+//-------------------------------------------------------------------------
+// class stuff
+//-------------------------------------------------------------------------
+
+class Binder : public Inspector {
+public:
+    Binder(vector<Binding*>);
+    ~Binder();
+
+    void show(SnortConfig*)
+    { LogMessage("Binder\n"); };
+
+    void eval(Packet*);
+
+    void add(Binding* b)
+    { bindings.push_back(b); };
+
+private:
+    Inspector* get_clouseau(Flow*, Packet*);
+
+    void init_flow(Flow*);
+    void init_flow(Flow*, Packet*);
+
+private:
+    vector<Binding*> bindings;
+};
+
+Binder::Binder(vector<Binding*> v)
+{
+    bindings = v;
+}
+
+Binder::~Binder()
+{
+    for ( auto* p : bindings )
+        delete p;
+}
+
+void Binder::eval(Packet* p)
+{
+    Flow* flow = p->flow;
+
+    if ( !flow->ssn_client )
+        init_flow(p->flow);
+
+    else if ( !flow->clouseau )
+        init_flow(p->flow, p);
+
+    ++tstats.total_packets;
+}
+
 // FIXIT bind services - this is a temporary hack that just looks at ports,
 // need to examine all key fields for matching.  ultimately need a routing
 // table, scapegoat tree, magic wand, etc.
-static Inspector* get_clouseau(Flow* flow, Packet* p)
+Inspector* Binder::get_clouseau(Flow* flow, Packet* p)
 {
     Binding* pb;
     unsigned i, sz = bindings.size();
@@ -97,10 +157,14 @@ static Inspector* get_clouseau(Flow* flow, Packet* p)
         if ( pb->ports.test(port) )
             break;
     }
+    Inspector* ins;
+
     if ( i == sz || !pb->type.size() )
-        return nullptr;
+        ins = InspectorManager::get_inspector("wizard");
+        
+    else
+        ins = InspectorManager::get_inspector(pb->type.c_str());
 
-    Inspector* ins = InspectorManager::get_inspector(pb->type.c_str());
     return ins;
 }
 
@@ -150,3 +214,84 @@ void Binder::init_flow(Flow* flow, Packet* p)
     flow->set_clouseau(ins);
 }
 
+//-------------------------------------------------------------------------
+// api stuff
+//-------------------------------------------------------------------------
+
+static Module* mod_ctor()
+{ return new BinderModule; }
+
+static void mod_dtor(Module* m)
+{ delete m; }
+
+void bind_init()
+{
+#ifdef PERF_PROFILING
+    RegisterPreprocessorProfile(
+        mod_name, &bindPerfStats, 0, &totalPerfStats, bind_get_profile);
+#endif
+}
+
+static Inspector* bind_ctor(Module* m)
+{
+    BinderModule* mod = (BinderModule*)m;
+    vector<Binding*> pb = mod->get_data();
+    return new Binder(pb);
+}
+
+static void bind_dtor(Inspector* p)
+{
+    delete p;
+}
+
+static void bind_sum()
+{
+    sum_stats(&gstats, &tstats);
+}
+
+static void bind_stats()
+{
+    show_stats(&gstats, mod_name);
+}
+
+static void bind_reset()
+{
+    memset(&gstats, 0, sizeof(gstats));
+}
+
+static const InspectApi bind_api =
+{
+    {
+        PT_INSPECTOR,
+        mod_name,
+        INSAPI_PLUGIN_V0,
+        0,
+        mod_ctor,
+        mod_dtor
+    },
+    IT_BINDER, 
+    PROTO_BIT__ALL,
+    nullptr, // buffers
+    nullptr, // service
+    bind_init,
+    nullptr, // term
+    bind_ctor,
+    bind_dtor,
+    nullptr, // pinit
+    nullptr, // pterm
+    nullptr, // ssn
+    bind_sum,
+    bind_stats,
+    bind_reset
+};
+
+#ifdef BUILDING_SO
+SO_PUBLIC const BaseApi* snort_plugins[] =
+{
+    &bind_api.base,
+    nullptr
+};
+#else
+const BaseApi* nin_binder = &bind_api.base;
+#endif
+
similarity index 88%
rename from src/main/binder.h
rename to src/network_inspectors/binder/binder.h
index a46bab7e20ef134357951d6f568699c7611d8e4a..d76dc860c8155118b75b1b136d06387ee207fe71 100644 (file)
@@ -71,15 +71,5 @@ struct Binding
     { role = BR_EITHER; action = BA_INSPECT; };
 };
 
-class Binder
-{
-public:
-    static void init();
-    static void term();
-    static void add(Binding*);
-    static void init_flow(class Flow*);
-    static void init_flow(class Flow*, struct Packet*);
-};
-
 #endif
 
index 9462ed572974b4bb7664ddd7bf3bb02a282ae453..7c161154126df212719333594830d0f7f98ce6de 100644 (file)
@@ -25,6 +25,7 @@
 #endif
 #include "framework/inspector.h"
 
+extern const BaseApi* nin_binder;
 extern const BaseApi* nin_normalize;
 extern const BaseApi* nin_perf_monitor;
 extern const BaseApi* nin_stream_ip;
@@ -40,6 +41,7 @@ extern const BaseApi* nin_port_scan;
 
 const BaseApi* network_inspectors[] =
 {
+    nin_binder,
     nin_normalize,
     nin_perf_monitor,
     nin_stream_ip,
index b5ad88cf074c28be7ce0d302bb8c373e822dfbb1..1c104829164b7c03b22ee785ae2e88b15a76ad82 100644 (file)
@@ -12,14 +12,17 @@ service_inspectors.h
 #back_orifice/libback_orifice.a \
 #ftp_telnet/libftp_telnet.a \
 #http_inspect/libhttp_inspect.a \
+#nhttp_inspect/libnhttp_inspect.a \
 #rpc_decode/librpc_decode.a
+#wizard/libwizard.a
 
 SUBDIRS = \
 back_orifice \
 ftp_telnet \
 http_inspect \
 nhttp_inspect \
-rpc_decode
+rpc_decode \
+wizard
 
 AM_CXXFLAGS = @AM_CXXFLAGS@
 
index 2b67d9891f5b6361a1f1e724efed508268596dd9..d9d106da89573b3d92d81c6cbc2e92227ecc7d62 100644 (file)
@@ -32,9 +32,10 @@ extern const BaseApi* sin_http_server;
 extern const BaseApi* sin_bo;
 extern const BaseApi* sin_ftp_client;
 extern const BaseApi* sin_ftp_server;
+extern const BaseApi* sin_nhttp;
 extern const BaseApi* sin_rpc_decode;
 extern const BaseApi* sin_telnet;
-extern const BaseApi* sin_nhttp;
+extern const BaseApi* sin_wizard;
 #endif
 
 const BaseApi* service_inspectors[] =
@@ -46,9 +47,10 @@ const BaseApi* service_inspectors[] =
     sin_bo,
     sin_ftp_client,
     sin_ftp_server,
+    sin_nhttp,
     sin_rpc_decode,
     sin_telnet,
-    sin_nhttp,
+    sin_wizard,
 #endif
     nullptr,
 };
diff --git a/src/service_inspectors/wizard/Makefile.am b/src/service_inspectors/wizard/Makefile.am
new file mode 100644 (file)
index 0000000..529ea7f
--- /dev/null
@@ -0,0 +1,20 @@
+AUTOMAKE_OPTIONS=foreign no-dependencies
+
+file_list = \
+wizard.cc wizard.h \
+wiz_module.cc wiz_module.h
+
+#if STATIC_INSPECTORS
+noinst_LIBRARIES = libwizard.a
+libwizard_a_SOURCES = $(file_list)
+#else
+# need to fix undefineds first :(
+#shlibdir = $(pkglibdir)/inspectors
+#shlib_LTLIBRARIES = libwizard.la
+#libwizard_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
+#libwizard_la_LDFLAGS = -export-dynamic -shared
+#libwizard_la_SOURCES = $(file_list)
+#endif
+
+AM_CXXFLAGS = @AM_CXXFLAGS@
+
diff --git a/src/service_inspectors/wizard/wiz_module.cc b/src/service_inspectors/wizard/wiz_module.cc
new file mode 100644 (file)
index 0000000..e4e34ce
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License Version 2 as
+** published by the Free Software Foundation.  You may not use, modify or
+** distribute this program under any other version of the GNU General
+** Public License.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+// wiz_module.cc author Russ Combs <rucombs@cisco.com>
+
+#include "wiz_module.h"
+
+#include <assert.h>
+#include <string.h>
+
+#include <string>
+using namespace std;
+
+#include "wizard.h"
+
+static const char* s_name = "wizard";
+
+//-------------------------------------------------------------------------
+// wizard module
+//-------------------------------------------------------------------------
+
+static const Parameter wizard_params[] =
+{
+    { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
+};
+
+WizardModule::WizardModule() : Module(s_name, wizard_params)
+{ }
+
+WizardModule::~WizardModule()
+{ }
+
+bool WizardModule::set(const char*, Value&, SnortConfig*)
+{
+    //if ( v.is("type") )
+    //    work->type = v.get_string();
+
+    //else
+    //    return false;
+
+    return true;
+}
+
+bool WizardModule::begin(const char*, int, SnortConfig*)
+{
+    return true;
+}
+
+bool WizardModule::end(const char*, int, SnortConfig*)
+{
+    return true;
+}
+
diff --git a/src/service_inspectors/wizard/wiz_module.h b/src/service_inspectors/wizard/wiz_module.h
new file mode 100644 (file)
index 0000000..4eb52bd
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License Version 2 as
+** published by the Free Software Foundation.  You may not use, modify or
+** distribute this program under any other version of the GNU General
+** Public License.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+// wiz_module.cc author Russ Combs <rucombs@cisco.com>
+
+#ifndef WIZ_MODULE_H
+#define WIZ_MODULE_H
+
+#include "framework/module.h"
+
+class WizardModule : public Module
+{
+public:
+    WizardModule();
+    ~WizardModule();
+
+    bool set(const char*, Value&, SnortConfig*);
+    bool begin(const char*, int, SnortConfig*);
+    bool end(const char*, int, SnortConfig*);
+
+private:
+};
+
+#endif
+
diff --git a/src/service_inspectors/wizard/wizard.cc b/src/service_inspectors/wizard/wizard.cc
new file mode 100644 (file)
index 0000000..2ad6708
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License Version 2 as
+** published by the Free Software Foundation.  You may not use, modify or
+** distribute this program under any other version of the GNU General
+** Public License.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+// wizard.cc author Russ Combs <rucombs@cisco.com>
+
+#include "wizard.h"
+
+#include <vector>
+using namespace std;
+
+#include "wiz_module.h"
+#include "flow/flow.h"
+#include "framework/inspector.h"
+#include "stream/stream_splitter.h"
+#include "managers/inspector_manager.h"
+#include "protocols/packet.h"
+#include "stream/stream_api.h"
+#include "stream/stream_splitter.h"
+#include "time/profiler.h"
+#include "utils/stats.h"
+#include "log/messages.h"
+
+static const char* mod_name = "wizard";
+
+#ifdef PERF_PROFILING
+static THREAD_LOCAL PreprocStats wizPerfStats;
+
+static PreprocStats* wiz_get_profile(const char* key)
+{
+    if ( !strcmp(key, mod_name) )
+        return &wizPerfStats;
+
+    return nullptr;
+}
+#endif
+
+static THREAD_LOCAL SimpleStats tstats;
+static SimpleStats gstats;
+
+//-------------------------------------------------------------------------
+// splitter - this doesn't actually split the stream but it applies 
+// basic magic type logic to determine the appropriate inspector that
+// will split the stream.
+//-------------------------------------------------------------------------
+
+class MagicSplitter : public StreamSplitter
+{
+public:
+    MagicSplitter(bool c2s) : StreamSplitter(c2s) { };
+    ~MagicSplitter() { };
+
+    PAF_Status scan(Flow*, const uint8_t* data, uint32_t len,
+        uint32_t flags, uint32_t* fp);
+};
+
+PAF_Status MagicSplitter::scan (
+    Flow*, const uint8_t* data, uint32_t len,
+    uint32_t, uint32_t* fp)
+{
+    // this is a basic hack to find http requests so that the overall
+    // processing flow can be determined at which point the real magic
+    // can begin.
+    if ( len >= 3 && !strncmp((const char*)data, "GET", 3) )
+    {
+        // FIXIT here we have determined that the inspector should
+        // be http and must somehow tell the binder so it can set 
+        // inspector gadget.
+
+        // the real magic must check direction and protocol
+        // (and should be called from eval() for udp and from
+        // here for tcp).
+
+        // len + 1 means go back to the last flush point
+        *fp = len + 1;
+
+        // the reset status ensures that all the
+        // data scanned so far is delivered to the new inspector's
+        // splitter.
+        return PAF_RESET;
+    }
+
+    return PAF_SEARCH;
+}
+
+//-------------------------------------------------------------------------
+// class stuff
+//-------------------------------------------------------------------------
+
+class Wizard : public Inspector {
+public:
+    Wizard();
+    ~Wizard();
+
+    void show(SnortConfig*)
+    { LogMessage("Wizard\n"); };
+
+    void eval(Packet*);
+
+    StreamSplitter* get_splitter(bool);
+
+private:
+
+private:
+};
+
+Wizard::Wizard()
+{
+}
+
+Wizard::~Wizard()
+{
+}
+
+void Wizard::eval(Packet*)
+{
+    if ( !IsUDP(p) )
+        return;
+
+    // FIXIT do udp scanning here
+    ++tstats.total_packets;
+}
+
+StreamSplitter* Wizard::get_splitter(bool c2s)
+{
+    return new MagicSplitter(c2s);
+}
+
+//-------------------------------------------------------------------------
+// api stuff
+//-------------------------------------------------------------------------
+
+static Module* mod_ctor()
+{ return new WizardModule; }
+
+static void mod_dtor(Module* m)
+{ delete m; }
+
+void wiz_init()
+{
+#ifdef PERF_PROFILING
+    RegisterPreprocessorProfile(
+        mod_name, &wizPerfStats, 0, &totalPerfStats, wiz_get_profile);
+#endif
+}
+
+static Inspector* wiz_ctor(Module* m)
+{
+    WizardModule* mod = (WizardModule*)m;
+    assert(mod);
+    return new Wizard;
+}
+
+static void wiz_dtor(Inspector* p)
+{
+    delete p;
+}
+
+static void wiz_sum()
+{
+    sum_stats(&gstats, &tstats);
+}
+
+static void wiz_stats()
+{
+    show_stats(&gstats, mod_name);
+}
+
+static void wiz_reset()
+{
+    memset(&gstats, 0, sizeof(gstats));
+}
+
+static const InspectApi wiz_api =
+{
+    {
+        PT_INSPECTOR,
+        mod_name,
+        INSAPI_PLUGIN_V0,
+        0,
+        mod_ctor,
+        mod_dtor
+    },
+    IT_WIZARD, 
+    PROTO_BIT__TCP | PROTO_BIT__UDP,
+    nullptr, // buffers
+    nullptr, // service
+    wiz_init,
+    nullptr, // term
+    wiz_ctor,
+    wiz_dtor,
+    nullptr, // pinit
+    nullptr, // pterm
+    nullptr, // ssn
+    wiz_sum,
+    wiz_stats,
+    wiz_reset
+};
+
+#ifdef BUILDING_SO
+SO_PUBLIC const BaseApi* snort_plugins[] =
+{
+    &wiz_api.base,
+    nullptr
+};
+#else
+const BaseApi* sin_wizard = &wiz_api.base;
+#endif
+
diff --git a/src/service_inspectors/wizard/wizard.h b/src/service_inspectors/wizard/wizard.h
new file mode 100644 (file)
index 0000000..b2029d6
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+** Copyright (C) 2014 Cisco and/or its affiliates. All rights reserved.
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License Version 2 as
+** published by the Free Software Foundation.  You may not use, modify or
+** distribute this program under any other version of the GNU General
+** Public License.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+// wizard.cc author Russ Combs <rucombs@cisco.com>
+
+#ifndef WIZARD_H
+#define WIZARD_H
+
+#include <string>
+
+#endif
+
index b53ab29c5666408164aa91c7becdb47f36317f92..7cbe3c408147c224e5d794fc02d24d402b1539db 100644 (file)
@@ -141,7 +141,8 @@ StreamBase::StreamBase(const StreamConfig* c)
 void StreamBase::pinit()
 {
     assert(!flow_con);
-    flow_con = new FlowControl();
+    Inspector* pi = InspectorManager::get_inspector("binder");
+    flow_con = new FlowControl(pi);
     InspectSsnFunc f;
 
     if ( config->tcp_cfg.max_sessions )
index ec58c2b9e424a06a982301e8099ca665ed9a7291..76fa73505000dac0dfee6b46739cb32ec3e3885e 100644 (file)
@@ -33,7 +33,8 @@ class Flow;
         PAF_START,   // internal use only
         PAF_SEARCH,  // searching for next flush point
         PAF_FLUSH,   // flush at given offset
-        PAF_SKIP     // skip ahead to given offset
+        PAF_SKIP,    // skip ahead to given offset
+        PAF_RESET    // rewind to the prior flush point
     };
 
 //-------------------------------------------------------------------------
index 2abee3f51dc1d05c6f7d113ce31c74c37c6c581a..3a2875b7b3b0efad2d0be5f3ef50cf510a9cf584 100644 (file)
@@ -149,12 +149,12 @@ void ShowRuleProfiles(void);
 void ResetRuleProfiling(void);
 
 /* Preprocessor stats info */
-typedef struct _PreprocStats
+struct PreprocStats
 {
     uint64_t ticks, ticks_start;
     uint64_t checks;
     uint64_t exits;
-} PreprocStats;
+};
 
 typedef struct _ProfileConfig
 {