]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1200 in SNORT/snort3 from navl_integration to master
authorMike Stepanek (mstepane) <mstepane@cisco.com>
Fri, 27 Apr 2018 19:55:23 +0000 (15:55 -0400)
committerMike Stepanek (mstepane) <mstepane@cisco.com>
Fri, 27 Apr 2018 19:55:23 +0000 (15:55 -0400)
Squashed commit of the following:

commit 1ce3e5786af7a18a4f23af459fa65ca4f14c0298
Author: Shravan Rangaraju <shrarang@cisco.com>
Date:   Tue Apr 10 13:22:37 2018 -0400

    appid: Third party integration support

70 files changed:
cmake/create_options.cmake
cmake/create_pkg_config.cmake
config.cmake.h.in
extra/CMakeLists.txt
extra/src/CMakeLists.txt
extra/src/tp_appid/CMakeLists.txt [new file with mode: 0644]
extra/src/tp_appid/mock/CMakeLists.txt [new file with mode: 0644]
extra/src/tp_appid/mock/tp_mock.cc [new file with mode: 0644]
snort.pc.in
src/network_inspectors/appid/CMakeLists.txt
src/network_inspectors/appid/app_forecast.cc
src/network_inspectors/appid/app_forecast.h
src/network_inspectors/appid/appid_api.cc
src/network_inspectors/appid/appid_config.cc
src/network_inspectors/appid/appid_config.h
src/network_inspectors/appid/appid_detector.h
src/network_inspectors/appid/appid_discovery.cc
src/network_inspectors/appid/appid_discovery.h
src/network_inspectors/appid/appid_http_event_handler.cc
src/network_inspectors/appid/appid_http_session.cc
src/network_inspectors/appid/appid_http_session.h
src/network_inspectors/appid/appid_inspector.cc
src/network_inspectors/appid/appid_module.cc
src/network_inspectors/appid/appid_session.cc
src/network_inspectors/appid/appid_session.h
src/network_inspectors/appid/appid_types.h [new file with mode: 0644]
src/network_inspectors/appid/client_plugins/client_discovery.cc
src/network_inspectors/appid/client_plugins/client_discovery.h
src/network_inspectors/appid/detector_plugins/detector_dns.cc
src/network_inspectors/appid/detector_plugins/detector_dns.h
src/network_inspectors/appid/detector_plugins/detector_kerberos.cc
src/network_inspectors/appid/detector_plugins/detector_sip.cc
src/network_inspectors/appid/http_xff_fields.h [new file with mode: 0644]
src/network_inspectors/appid/length_app_cache.h
src/network_inspectors/appid/lua_detector_api.cc
src/network_inspectors/appid/lua_detector_api.h
src/network_inspectors/appid/lua_detector_flow_api.cc
src/network_inspectors/appid/service_plugins/service_detector.cc
src/network_inspectors/appid/service_plugins/service_detector.h
src/network_inspectors/appid/service_plugins/service_direct_connect.cc
src/network_inspectors/appid/service_plugins/service_direct_connect.h
src/network_inspectors/appid/service_plugins/service_discovery.cc
src/network_inspectors/appid/service_plugins/service_discovery.h
src/network_inspectors/appid/service_plugins/service_ftp.cc
src/network_inspectors/appid/service_plugins/service_ftp.h
src/network_inspectors/appid/service_plugins/service_netbios.cc
src/network_inspectors/appid/service_plugins/service_rpc.cc
src/network_inspectors/appid/service_plugins/service_rpc.h
src/network_inspectors/appid/test/CMakeLists.txt
src/network_inspectors/appid/test/appid_api_test.cc
src/network_inspectors/appid/test/appid_debug_test.cc
src/network_inspectors/appid/test/appid_http_event_test.cc
src/network_inspectors/appid/test/appid_mock_definitions.h
src/network_inspectors/appid/test/appid_mock_http_session.h
src/network_inspectors/appid/test/appid_mock_session.h
src/network_inspectors/appid/test/log_message_mock.h [new file with mode: 0644]
src/network_inspectors/appid/test/service_state_test.cc
src/network_inspectors/appid/test/tp_appid_types_test.cc [new file with mode: 0644]
src/network_inspectors/appid/test/tp_lib_handler_test.cc [new file with mode: 0644]
src/network_inspectors/appid/test/tp_mock.cc [new file with mode: 0644]
src/network_inspectors/appid/thirdparty_appid_api.h [deleted file]
src/network_inspectors/appid/thirdparty_appid_types.h [deleted file]
src/network_inspectors/appid/thirdparty_appid_utils.cc [deleted file]
src/network_inspectors/appid/thirdparty_appid_utils.h [deleted file]
src/network_inspectors/appid/tp_appid_module_api.h [new file with mode: 0644]
src/network_inspectors/appid/tp_appid_session_api.h [new file with mode: 0644]
src/network_inspectors/appid/tp_appid_types.h [new file with mode: 0644]
src/network_inspectors/appid/tp_appid_utils.cc [new file with mode: 0644]
src/network_inspectors/appid/tp_lib_handler.cc [new file with mode: 0644]
src/network_inspectors/appid/tp_lib_handler.h [new file with mode: 0644]

index 5e3eb06dbb7e74d46903e3609de94340225d16fb..cc7f3869ff8b37622f3e020412410e83325a7682 100644 (file)
@@ -16,6 +16,7 @@ option ( ENABLE_STATIC_DAQ "link static DAQ modules" ON )
 
 # features
 option ( ENABLE_SHELL "enable shell support" OFF )
+option ( ENABLE_APPID_THIRD_PARTY "enable third party appid" OFF )
 option ( ENABLE_UNIT_TESTS "enable unit tests" OFF )
 option ( ENABLE_PIGLET "enable piglet test harness" OFF )
 
index 098d0534fda6048813ea7aefd713899d0352eb4c..7550dbaec6bb7e9d966cd54080633755aeb55333 100644 (file)
@@ -60,6 +60,9 @@ if(UUID_INCLUDE_DIR)
     set(UUID_CPPFLAGS "-I${UUID_INCLUDE_DIR}")
 endif()
 
+if(ENABLE_APPID_THIRD_PARTY)
+    set(TP_APPID_CPPFLAGS "-DENABLE_APPID_THIRD_PARTY")
+endif()
 # create & install pkgconfig file
 
 configure_file(
index 196708141c4f8313cfabd7be773fde8c03e6ce6c..cb7f2333a24fe635df8e036ec28e8502f4425114 100644 (file)
@@ -61,6 +61,9 @@
 /* include internal inspectors in binary */
 #cmakedefine STATIC_SEARCH_ENGINES 1
 
+/* enable third party appid */
+#cmakedefine ENABLE_APPID_THIRD_PARTY 1
+
 /* enable unit tests */
 #cmakedefine UNIT_TEST 1
 
index 05fc5074434605f6169fb36d085af096c803c34b..49ac83cf6d4996730d480cd0243031aa28069c53 100644 (file)
@@ -77,6 +77,9 @@ foreach ( OPT ${CPP_OPTS_OTHER} )
 
     string ( REGEX REPLACE "[\r\n]" " " CPPFLAGS "${CPPFLAGS}" )
     set ( ${OPT}_CPPFLAGS "${CPPFLAGS}" CACHE STRING "" )
+
+    set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${${OPT}_CPPFLAGS}" CACHE STRING "" FORCE )
+    set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${${OPT}_CPPFLAGS}" CACHE STRING "" FORCE )
 endforeach ( OPT )
 
 # Set these after all tests are done but *before* any subdirectories are included
index d465fd3bcfb4732a12807ec9703b884c37ee6c4c..8f277fd141bb9e8f24c3a192b8b4ae1deebb1bc8 100644 (file)
@@ -1,3 +1,5 @@
+include(CheckIncludeFileCXX)
+
 add_subdirectory ( codecs )
 add_subdirectory ( daqs )
 add_subdirectory ( inspectors )
@@ -5,3 +7,9 @@ add_subdirectory ( ips_options )
 add_subdirectory ( loggers )
 add_subdirectory ( search_engines )
 add_subdirectory ( so_rules )
+
+CHECK_INCLUDE_FILE_CXX( "${CMAKE_INSTALL_PREFIX}/include/snort/network_inspectors/appid/tp_appid_module_api.h" ENABLE_APPID_THIRD_PARTY ${CMAKE_CXX_FLAGS})
+
+if ( ENABLE_APPID_THIRD_PARTY )
+  add_subdirectory ( tp_appid )
+endif()
diff --git a/extra/src/tp_appid/CMakeLists.txt b/extra/src/tp_appid/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b41ab56
--- /dev/null
@@ -0,0 +1 @@
+add_subdirectory ( mock )
diff --git a/extra/src/tp_appid/mock/CMakeLists.txt b/extra/src/tp_appid/mock/CMakeLists.txt
new file mode 100644 (file)
index 0000000..55d325e
--- /dev/null
@@ -0,0 +1,45 @@
+cmake_minimum_required ( VERSION 3.4.3 )
+project ( lowmem CXX )
+
+set (CMAKE_CXX_STANDARD 11)
+set (CMAKE_CXX_STANDARD_REQUIRED ON)
+set (CMAKE_CXX_EXTENSIONS OFF)
+
+if ( APPLE )
+    set ( CMAKE_MACOSX_RPATH OFF )
+endif ( APPLE )
+
+include ( FindPkgConfig )
+pkg_search_module ( SNORT3 REQUIRED snort>=3 )
+
+add_library (
+  tp_mock MODULE
+  tp_mock.cc
+)
+
+if ( APPLE )
+    set_target_properties (
+      tp_lib
+        PROPERTIES
+            LINK_FLAGS "-undefined dynamic_lookup"
+    )
+endif ( APPLE )
+
+set_target_properties (
+  tp_mock
+    PROPERTIES
+        PREFIX ""
+       )
+
+set_property(TARGET tp_mock PROPERTY ENABLE_EXPORTS 1)      
+
+target_include_directories (
+    tp_mock PUBLIC
+    ${SNORT3_INCLUDE_DIRS}
+)
+
+install (
+    TARGETS tp_mock
+    LIBRARY
+        DESTINATION "${CMAKE_INSTALL_LIBDIR}/${CMAKE_PROJECT_NAME}/tp_appid"
+)
diff --git a/extra/src/tp_appid/mock/tp_mock.cc b/extra/src/tp_appid/mock/tp_mock.cc
new file mode 100644 (file)
index 0000000..e9b5afa
--- /dev/null
@@ -0,0 +1,147 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2016-2018 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.
+//--------------------------------------------------------------------------
+
+// Brief description:
+//
+// Minimalist example of an implementation of a third party library for appid
+// detection.
+// Snort interacts with this library via 3 classes:
+// 1) TPLibHandler - to load the third party library.
+// 2) ThirdPartyAppIDModule - to initialize and clean-up whatever we might need
+// 3) ThirdPartyAppIDSession - for the actual information extracted from packets
+// The third party library must provide implementations to the abstract classes
+// ThirdPartyAppIDModule and ThirdPartyAppIDSession and must also implement the
+// object factory functions returning pointers to the derived classes.
+//
+//
+// Standalone compilation:
+// g++ -g -Wall -I/path/to/snort3/src -c tp_mock.cc
+// g++ -std=c++11 -g -Wall -I/path/to/snort3/src -shared -fPIC -o libtp_mock.so tp_mock.cc
+// As a module (dynamically loaded)  - see CMakeLists.txt
+
+#include <iostream>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "main/snort_types.h"
+
+#include "network_inspectors/appid/tp_appid_module_api.h"
+#include "network_inspectors/appid/tp_appid_session_api.h"
+
+#define THIRD_PARTY_APPID_MODULE_NAME "NAVL"
+
+#define WhereMacro __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__
+
+using namespace std;
+
+class ThirdPartyAppIDModuleImpl : public ThirdPartyAppIDModule
+{
+public:
+    ThirdPartyAppIDModuleImpl(uint32_t ver, const char* mname)
+        : ThirdPartyAppIDModule(ver, mname)
+    {
+        cerr << WhereMacro << endl;
+    }
+
+    ~ThirdPartyAppIDModuleImpl()
+    {
+        cerr << WhereMacro << endl;
+    }
+
+    int pinit(ThirdPartyConfig& config)
+    {
+        cerr << WhereMacro
+             << ": main thread initialization, possibly load other libraries." << endl;
+        return 0;
+    }
+
+    int tinit()
+    {
+        cerr << WhereMacro << ": per worker thread initialization." << endl;
+        return 0;
+    }
+
+    int reconfigure(const ThirdPartyConfig& config)
+    {
+        cerr << WhereMacro << ": do not call pinit() during reconfigure." << endl;
+        return 0;
+    }
+
+    int pfini()
+    {
+        cerr << WhereMacro << ": main thread clean-up." << endl;
+        return 0;
+    }
+
+    int tfini()
+    {
+        cerr << WhereMacro << ": per worker-thread clean-up." << endl;
+        return 0;
+    }
+
+    int print_stats() { return 0; }
+    int reset_stats() { return 0; }
+};
+
+class ThirdPartyAppIDSessionImpl : public ThirdPartyAppIDSession
+{
+public:
+
+    bool reset() { return 1; }
+    bool process(const snort::Packet&,
+        AppidSessionDirection direction,
+        vector<AppId>& proto_list,
+        ThirdPartyAppIDAttributeData& attribute_data)
+    {
+        cerr << WhereMacro
+             << ": third party packet parsing and appid processing." << endl;
+        return 1;
+    }
+
+    int disable_flags(uint32_t session_flags) { return 0; }
+    TPState get_state() { return state; }
+    void set_state(TPState s) { state=s; }
+    void clear_attr(TPSessionAttr attr) { flags &= ~attr; }
+    void set_attr(TPSessionAttr attr) { flags |= attr; }
+    unsigned get_attr(TPSessionAttr attr) { return flags & attr; }
+
+private:
+    unsigned flags=0;
+};
+
+// Object factories to create module and session.
+// This is the only way for outside callers to create module and session
+// once the .so has been loaded.
+extern "C"
+{
+    SO_PUBLIC ThirdPartyAppIDModuleImpl* create_third_party_appid_module()
+    {
+        return new ThirdPartyAppIDModuleImpl(1,"third party");
+    }
+}
+
+extern "C"
+{
+    SO_PUBLIC ThirdPartyAppIDSessionImpl* create_third_party_appid_session()
+    {
+        return new ThirdPartyAppIDSessionImpl;
+    }
+}
+
index 9aa826f29a48e817c05df21c9fe3086204eec7cc..08972e438e5b0c9b859c4939434ede552ae7d39b 100644 (file)
@@ -9,8 +9,9 @@ mandir=@mandir@
 infodir=@infodir@
 
 cpp_opts=DAQ LUAJIT
-cpp_opts_other=DNET FLATBUFFERS HWLOC HYPERSCAN LZMA OPENSSL PCAP PCRE UUID
+cpp_opts_other=DNET FLATBUFFERS HWLOC HYPERSCAN LZMA OPENSSL PCAP PCRE UUID TP_APPID
 
+TP_APPID_CPPFLAGS=@TP_APPID_CPPFLAGS@
 PCAP_CPPFLAGS=@PCAP_CPPFLAGS@
 LUAJIT_CPPFLAGS=@LUAJIT_CPPFLAGS@
 DNET_CPPFLAGS=@DNET_CPPFLAGS@
index d92cf734fa6d538485334963b9091eaed0123280..2a460990aa6ecf820f75d870291b79ece9f70969 100644 (file)
@@ -1,9 +1,21 @@
+if ( ENABLE_APPID_THIRD_PARTY )
+  set (APPID_TP_INCLUDES
+    tp_appid_module_api.h
+    tp_appid_session_api.h
+    tp_appid_types.h
+    http_xff_fields.h
+    )
+endif()
+
 
 set (APPID_INCLUDES
     appid_api.h
     appid_dns_session.h
     appid_http_session.h
+    appid_types.h
     application_ids.h
+    http_xff_fields.h
+    ${APPID_TP_INCLUDES}
 )
 
 set ( APPID_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR} )
@@ -142,6 +154,15 @@ set ( UTIL_APPID_SOURCES
        appid_utils/sf_multi_mpse.h
 )
 
+if ( ENABLE_APPID_THIRD_PARTY )
+  set( APPID_TP_SOURCES
+    tp_lib_handler.cc
+    tp_appid_utils.cc
+    tp_lib_handler.h
+    tp_appid_types.h
+    )
+endif()
+
 set ( APPID_SOURCES
     app_forecast.cc
     app_forecast.h
@@ -163,6 +184,7 @@ set ( APPID_SOURCES
     appid_peg_counts.cc
     appid_session.cc
     appid_session.h
+    appid_types.h
     appid_inspector.cc
     appid_inspector.h
     appid_module.cc
@@ -188,10 +210,8 @@ set ( APPID_SOURCES
     lua_detector_util.h
     service_state.cc
     service_state.h
-    thirdparty_appid_api.h
-    thirdparty_appid_types.h
-    thirdparty_appid_utils.cc
-    thirdparty_appid_utils.h
+    http_xff_fields.h
+    ${APPID_TP_SOURCES}
     )
 
 
index a92986e98a89895dd169f9ac2b9d8af655e29988..987fe156d625d8075d8ca64be6184a8674c744e1 100644 (file)
@@ -89,7 +89,7 @@ void add_af_indicator(AppId indicator, AppId forecast, AppId target)
         ErrorMessage("LuaDetectorApi:Failed to add AFElement for appId %d", indicator);
 }
 
-static inline void rekey_master_AF_key(Packet* p, int dir, AppId forecast)
+static inline void rekey_master_AF_key(Packet* p, AppidSessionDirection dir, AppId forecast)
 {
     const SfIp* src = dir ? p->ptrs.ip_api.get_dst() : p->ptrs.ip_api.get_src();
 
@@ -99,7 +99,7 @@ static inline void rekey_master_AF_key(Packet* p, int dir, AppId forecast)
     master_key.forecast = forecast;
 }
 
-void check_session_for_AF_indicator(Packet* p, int dir, AppId indicator)
+void check_session_for_AF_indicator(Packet* p, AppidSessionDirection dir, AppId indicator)
 {
     AFElement* ind_element;
     if (!(ind_element = (AFElement*)xhash_find(AF_indicators, &indicator)))
@@ -122,7 +122,7 @@ void check_session_for_AF_indicator(Packet* p, int dir, AppId indicator)
     xhash_add(AF_actives, &master_key, &new_active_value);
 }
 
-AppId check_session_for_AF_forecast(AppIdSession& asd, Packet* p, int dir, AppId forecast)
+AppId check_session_for_AF_forecast(AppIdSession& asd, Packet* p, AppidSessionDirection dir, AppId forecast)
 {
     AFActVal* check_act_val;
 
index d292c00099eec212179f5d81ebd3197bf587f6ae..98a70810e2e49c57b55f734f3ebb59da3eba0828 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <ctime>
 #include "flow/flow.h"
+#include "appid_types.h"
 #include "application_ids.h"
 
 class AppIdSession;
@@ -62,8 +63,8 @@ struct AFActVal
 int init_appid_forecast();
 void clean_appid_forecast();
 void add_af_indicator(AppId, AppId, AppId);
-void check_session_for_AF_indicator(snort::Packet*, int, AppId);
-AppId check_session_for_AF_forecast(AppIdSession&, snort::Packet*, int, AppId);
+void check_session_for_AF_indicator(snort::Packet*, AppidSessionDirection, AppId);
+AppId check_session_for_AF_forecast(AppIdSession&, snort::Packet*, AppidSessionDirection, AppId);
 
 #endif
 
index 0a0d1df2f2d11b804cf8b271ba163f910e20992c..0c775ab4e51fa19363fed60ab13997b1270ff7f1 100644 (file)
 
 #include "appid_api.h"
 #include "app_info_table.h"
-#include "thirdparty_appid_utils.h"
 #include "service_plugins/service_bootp.h"
 #include "service_plugins/service_netbios.h"
 #include "utils/util.h"
+#ifdef ENABLE_APPID_THIRD_PARTY
+#include "tp_appid_session_api.h"
+#endif
 
 using namespace snort;
 
@@ -195,11 +197,11 @@ bool AppIdApi::is_appid_inspecting_session(Flow& flow)
         if ( asd->common.flow_type == APPID_FLOW_TYPE_NORMAL )
         {
             if ( asd->service_disco_state != APPID_DISCO_STATE_FINISHED ||
-                !is_third_party_appid_done(asd->tpsession) ||
-                asd->get_session_flags(APPID_SESSION_HTTP_SESSION | APPID_SESSION_CONTINUE) ||
-                (asd->get_session_flags(APPID_SESSION_ENCRYPTED) &&
-                (asd->get_session_flags(APPID_SESSION_DECRYPTED) ||
-                asd->session_packet_count < SSL_WHITELIST_PKT_LIMIT)) )
+                 !asd->is_third_party_appid_done() ||
+                 asd->get_session_flags(APPID_SESSION_HTTP_SESSION | APPID_SESSION_CONTINUE) ||
+                 (asd->get_session_flags(APPID_SESSION_ENCRYPTED) &&
+                  (asd->get_session_flags(APPID_SESSION_DECRYPTED) ||
+                   asd->session_packet_count < SSL_WHITELIST_PKT_LIMIT)) )
             {
                 return true;
             }
@@ -244,7 +246,7 @@ bool AppIdApi::is_appid_available(Flow& flow)
         // FIXIT-M: If a third-party module is not available then this
         //          should probably check if an appId has been discovered
         //          by the local AppId module.
-        return is_third_party_appid_available(asd->tpsession);
+        return asd->is_third_party_appid_available();
     }
 
     return false;
@@ -395,7 +397,7 @@ uint32_t AppIdApi::produce_ha_state(Flow& flow, uint8_t* buf)
     if ( asd && ( get_flow_type(flow) == APPID_FLOW_TYPE_NORMAL ) )
     {
         appHA->flags = APPID_HA_FLAGS_APP;
-        if ( is_third_party_appid_available(asd->tpsession) )
+        if ( asd->is_third_party_appid_available() )
             appHA->flags |= APPID_HA_FLAGS_TP_DONE;
         if ( asd->is_service_detected() )
             appHA->flags |= APPID_HA_FLAGS_SVC_DONE;
@@ -446,8 +448,10 @@ uint32_t AppIdApi::consume_ha_state(Flow& flow, const uint8_t* buf, uint8_t, IpP
                 asd->service_disco_state = APPID_DISCO_STATE_FINISHED;
 
             asd->client_disco_state = APPID_DISCO_STATE_FINISHED;
-            if ( thirdparty_appid_module )
-                thirdparty_appid_module->session_state_set(asd->tpsession, TP_STATE_HA);
+#ifdef ENABLE_APPID_THIRD_PARTY
+            if (asd->tpsession)
+                asd->tpsession->set_state(TP_STATE_HA);
+#endif
         }
 #else
         if ( !asd )
@@ -457,9 +461,12 @@ uint32_t AppIdApi::consume_ha_state(Flow& flow, const uint8_t* buf, uint8_t, IpP
         }
 #endif
 
-        if ( ( appHA->flags & APPID_HA_FLAGS_TP_DONE ) && thirdparty_appid_module )
+        if( (appHA->flags & APPID_HA_FLAGS_TP_DONE) && asd->tpsession )
         {
-            thirdparty_appid_module->session_state_set(asd->tpsession, TP_STATE_TERMINATED);
+#ifdef ENABLE_APPID_THIRD_PARTY
+            if( asd->tpsession)
+                asd->tpsession->set_state(TP_STATE_TERMINATED);
+#endif
             asd->set_session_flags(APPID_SESSION_NO_TPI);
         }
 
@@ -514,7 +521,7 @@ bool AppIdApi::is_http_inspection_done(Flow& flow)
 
     if ( AppIdSession* asd = get_appid_session(flow) )
         if ( ( asd->common.flow_type == APPID_FLOW_TYPE_NORMAL ) &&
-                    !is_third_party_appid_done(asd->tpsession) )
+             !asd->is_third_party_appid_done() )
             done = false;
 
     return done;
index 9fe2ac9514fcce49da383544d9cabb0fbc28b1f5..c374d285894ad2bc87dda0b045062af7b23e68b8 100644 (file)
@@ -30,7 +30,6 @@
 
 #include "app_info_table.h"
 #include "appid_session.h"
-#include "thirdparty_appid_utils.h"
 #ifdef USE_RNA_CONFIG
 #include "appid_utils/network_set.h"
 #include "appid_utils/ip_funcs.h"
 #include "log/messages.h"
 #include "utils/util.h"
 #include "target_based/snort_protocols.h"
+#ifdef ENABLE_APPID_THIRD_PARTY
+#include "tp_lib_handler.h"
+#endif
+
 
 #define ODP_PORT_DETECTORS "odp/port/*"
 #define CUSTOM_PORT_DETECTORS "custom/port/*"
@@ -85,7 +88,6 @@ AppIdModuleConfig::~AppIdModuleConfig()
     snort_free((void*)conf_file);
 #endif
     snort_free((void*)app_detector_dir);
-    snort_free((void*)thirdparty_appid_dir);
 }
 
 AppIdConfig::AppIdConfig(AppIdModuleConfig* config)
@@ -119,6 +121,38 @@ AppIdConfig::~AppIdConfig()
     cleanup();
 }
 
+const TPLibHandler * AppIdConfig::tp_handler() const
+{
+#ifdef ENABLE_APPID_THIRD_PARTY
+    return tph;
+#else
+    return nullptr;
+#endif
+}
+
+bool AppIdConfig::have_tp() const
+{
+#ifdef ENABLE_APPID_THIRD_PARTY
+    return tph != nullptr && tph->have_tp();
+#else
+    return false;
+#endif
+}
+
+void AppIdConfig::tp_appid_module_tinit()
+{
+#ifdef ENABLE_APPID_THIRD_PARTY
+    if(tph) tph->tinit();
+#endif
+}
+
+void AppIdConfig::tp_appid_module_tterm()
+{
+#ifdef ENABLE_APPID_THIRD_PARTY
+    if(tph) tph->tterm();
+#endif
+}
+
 void AppIdConfig::read_port_detectors(const char* files)
 {
     int rval;
@@ -737,7 +771,11 @@ bool AppIdConfig::init_appid(SnortConfig* sc)
 #endif
     read_port_detectors(ODP_PORT_DETECTORS);
     read_port_detectors(CUSTOM_PORT_DETECTORS);
-    ThirdPartyAppIDInit(mod_config);
+
+#ifdef ENABLE_APPID_THIRD_PARTY
+    tph=TPLibHandler::get();
+    tph->pinit(mod_config);
+#endif
     map_app_names_to_snort_ids(sc);
     return true;
 }
@@ -756,10 +794,11 @@ static void free_port_exclusion_list(AppIdPortExclusions& pe_list)
 
 void AppIdConfig::cleanup()
 {
-    if (thirdparty_appid_module != nullptr)
-        thirdparty_appid_module->print_stats();
-    ThirdPartyAppIDFini();
-
+#ifdef ENABLE_APPID_THIRD_PARTY
+    tph->pfini(0);
+    TPLibHandler::destroy(tph);
+#endif
+    
     app_info_mgr.cleanup_appid_info_table();
 
 #ifdef USE_RNA_CONFIG
@@ -815,8 +854,8 @@ void AppIdConfig::show()
 {
     unsigned i;
 
-    if (mod_config->thirdparty_appid_dir)
-        LogMessage("    3rd Party Dir: %s\n", mod_config->thirdparty_appid_dir);
+    if (!mod_config->tp_appid_path.empty())
+        LogMessage("    3rd Party Dir: %s\n", mod_config->tp_appid_path.c_str());
 
 #ifdef USE_RNA_CONFIG
     struct in_addr ia;
index 59c91ec8e68d252f4a9520bbf895604a80fd12aa..54156b0709ee6030af8ed9398f740b528e09a80c 100644 (file)
@@ -23,6 +23,7 @@
 #define APP_ID_CONFIG_H
 
 #include <array>
+#include <string>
 
 #include "application_ids.h"
 #include "framework/decode_data.h"
@@ -38,6 +39,7 @@
 
 struct NetworkSet;
 class AppInfoManager;
+class TPLibHandler;
 
 extern unsigned appIdPolicyId;
 extern uint32_t app_id_netmasks[];
@@ -67,7 +69,8 @@ public:
     unsigned long app_stats_rollover_size = 0;
     unsigned long app_stats_rollover_time = 0;
     const char* app_detector_dir = nullptr;
-    const char* thirdparty_appid_dir = nullptr;
+    std::string tp_appid_path = "";
+    std::string tp_appid_config = "";
     uint32_t instance_id = 0;
     uint32_t memcap = 0;
     bool debug = false;
@@ -121,6 +124,11 @@ public:
     AppIdModuleConfig* mod_config = nullptr;
     unsigned appIdPolicyId = 53;
 
+    const TPLibHandler * tp_handler() const;
+    bool have_tp() const;
+    void tp_appid_module_tinit();
+    void tp_appid_module_tterm();
+
 private:
     void read_port_detectors(const char* files);
     void configure_analysis_networks(char* toklist[], uint32_t flag);
@@ -132,6 +140,11 @@ private:
     void display_port_config();
 
     AppInfoManager& app_info_mgr;
+
+// #ifdef ENABLE_APPID_THIRD_PARTY
+    // class that holds pointers to third party objects in thirdparty.so
+    TPLibHandler* tph = nullptr;
+// #endif
 };
 
 #endif
index 0bce0d1ee428a28b80419262b4eea4a8ec54e3ae..fa7176d527e58ad8178bd931aa94954df4249beb 100644 (file)
@@ -75,13 +75,13 @@ typedef std::vector<ServiceDetectorPort> ServiceDetectorPorts;
 class AppIdDiscoveryArgs
 {
 public:
-    AppIdDiscoveryArgs(const uint8_t* data, uint16_t size, int dir, AppIdSession& asd,
+    AppIdDiscoveryArgs(const uint8_t* data, uint16_t size, AppidSessionDirection dir, AppIdSession& asd,
         snort::Packet* p) : data(data), size(size), dir(dir), asd(asd), pkt(p), config(asd.config)
     {}
 
     const uint8_t* data;
     uint16_t size;
-    int dir;
+    AppidSessionDirection dir;
     AppIdSession& asd;
     snort::Packet* pkt;
     const AppIdConfig* config = nullptr;
@@ -147,11 +147,11 @@ public:
     AppIdDiscovery& get_handler() const
     { return *handler; }
 
-       bool is_client() const
-       { return client; }
+        bool is_client() const
+        { return client; }
 
-       virtual LuaStateDescriptor* validate_lua_state(bool /*packet_context*/)
-       { return nullptr; }
+        virtual LuaStateDescriptor* validate_lua_state(bool /*packet_context*/)
+        { return nullptr; }
 
 protected:
     AppIdDiscovery* handler = nullptr;
index b879be612d4c1ed6ccf5a9c8f29a2706240db930..3197e03a5ef496c9eeb83ea42499b79cc50a6ca0 100644 (file)
 #include "detector_plugins/http_url_patterns.h"
 #include "host_port_app_cache.h"
 #include "service_plugins/service_discovery.h"
-#include "thirdparty_appid_utils.h"
+#ifdef ENABLE_THIRD_PARTY_APPID
+#include "tp_appid_session_api.h"
+#endif
 
 using namespace snort;
 
+bool do_discovery(AppIdSession&, IpProtocol, Packet*, AppidSessionDirection&);
+
 AppIdDiscovery::AppIdDiscovery(AppIdInspector& ins)
     : inspector(ins)
 {
@@ -269,7 +273,7 @@ static inline bool is_special_session_monitored(const Packet* p)
 }
 
 static bool set_network_attributes(AppIdSession* asd, Packet* p, IpProtocol& protocol,
-    int& direction)
+    AppidSessionDirection& direction)
 {
     if (asd)
     {
@@ -314,7 +318,7 @@ static bool set_network_attributes(AppIdSession* asd, Packet* p, IpProtocol& pro
     return true;
 }
 
-static bool is_packet_ignored(AppIdSession* asd, Packet* p, int& direction)
+static bool is_packet_ignored(AppIdSession* asd, Packet* p, AppidSessionDirection& direction)
 {
 // FIXIT-M - Need to convert this _dpd stream api call to the correct snort++ method
 #ifdef REMOVED_WHILE_NOT_IN_USE
@@ -357,7 +361,7 @@ static bool is_packet_ignored(AppIdSession* asd, Packet* p, int& direction)
     return false;
 }
 
-static uint64_t is_session_monitored(AppIdSession& asd, const Packet* p, int dir,
+static uint64_t is_session_monitored(AppIdSession& asd, const Packet* p, AppidSessionDirection dir,
     AppIdInspector& inspector)
 {
     uint64_t flags = 0;
@@ -491,7 +495,7 @@ static uint64_t is_session_monitored(AppIdSession& asd, const Packet* p, int dir
     return flow_flags;
 }
 
-static uint64_t is_session_monitored(const Packet* p, int dir, AppIdInspector& inspector)
+static uint64_t is_session_monitored(const Packet* p, AppidSessionDirection dir, AppIdInspector& inspector)
 {
     uint64_t flags = 0;
     uint64_t flow_flags = APPID_SESSION_DISCOVER_APP;
@@ -556,7 +560,7 @@ static uint64_t is_session_monitored(const Packet* p, int dir, AppIdInspector& i
 }
 
 static void lookup_appid_by_host_port(AppIdSession& asd, Packet* p, IpProtocol protocol,
-    int direction)
+    AppidSessionDirection direction)
 {
     HostPortVal* hv = nullptr;
     uint16_t port = 0;
@@ -589,10 +593,10 @@ static void lookup_appid_by_host_port(AppIdSession& asd, Packet* p, IpProtocol p
             asd.service_disco_state = APPID_DISCO_STATE_FINISHED;
             asd.client_disco_state = APPID_DISCO_STATE_FINISHED;
             asd.set_session_flags(APPID_SESSION_SERVICE_DETECTED);
-            if (thirdparty_appid_module)
-                thirdparty_appid_module->session_delete(asd.tpsession, 1);
-
-            asd.tpsession = nullptr;
+#ifdef ENABLE_THIRD_PARTY_APPID
+            if (asd.tpsession)
+                asd.tpsession->reset();
+#endif
         }
     }
 }
@@ -600,8 +604,8 @@ static void lookup_appid_by_host_port(AppIdSession& asd, Packet* p, IpProtocol p
 void AppIdDiscovery::do_application_discovery(Packet* p, AppIdInspector& inspector)
 {
     IpProtocol protocol = IpProtocol::PROTO_NOT_SET;
-    bool isTpAppidDiscoveryDone = false;
-    int direction = 0;
+    bool isTpAppidDiscoveryDone = true;
+    AppidSessionDirection direction = APP_ID_FROM_INITIATOR;
 
     AppIdSession* asd = (AppIdSession*)p->flow->get_flow_data(AppIdSession::inspector_id);
     if ( !set_network_attributes(asd, p, protocol, direction) )
@@ -616,6 +620,7 @@ void AppIdDiscovery::do_application_discovery(Packet* p, AppIdInspector& inspect
     if ( is_packet_ignored(asd, p, direction) )
         return;
 
+    // Create a TPDiscovery object from a TPLibHandle.
     uint64_t flow_flags;
     if (asd)
         flow_flags = is_session_monitored(*asd, p, direction, inspector);
@@ -749,9 +754,10 @@ void AppIdDiscovery::do_application_discovery(Packet* p, AppIdInspector& inspect
 
     asd->check_app_detection_restart();
 
-#ifdef REMOVED_WHILE_NOT_IN_USE
-    // do third party detector processing
-    isTpAppidDiscoveryDone = do_third_party_discovery(asd, protocol, ip, p, direction);
+// #ifdef ENABLE_APPID_THIRD_PARTY
+#if(0)   // FIXIT-H switch to ENABLE_APPID_THIRD_PARTY once bugs fixed
+    if(asd->config->have_tp())
+        isTpAppidDiscoveryDone = do_discovery(*asd,protocol,p,direction);
 #endif
 
     if ( !asd->get_session_flags(APPID_SESSION_PORT_SERVICE_DONE) )
index a701c4d95d5f75f808182baa6c1e6f88671777ac..c93c45f677e2893e49e889a529505e0a66309b67 100644 (file)
@@ -57,8 +57,7 @@ class AppIdPatternMatchNode
 {
 public:
     AppIdPatternMatchNode(AppIdDetector* detector, int start, unsigned len)
-        : service(detector), pattern_start_pos(start), size(len)
-    {}
+        : service(detector), pattern_start_pos(start), size(len) { }
 
     bool valid_match(int end_position)
     {
index 08565b38f3e3f260d29cf12afb63bdd5c3b30d9c..34b2c0f60b300e9003382256ac0d8195858b0a3f 100644 (file)
@@ -38,7 +38,7 @@ using namespace snort;
 
 void HttpEventHandler::handle(DataEvent& event, Flow* flow)
 {
-    int direction;
+    AppidSessionDirection direction;
     const uint8_t* header_start;
     int32_t header_length;
     HttpEvent* http_event = (HttpEvent*)&event;
index bf56e26fbbba1b7b6078b920bd5c16ad9b002e53..dbecf5b39de99a769a697790063b0bbbb40671e5 100644 (file)
 #include "appid_debug.h"
 #include "appid_session.h"
 #include "detector_plugins/http_url_patterns.h"
-#include "thirdparty_appid_utils.h"
+#include "http_xff_fields.h"
+#ifdef ENABLE_APPID_THIRD_PARTY
+#include "tp_appid_session_api.h"
+#endif
 
 static const char* httpFieldName[ MAX_HTTP_FIELD_ID ] = // for use in debug messages
 {
@@ -122,9 +125,10 @@ int AppIdHttpSession::initial_chp_sweep(ChpMatchDescriptor& cmd)
                                              && !asd.get_session_flags(APPID_SESSION_SPDY_SESSION))
         {
             asd.clear_session_flags(APPID_SESSION_CHP_INSPECTING);
-            if (thirdparty_appid_module)
-                thirdparty_appid_module->session_attr_clear(asd.tpsession,
-                    TP_ATTR_CONTINUE_MONITORING);
+#ifdef ENABLE_APPID_THIRD_PARTY
+            if (asd.tpsession)
+                asd.tpsession->clear_attr(TP_ATTR_CONTINUE_MONITORING);
+#endif
         }
     }
     chp_candidate = cah->appIdInstance;
@@ -132,28 +136,25 @@ int AppIdHttpSession::initial_chp_sweep(ChpMatchDescriptor& cmd)
     num_matches = cah->num_matches;
     num_scans = cah->num_scans;
 
-    if (thirdparty_appid_module)
+#ifdef ENABLE_APPID_THIRD_PARTY
+    if (asd.tpsession)
     {
         if ((ptype_scan_counts[RSP_CONTENT_TYPE_FID]))
-            thirdparty_appid_module->session_attr_set(asd.tpsession,
-                TP_ATTR_COPY_RESPONSE_CONTENT);
+            asd.tpsession->set_attr(TP_ATTR_COPY_RESPONSE_CONTENT);
         else
-            thirdparty_appid_module->session_attr_clear(asd.tpsession,
-                TP_ATTR_COPY_RESPONSE_CONTENT);
+            asd.tpsession->clear_attr(TP_ATTR_COPY_RESPONSE_CONTENT);
 
         if ((ptype_scan_counts[RSP_LOCATION_FID]))
-            thirdparty_appid_module->session_attr_set(asd.tpsession,
-                TP_ATTR_COPY_RESPONSE_LOCATION);
+            asd.tpsession->set_attr(TP_ATTR_COPY_RESPONSE_LOCATION);
         else
-            thirdparty_appid_module->session_attr_clear(asd.tpsession,
-                TP_ATTR_COPY_RESPONSE_LOCATION);
+            asd.tpsession->clear_attr(TP_ATTR_COPY_RESPONSE_LOCATION);
 
         if ((ptype_scan_counts[RSP_BODY_FID]))
-            thirdparty_appid_module->session_attr_set(asd.tpsession, TP_ATTR_COPY_RESPONSE_BODY);
+            asd.tpsession->set_attr(TP_ATTR_COPY_RESPONSE_BODY);
         else
-            thirdparty_appid_module->session_attr_clear(asd.tpsession,
-                TP_ATTR_COPY_RESPONSE_BODY);
+            asd.tpsession->clear_attr(TP_ATTR_COPY_RESPONSE_BODY);
     }
+#endif
 
     return 1;
 }
@@ -347,13 +348,14 @@ void AppIdHttpSession::process_chp_buffers()
     }
 }
 
-int AppIdHttpSession::process_http_packet(int direction)
+int AppIdHttpSession::process_http_packet(AppidSessionDirection direction)
 {
     snort::Profile http_profile_context(httpPerfStats);
     AppId service_id = APP_ID_NONE;
     AppId client_id = APP_ID_NONE;
     AppId payload_id = APP_ID_NONE;
-
+    bool have_tp = asd.tpsession != nullptr;
+    
     // For fragmented HTTP headers, do not process if none of the fields are set.
     // These fields will get set when the HTTP header is reassembled.
     if ( useragent.empty() && host.empty() && referer.empty() && uri.empty() )
@@ -407,9 +409,9 @@ int AppIdHttpSession::process_http_packet(int direction)
         {
             // Scan Server Header for Vendor & Version
             // FIXIT-M: Should we be checking the scan_flags even when
-            //     thirdparty_appid_module is off?
-            if ( (thirdparty_appid_module && (asd.scan_flags & SCAN_HTTP_VENDOR_FLAG) &&
-                            !server.empty()) || (!thirdparty_appid_module && !server.empty()) )
+            //     tp_appid_module is off?
+            if ( (have_tp && (asd.scan_flags & SCAN_HTTP_VENDOR_FLAG) &&
+                  !server.empty()) || (!have_tp && !server.empty()) )
             {
                 if ( asd.service.get_id() == APP_ID_NONE || asd.service.get_id() == APP_ID_HTTP )
                 {
@@ -485,9 +487,9 @@ int AppIdHttpSession::process_http_packet(int direction)
 
         /* Scan X-Working-With HTTP header */
         // FIXIT-M: Should we be checking the scan_flags even when
-        //     thirdparty_appid_module is off?
-        if ( (thirdparty_appid_module && (asd.scan_flags & SCAN_HTTP_XWORKINGWITH_FLAG) &&
-                        !x_working_with.empty()) || (!thirdparty_appid_module && !x_working_with.empty()) )
+        //     tp_appid_module is off?
+        if ( (have_tp && (asd.scan_flags & SCAN_HTTP_XWORKINGWITH_FLAG) &&
+              !x_working_with.empty()) || (!have_tp && !x_working_with.empty()))
         {
             AppId appId;
             char* version = nullptr;
@@ -519,10 +521,10 @@ int AppIdHttpSession::process_http_packet(int direction)
 
         // Scan Content-Type Header for multimedia types and scan contents
         // FIXIT-M: Should we be checking the scan_flags even when
-        //     thirdparty_appid_module is off?
-        if ( (thirdparty_appid_module && (asd.scan_flags & SCAN_HTTP_CONTENT_TYPE_FLAG)
-                        && !content_type.empty() && !asd.is_payload_appid_set())
-                        || (!thirdparty_appid_module && !asd.is_payload_appid_set() && !content_type.empty()) )
+        //     tp_appid_module is off?
+        if ( (have_tp && (asd.scan_flags & SCAN_HTTP_CONTENT_TYPE_FLAG)
+              && !content_type.empty() && !asd.is_payload_appid_set())
+             || (!have_tp && !asd.is_payload_appid_set() && !content_type.empty()) )
         {
             payload_id = http_matchers->get_appid_by_content_type(content_type.c_str(), content_type.size());
             if (appidDebug->is_active() && payload_id > APP_ID_NONE
@@ -606,11 +608,12 @@ int AppIdHttpSession::process_http_packet(int direction)
     return 0;
 }
 
-// FIXIT-H - This function is unused and untested currently... need to figure who wants it
-// and what it should do
-void AppIdHttpSession::update_http_xff_address(struct XffFieldValue* /*xff_fields*/,
-    uint32_t /*numXffFields*/)
+// FIXIT-H - Implement this function when (reconfigurable) XFF is supported.
+void AppIdHttpSession::update_http_xff_address(struct XffFieldValue* xff_fields,
+    uint32_t numXffFields)
 {
+    UNUSED(xff_fields);
+    UNUSED(numXffFields);
 #if 0
     static const char* defaultXffPrecedence[] =
     {
@@ -637,7 +640,7 @@ void AppIdHttpSession::update_http_xff_address(struct XffFieldValue* /*xff_field
     {
         for (unsigned i = 0; i < numXffFields; i++)
             LogMessage("AppIdDbg %s XFF %s : %s\n", appidDebug->get_debug_session(),
-                xff_fields[i].field, xff_fields[i].value.empty()? "(empty)": xff_fields[i].value);
+               xff_fields[i].field.c_str(), xff_fields[i].value.empty()? "(empty)": xff_fields[i].value);
     }
 
     // xffPrecedence array is sorted based on precedence
@@ -651,32 +654,36 @@ void AppIdHttpSession::update_http_xff_address(struct XffFieldValue* /*xff_field
                 xff_addr = nullptr;
             }
 
-            if (strncasecmp(xff_fields[j].field, xffPrecedence[i], UINT8_MAX) == 0)
+            if (strncasecmp(xff_fields[j].field.c_str(), xffPrecedence[i], UINT8_MAX) == 0)
             {
-                if (!xff_fields[j].value || (xff_fields[j].value[0] == '\0'))
+                if(xff_fields[j].value.empty())
                     return;
 
                 // For a comma-separated list of addresses, pick the last address
                 // FIXIT-L: change to select last address port from 2.9.10-42..not tested
-                xff_addr = new snort::SfIp();
-                char* xff_addr_str = nullptr;
-                char* tmp = strchr(xff_fields[j].value, ',');
-
-                if (tmp)
-                {
-                    xff_addr_str = tmp + 1;
-                }
-                else
-                {
-                    xff_fields[j].value[tmp - xff_fields[j].value] = '\0';
-                    xff_addr_str = xff_fields[j].value;
-                }
 
-                if (xff_addr->set(xff_addr_str) != SFIP_SUCCESS)
-                {
-                    delete xff_addr;
-                    xff_addr = nullptr;
-                }
+                // FIXIT_H: - this code is wrong. We can't have
+                // tmp-xff_fields[j].value when tmp=0.
+
+                // xff_addr = new snort::SfIp();
+                // char* xff_addr_str = nullptr;
+                // char* tmp = strchr(xff_fields[j].value, ',');
+
+                // if (tmp)
+                // {
+                //     xff_addr_str = tmp + 1;
+                // }
+                // else
+                // {
+                //     xff_fields[j].value[tmp - xff_fields[j].value] = '\0';
+                //     xff_addr_str = xff_fields[j].value;
+                // }
+
+                // if (xff_addr->set(xff_addr_str) != SFIP_SUCCESS)
+                // {
+                //     delete xff_addr;
+                //     xff_addr = nullptr;
+                // }
                 break;
             }
         }
@@ -760,23 +767,14 @@ uint16_t AppIdHttpSession::get_cookie_end_offset()
     return http_fields[REQ_COOKIE_FID].end_offset;
 }
 
-static void replace_header_data(std::string& header, const uint8_t* content, int32_t clen)
-{
-    if (clen <= 0)
-        return;
-
-    header.clear();
-    header.append((const char*) content, clen);
-}
-
 void AppIdHttpSession::update_host(const uint8_t* new_host, int32_t len)
 {
-    replace_header_data(host, new_host, len);
+    host.assign((const char*)new_host, len);
 }
 
 void AppIdHttpSession::update_uri(const uint8_t* new_uri, int32_t len)
 {
-    replace_header_data(uri, new_uri, len);
+    uri.assign((const char*)new_uri, len);
 }
 
 void AppIdHttpSession::update_url()
@@ -787,52 +785,52 @@ void AppIdHttpSession::update_url()
 
 void AppIdHttpSession::update_useragent(const uint8_t* new_ua, int32_t len)
 {
-    replace_header_data(useragent, new_ua, len);
+    useragent.assign((const char*)new_ua, len);
 }
 
 void AppIdHttpSession::update_cookie(const uint8_t* new_cookie, int32_t len)
 {
-    replace_header_data(cookie, new_cookie, len);
+    cookie.assign((const char*)new_cookie, len);
 }
 
 void AppIdHttpSession::update_referer(const uint8_t* new_referer, int32_t len)
 {
-    replace_header_data(referer, new_referer, len);
+    referer.assign((const char*)new_referer, len);
 }
 
 void AppIdHttpSession::update_x_working_with(const uint8_t* new_xww, int32_t len)
 {
-    replace_header_data(x_working_with, new_xww, len);
+    x_working_with.assign((const char*)new_xww, len);
 }
 
 void AppIdHttpSession::update_content_type(const uint8_t* new_content_type, int32_t len)
 {
-    replace_header_data(content_type, new_content_type, len);
+    content_type.assign((const char*)new_content_type, len);
 }
 
 void AppIdHttpSession::update_location(const uint8_t* new_location, int32_t len)
 {
-    replace_header_data(location, new_location, len);
+    location.assign((const char*)new_location, len);
 }
 
 void AppIdHttpSession::update_server(const uint8_t* new_server, int32_t len)
 {
-    replace_header_data(server, new_server, len);
+    server.assign((const char*)new_server, len);
 }
 
 void AppIdHttpSession::update_via(const uint8_t* new_via, int32_t len)
 {
-    replace_header_data(via, new_via, len);
+    via.assign((const char*)new_via, len);
 }
 
 void AppIdHttpSession::update_body(const uint8_t* new_body, int32_t len)
 {
-    replace_header_data(body, new_body, len);
+    body.assign((const char*)new_body, len);
 }
 
 void AppIdHttpSession::update_req_body(const uint8_t* new_req_body, int32_t len)
 {
-    replace_header_data(req_body, new_req_body, len);
+    req_body.assign((const char*)new_req_body, len);
 }
 
 void AppIdHttpSession::update_response_code(const char* new_rc)
index e108b554deaa0839aaf51d29efc386737714321d..42c5249399851c481ca11bb1223bebe958c3555a 100644 (file)
 #include <string>
 #include <vector>
 
-#include "application_ids.h"
 #include "flow/flow.h"
 #include "sfip/sf_ip.h"
+#include "appid_types.h"
+#include "application_ids.h"
+#include "http_xff_fields.h"
 
 class AppIdSession;
 class ChpMatchDescriptor;
@@ -48,19 +50,13 @@ struct HttpField
     uint16_t end_offset = 0;
 };
 
-struct XffFieldValue
-{
-    char* field;
-    char* value;
-};
-
 class AppIdHttpSession
 {
 public:
     AppIdHttpSession(AppIdSession&);
     virtual ~AppIdHttpSession();
 
-    int process_http_packet(int);
+    int process_http_packet(AppidSessionDirection direction);
     void update_http_xff_address(struct XffFieldValue* xff_fields, uint32_t numXffFields);
 
     const char* get_user_agent()
index f8ea11912a1c117b169da423ae40338fb76edc5e..6498fd1d17084c7162d30fbc6fdbf359f3312c98 100644 (file)
@@ -50,7 +50,6 @@
 #include "lua_detector_module.h"
 #include "service_plugins/service_discovery.h"
 #include "service_plugins/service_ssl.h"
-#include "thirdparty_appid_utils.h"
 
 using namespace snort;
 static THREAD_LOCAL PacketTracer::TracerMute appid_mute;
@@ -68,7 +67,7 @@ static void add_appid_to_packet_trace(Flow& flow)
     if (session)
     {
         AppId service_id, client_id, payload_id, misc_id;
-        const char *service_app_name, *client_app_name, *payload_app_name, *misc_name;
+        const char* service_app_name, * client_app_name, * payload_app_name, * misc_name;
         session->get_application_ids(service_id, client_id, payload_id, misc_id);
         service_app_name = appid_api.get_application_name(service_id);
         client_app_name = appid_api.get_application_name(client_id);
@@ -163,6 +162,9 @@ void AppIdInspector::tinit()
     appidDebug = new AppIdDebug();
     if (active_config->mod_config and active_config->mod_config->log_all_sessions)
         appidDebug->set_enabled(true);
+#ifdef ENABLE_APPID_THIRD_PARTY
+    active_config->tp_appid_module_tinit();
+#endif
 }
 
 void AppIdInspector::tterm()
@@ -180,6 +182,9 @@ void AppIdInspector::tterm()
     delete HttpPatternMatchers::get_instance();
     delete appidDebug;
     appidDebug = nullptr;
+#ifdef ENABLE_APPID_THIRD_PARTY
+    active_config->tp_appid_module_tterm();
+#endif
 }
 
 void AppIdInspector::eval(Packet* p)
@@ -234,7 +239,7 @@ static void appid_inspector_tterm()
 
 static Inspector* appid_inspector_ctor(Module* m)
 {
-       assert(m);
+    assert(m);
     return new AppIdInspector((AppIdModule&)*m);
 }
 
@@ -304,8 +309,7 @@ int sslAppGroupIdLookup(void*, const char*, const char*, AppId*, AppId*, AppId*)
     if (serverName)
     {
         ssl_scan_hostname((const uint8_t*)serverName, strlen(serverName), client_id,
-            payload_app_id,
-            &get_appid_config()->serviceSslConfig);
+            payload_app_id, &get_appid_config()->serviceSslConfig);
     }
 
     if (ssnptr && (asd = appid_api.get_appid_session(ssnptr)))
index 38e8ef3617c71233fdce27bbaabb17e4e3c73803..c20d2a99c1e1e38551a3b5ac73e92366f020107c 100644 (file)
@@ -73,10 +73,10 @@ static const Parameter s_params[] =
       "enable appid debug logging" },
     { "dump_ports", Parameter::PT_BOOL, nullptr, "false",
       "enable dump of appid port information" },
-#ifdef REMOVED_WHILE_NOT_IN_USE
-    { "thirdparty_appid_dir", Parameter::PT_STRING, nullptr, nullptr,
-      "directory to load thirdparty appid detectors from" },
-#endif
+    { "tp_appid_path", Parameter::PT_STRING, nullptr, nullptr,
+      "path to third party appid dynamic library" },
+    { "tp_appid_config", Parameter::PT_STRING, nullptr, nullptr,
+      "path to third party appid configuration file" },
     { "log_all_sessions", Parameter::PT_BOOL, nullptr, "false",
       "enable logging of all appid sessions" },
     { nullptr, Parameter::PT_MAX, nullptr, nullptr, nullptr }
@@ -236,8 +236,10 @@ bool AppIdModule::set(const char* fqn, Value& v, SnortConfig* c)
         config->app_stats_rollover_time = v.get_long();
     else if ( v.is("app_detector_dir") )
         config->app_detector_dir = snort_strdup(v.get_string());
-    else if ( v.is("thirdparty_appid_dir") )
-        config->thirdparty_appid_dir = snort_strdup(v.get_string());
+    else if ( v.is("tp_appid_path") )
+        config->tp_appid_path = std::string(v.get_string());
+    else if ( v.is("tp_appid_config") )
+        config->tp_appid_config = std::string(v.get_string());
     else if ( v.is("instance_id") )
         config->instance_id = v.get_long();
     else if ( v.is("debug") )
index 7ddec94a52c38c01507661c04e6df780ccc5491b..bf9ec13116eb1a8e7522cdc320c9f853159b778d 100644 (file)
@@ -45,7 +45,9 @@
 #include "appid_stats.h"
 #include "appid_utils/ip_funcs.h"
 #include "service_plugins/service_ssl.h"
-#include "thirdparty_appid_utils.h"
+#ifdef ENABLE_APPID_THIRD_PARTY
+#include "tp_appid_session_api.h"
+#endif
 
 using namespace snort;
 
@@ -68,7 +70,8 @@ const uint8_t* service_strstr(const uint8_t* haystack, unsigned haystack_len,
     return nullptr;
 }
 
-AppIdSession* AppIdSession::allocate_session(const Packet* p, IpProtocol proto, int direction,
+AppIdSession* AppIdSession::allocate_session(const Packet* p, IpProtocol proto,
+    AppidSessionDirection direction,
     AppIdInspector& inspector)
 {
     uint16_t port = 0;
@@ -89,7 +92,7 @@ AppIdSession* AppIdSession::allocate_session(const Packet* p, IpProtocol proto,
 AppIdSession::AppIdSession(IpProtocol proto, const SfIp* ip, uint16_t port,
     AppIdInspector& inspector)
     : FlowData(inspector_id, &inspector), config(inspector.get_appid_config()),
-      protocol(proto), inspector(inspector)
+    protocol(proto), inspector(inspector)
 {
     service_ip.clear();
     session_id = ++appid_flow_data_id;
@@ -97,9 +100,6 @@ AppIdSession::AppIdSession(IpProtocol proto, const SfIp* ip, uint16_t port,
     common.initiator_ip = *ip;
     common.initiator_port = port;
     app_info_mgr = &AppInfoManager::get_instance();
-    if (thirdparty_appid_module)
-        if (!(tpsession = thirdparty_appid_module->session_create()))
-            ErrorMessage("Could not allocate third party session data");
 
     length_sequence.proto = IpProtocol::PROTO_NOT_SET;
     length_sequence.sequence_cnt = 0;
@@ -134,11 +134,13 @@ AppIdSession::~AppIdSession()
         }
     }
 
-    if (thirdparty_appid_module)
+#ifdef ENABLE_APPID_THIRD_PARTY
+    if (tpsession)
     {
-        thirdparty_appid_module->session_delete(tpsession, 0);
+        delete tpsession;
         tpsession = nullptr;
     }
+#endif
 
     delete_session_data();
     free_flow_data();
@@ -243,9 +245,12 @@ void AppIdSession::reinit_session_data()
     client_disco_state = APPID_DISCO_STATE_NONE;
     free_flow_data_by_mask(APPID_SESSION_DATA_CLIENT_MODSTATE_BIT);
 
+#ifdef ENABLE_APPID_THIRD_PARTY
     //3rd party cleaning
-    if (thirdparty_appid_module)
-        thirdparty_appid_module->session_delete(tpsession, 1);
+    if (tpsession)
+        tpsession->reset();
+#endif
+
     init_tpPackets = 0;
     resp_tpPackets = 0;
 
@@ -294,14 +299,15 @@ void AppIdSession::sync_with_snort_protocol_id(AppId newAppId, Packet* p)
         {
             SnortProtocolId tmp_snort_protocol_id = entry->snort_protocol_id;
             // A particular APP_ID_xxx may not be assigned a service_snort_key value
-            // in the rna_app.yaml file entry; so ignore the snort_protocol_id == UNKNOWN_PROTOCOL_ID case.
+            // in the rna_app.yaml file entry; so ignore the snort_protocol_id ==
+            // UNKNOWN_PROTOCOL_ID case.
             if ( tmp_snort_protocol_id == UNKNOWN_PROTOCOL_ID && (newAppId == APP_ID_HTTP2))
                 tmp_snort_protocol_id = snortId_for_http2;
 
             if ( tmp_snort_protocol_id != snort_protocol_id )
             {
                 snort_protocol_id = tmp_snort_protocol_id;
-                if (appidDebug->is_active() && tmp_snort_protocol_id == snortId_for_http2) 
+                if (appidDebug->is_active() && tmp_snort_protocol_id == snortId_for_http2)
                     LogMessage("AppIdDbg %s Telling Snort that it's HTTP/2\n",
                         appidDebug->get_debug_session());
 
@@ -516,7 +522,7 @@ void AppIdSession::set_payload_appid_data(AppId id, char* version)
         return;
 
     if ( app_info_mgr->get_priority(payload.get_id()) > app_info_mgr->get_priority(id) )
-            return;
+        return;
     payload.set_id(id);
     payload.set_version(version);
 }
@@ -576,7 +582,6 @@ void AppIdSession::delete_session_data()
     delete dsession;
 }
 
-
 int AppIdSession::add_flow_data(void* data, unsigned id, AppIdFreeFCN fcn)
 {
     AppIdFlowDataIter it = flow_data.find(id);
@@ -651,7 +656,7 @@ int AppIdSession::add_flow_data_id(uint16_t port, ServiceDetector* service)
     return 0;
 }
 
-void AppIdSession::stop_rna_service_inspection(Packet* p, int direction)
+void AppIdSession::stop_rna_service_inspection(Packet* p, AppidSessionDirection direction)
 {
     if (direction == APP_ID_FROM_INITIATOR)
     {
@@ -683,7 +688,7 @@ AppId AppIdSession::pick_service_app_id()
 
         if (service.get_id() > APP_ID_NONE && !deferred)
             return service.get_id();
-        if (is_third_party_appid_available(tpsession))
+        if (is_third_party_appid_available())
         {
             if (tp_app_id > APP_ID_NONE)
                 return tp_app_id;
@@ -720,7 +725,7 @@ AppId AppIdSession::pick_only_service_app_id()
     if (service.get_id() > APP_ID_NONE && !deferred)
         return service.get_id();
 
-    if (is_third_party_appid_available(tpsession) && tp_app_id > APP_ID_NONE)
+    if (is_third_party_appid_available() && tp_app_id > APP_ID_NONE)
         return tp_app_id;
     else if (deferred)
         return service.get_id();
@@ -812,7 +817,7 @@ AppId AppIdSession::pick_fw_referred_payload_app_id()
 }
 
 void AppIdSession::set_application_ids(AppId service_id, AppId client_id,
-        AppId payload_id, AppId misc_id)
+    AppId payload_id, AppId misc_id)
 {
     application_ids[APP_PROTOID_SERVICE] = service_id;
     application_ids[APP_PROTOID_CLIENT] = client_id;
@@ -821,7 +826,7 @@ void AppIdSession::set_application_ids(AppId service_id, AppId client_id,
 }
 
 void AppIdSession::get_application_ids(AppId& service_id, AppId& client_id,
-        AppId& payload_id, AppId& misc_id)
+    AppId& payload_id, AppId& misc_id)
 {
     service_id = application_ids[APP_PROTOID_SERVICE];
     client_id  = application_ids[APP_PROTOID_CLIENT];
@@ -844,8 +849,10 @@ void AppIdSession::reset_session_data()
     tp_payload_app_id = APP_ID_UNKNOWN;
     tp_app_id = APP_ID_UNKNOWN;
 
-    if (thirdparty_appid_module)
-        thirdparty_appid_module->session_delete(tpsession, 1);
+#ifdef ENABLE_APPID_THIRD_PARTY
+    if (this->tpsession)
+        this->tpsession->reset();
+#endif
 }
 
 bool AppIdSession::is_payload_appid_set()
@@ -858,9 +865,10 @@ void AppIdSession::clear_http_flags()
     if (!get_session_flags(APPID_SESSION_SPDY_SESSION))
     {
         clear_session_flags(APPID_SESSION_CHP_INSPECTING);
-        if (thirdparty_appid_module)
-            thirdparty_appid_module->session_attr_clear(tpsession,
-                TP_ATTR_CONTINUE_MONITORING);
+#ifdef ENABLE_APPID_THIRD_PARTY
+        if (this->tpsession)
+            this->tpsession->clear_attr(TP_ATTR_CONTINUE_MONITORING);
+#endif
     }
 }
 
@@ -877,3 +885,43 @@ AppIdDnsSession* AppIdSession::get_dns_session()
         dsession = new AppIdDnsSession();
     return dsession;
 }
+
+bool AppIdSession::is_third_party_appid_done() const
+{
+#ifdef ENABLE_APPID_THIRD_PARTY
+    if (config->have_tp())
+    {
+        unsigned state;
+
+        if (tpsession)
+            state = tpsession->get_state();
+        else
+            state = TP_STATE_INIT;
+
+        return (state  == TP_STATE_CLASSIFIED || state == TP_STATE_TERMINATED
+               || state == TP_STATE_HA);
+    }
+#endif
+
+    return true;
+}
+
+bool AppIdSession::is_third_party_appid_available() const
+{
+#ifdef ENABLE_APPID_THIRD_PARTY
+    if (config->have_tp())
+    {
+        unsigned state;
+
+        if (tpsession)
+            state = tpsession->get_state();
+        else
+            state = TP_STATE_INIT;
+
+        return (state == TP_STATE_CLASSIFIED || state == TP_STATE_TERMINATED
+               || state == TP_STATE_MONITORING);
+    }
+#endif
+
+    return false;
+}
index 0b7dc550c2564f67387e8c3bf383e88379049495..de7f6590f1657fb38ee0816daabc993572a7d445 100644 (file)
 #include <map>
 #include <string>
 
+#include "detector_plugins/http_url_patterns.h"
 #include "app_info_table.h"
 #include "appid_api.h"
 #include "appid_app_descriptor.h"
+#include "appid_types.h"
 #include "application_ids.h"
 #include "length_app_cache.h"
 #include "service_state.h"
-#include "detector_plugins/http_url_patterns.h"
 
 class ClientDetector;
 class ServiceDetector;
 class AppIdDnsSession;
 class AppIdHttpSession;
+class ThirdPartyAppIDSession;
 
 using AppIdFreeFCN = void (*)(void*);
 
@@ -87,13 +89,6 @@ enum APPID_DISCOVERY_STATE
     APPID_DISCO_STATE_FINISHED
 };
 
-enum APPID_SESSION_DIRECTION
-{
-    APP_ID_FROM_INITIATOR,
-    APP_ID_FROM_RESPONDER,
-    APP_ID_APPID_SESSION_DIRECTION_MAX // Maximum value of a direction (must be last in the list)
-};
-
 class AppIdFlowData
 {
 public:
@@ -128,6 +123,7 @@ struct CommonAppIdData
     uint16_t initiator_port = 0;
 };
 
+// FIXIT-L: make these const strings
 struct TlsSession
 {
     char* tls_host = nullptr;
@@ -144,8 +140,10 @@ public:
     AppIdSession(IpProtocol, const snort::SfIp*, uint16_t port, AppIdInspector&);
     ~AppIdSession() override;
 
-    static AppIdSession* allocate_session(const snort::Packet*, IpProtocol, int, AppIdInspector&);
-    static AppIdSession* create_future_session(const snort::Packet*, const snort::SfIp*, uint16_t, const snort::SfIp*,
+    static AppIdSession* allocate_session(const snort::Packet*, IpProtocol,
+        AppidSessionDirection, AppIdInspector&);
+    static AppIdSession* create_future_session(const snort::Packet*, const snort::SfIp*, uint16_t,
+        const snort::SfIp*,
         uint16_t, IpProtocol, SnortProtocolId, int, AppIdInspector&);
 
     AppIdInspector& get_inspector() const
@@ -196,7 +194,7 @@ public:
 
     TlsSession* tsession = nullptr;
     unsigned scan_flags = 0;
-    void* tpsession = nullptr;
+    ThirdPartyAppIDSession* tpsession = nullptr;
     uint16_t init_tpPackets = 0;
     uint16_t resp_tpPackets = 0;
     bool tp_reinspect_by_initiator = false;
@@ -233,9 +231,9 @@ public:
     static unsigned inspector_id;
     static void init() { inspector_id = FlowData::create_flow_data_id(); }
 
-    void set_session_flags(uint64_t flags){ common.flags |= flags; }
+    void set_session_flags(uint64_t flags) { common.flags |= flags; }
     void clear_session_flags(uint64_t flags) { common.flags &= ~flags; }
-    uint64_t get_session_flags(uint64_t flags) { return (common.flags & flags); }
+    uint64_t get_session_flags(uint64_t flags) const { return (common.flags & flags); }
     void set_service_detected() { common.flags |= APPID_SESSION_SERVICE_DETECTED; }
     bool is_service_detected() { return common.flags & APPID_SESSION_SERVICE_DETECTED; }
     void set_client_detected() { common.flags |= APPID_SESSION_CLIENT_DETECTED; }
@@ -275,7 +273,7 @@ public:
     void update_encrypted_app_id(AppId);
     void examine_rtmp_metadata();
     void sync_with_snort_protocol_id(AppId, snort::Packet*);
-    void stop_rna_service_inspection(snort::Packet*,  int);
+    void stop_rna_service_inspection(snort::Packet*,  AppidSessionDirection);
 
     bool is_payload_appid_set();
     void clear_http_flags();
@@ -284,6 +282,9 @@ public:
     AppIdHttpSession* get_http_session();
     AppIdDnsSession* get_dns_session();
 
+    bool is_third_party_appid_done() const;
+    bool is_third_party_appid_available() const;
+
 private:
     AppIdHttpSession* hsession = nullptr;
     AppIdDnsSession* dsession = nullptr;
diff --git a/src/network_inspectors/appid/appid_types.h b/src/network_inspectors/appid/appid_types.h
new file mode 100644 (file)
index 0000000..614d3f6
--- /dev/null
@@ -0,0 +1,32 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2014-2018 Cisco and/or its affiliates. All rights reserved.
+// Copyright (C) 2005-2013 Sourcefire, Inc.
+//
+// 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.
+//--------------------------------------------------------------------------
+
+// appid_session.h author Sourcefire Inc.
+
+#ifndef APPID_TYPES_H
+#define APPID_TYPES_H
+
+enum AppidSessionDirection
+{
+    APP_ID_FROM_INITIATOR,
+    APP_ID_FROM_RESPONDER,
+    APP_ID_APPID_SESSION_DIRECTION_MAX 
+};
+
+#endif
index 0bc299c546b3c958dd131921e3480c48aa9ab990..bb183c3bac6726e53bb5533ea62c034b1298e97a 100644 (file)
@@ -49,7 +49,6 @@
 #include "detector_plugins/detector_pop3.h"
 #include "detector_plugins/detector_sip.h"
 #include "detector_plugins/detector_smtp.h"
-#include "thirdparty_appid_utils.h"
 
 using namespace snort;
 
@@ -271,7 +270,7 @@ void ClientDiscovery::create_detector_candidates_list(AppIdSession& asd, Packet*
     free_matched_list(&match_list);
 }
 
-int ClientDiscovery::get_detector_candidates_list(AppIdSession& asd, Packet* p, int direction)
+int ClientDiscovery::get_detector_candidates_list(AppIdSession& asd, Packet* p, AppidSessionDirection direction)
 {
     if (direction == APP_ID_FROM_INITIATOR)
     {
@@ -286,7 +285,7 @@ int ClientDiscovery::get_detector_candidates_list(AppIdSession& asd, Packet* p,
     return APPID_SESSION_SUCCESS;
 }
 
-int ClientDiscovery::exec_client_detectors(AppIdSession& asd, Packet* p, int direction)
+int ClientDiscovery::exec_client_detectors(AppIdSession& asd, Packet* p, AppidSessionDirection direction)
 {
     int ret = APPID_INPROCESS;
 
@@ -327,7 +326,7 @@ int ClientDiscovery::exec_client_detectors(AppIdSession& asd, Packet* p, int dir
     return ret;
 }
 
-bool ClientDiscovery::do_client_discovery(AppIdSession& asd, Packet* p, int direction)
+bool ClientDiscovery::do_client_discovery(AppIdSession& asd, Packet* p, AppidSessionDirection direction)
 {
     bool isTpAppidDiscoveryDone = false;
     AppInfoTableEntry* entry;
@@ -342,7 +341,7 @@ bool ClientDiscovery::do_client_discovery(AppIdSession& asd, Packet* p, int dire
     {
         if ( p->flow->get_session_flags() & SSNFLAG_MIDSTREAM )
             asd.client_disco_state = APPID_DISCO_STATE_FINISHED;
-        else if ( is_third_party_appid_available(asd.tpsession)
+        else if ( asd.is_third_party_appid_available()
             && ( asd.tp_app_id > APP_ID_NONE && asd.tp_app_id < SF_APPID_MAX ) )
         {
             //tp has positively identified appId, Dig deeper only if sourcefire
@@ -370,11 +369,11 @@ bool ClientDiscovery::do_client_discovery(AppIdSession& asd, Packet* p, int dire
 
     //stop rna inspection as soon as tp has classified a valid AppId
     if ( ( asd.client_disco_state == APPID_DISCO_STATE_STATEFUL ||
-        asd.client_disco_state == APPID_DISCO_STATE_DIRECT) &&
-        asd.client_disco_state == prevRnaClientState &&
-        !asd.get_session_flags(APPID_SESSION_NO_TPI)  &&
-        is_third_party_appid_available(asd.tpsession) &&
-        asd.tp_app_id > APP_ID_NONE && asd.tp_app_id < SF_APPID_MAX)
+           asd.client_disco_state == APPID_DISCO_STATE_DIRECT) &&
+         asd.client_disco_state == prevRnaClientState &&
+         !asd.get_session_flags(APPID_SESSION_NO_TPI)  &&
+         asd.is_third_party_appid_available() &&
+         asd.tp_app_id > APP_ID_NONE && asd.tp_app_id < SF_APPID_MAX)
     {
         entry = asd.app_info_mgr->get_app_info_entry(asd.tp_app_id);
         if ( !( entry && entry->client_detector
index 7063222065b59d49b9d9ee15ac850f3a1c54b7fe..344a610890f44904b964088af170510c2ae09c78 100644 (file)
@@ -27,6 +27,8 @@
 #include "flow/flow.h"
 #include "log/messages.h"
 
+#include "appid_types.h"
+
 class ClientDetector;
 class AppIdSession;
 
@@ -46,15 +48,15 @@ public:
     static ClientDiscovery& get_instance(AppIdInspector* ins = nullptr);
 
     void finalize_client_plugins();
-    bool do_client_discovery(AppIdSession&, snort::Packet*, int direction);
+    bool do_client_discovery(AppIdSession&, snort::Packet*, AppidSessionDirection direction);
 
 private:
     ClientDiscovery(AppIdInspector& ins);
     void initialize() override;
-    int exec_client_detectors(AppIdSession&, snort::Packet*, int direction);
+    int exec_client_detectors(AppIdSession&, snort::Packet*, AppidSessionDirection direction);
     ClientAppMatch* find_detector_candidates(const snort::Packet* pkt, IpProtocol);
     void create_detector_candidates_list(AppIdSession&, snort::Packet*);
-    int get_detector_candidates_list(AppIdSession&, snort::Packet*, int direction);
+    int get_detector_candidates_list(AppIdSession&, snort::Packet*, AppidSessionDirection direction);
 };
 
 #endif
index d4731ebee3a12d9e2559e67fe8519b5409fcbf8c..ce618dc43f50021699d7ad197a6c779a678f495b 100644 (file)
@@ -478,7 +478,7 @@ int DnsValidator::dns_validate_answer(const uint8_t* data, uint16_t* offset, uin
     return ret;
 }
 
-int DnsValidator::dns_validate_header(const int dir, const DNSHeader* hdr,
+int DnsValidator::dns_validate_header(const AppidSessionDirection dir, const DNSHeader* hdr,
     bool host_reporting, AppIdSession& asd)
 {
     if (hdr->Opcode > MAX_OPCODE || hdr->Opcode == INVALID_OPCODE)
index 89303b3d7c5054cfeed90013f43e3db9cb38bf9c..b648ca01938a3b0ee9ebcab78816075f4ba1ab96 100644 (file)
@@ -46,7 +46,7 @@ public:
         uint16_t id, bool host_reporting, AppIdSession&);
     int dns_validate_answer(const uint8_t* data, uint16_t* offset, uint16_t size,
         uint16_t id, uint8_t rcode, bool host_reporting, AppIdSession&);
-    int dns_validate_header(const int dir, const DNSHeader*, bool host_reporting, AppIdSession&);
+    int dns_validate_header(const AppidSessionDirection dir, const DNSHeader*, bool host_reporting, AppIdSession&);
     int validate_packet(const uint8_t* data, uint16_t size, const int,
         bool host_reporting, AppIdSession&);
 };
index 323003db2620a61d99eb4a0dd5959835bb691717..8bd6d092380199d1eb63d46033a5edd7546f4c22 100644 (file)
@@ -113,7 +113,7 @@ static THREAD_LOCAL KerberosClientDetector* krb_client_detector = nullptr;
 static THREAD_LOCAL KerberosServiceDetector* krb_service_detector = nullptr;
 
 static int krb_walk_server_packet(KRBState* krbs, const uint8_t* s, const uint8_t* end,
-    AppIdSession& asd, snort::Packet* pkt, const int dir, const char* reqCname)
+    AppIdSession& asd, snort::Packet* pkt, const AppidSessionDirection dir, const char* reqCname)
 {
     static const uint8_t KRB_SERVER_VERSION[] = "\x0a0\x003\x002\x001";
     static const uint8_t KRB_SERVER_TYPE[] = "\x0a1\x003\x002\x001";
index d4d42d84f13505ddf2155744c544a0c536484d66..8c45237859e007aec025d517890d5886a799b78d 100644 (file)
@@ -467,7 +467,7 @@ void SipEventHandler::handle(DataEvent& event, Flow* flow)
     {
         const Packet* p = sip_event.get_packet();
         IpProtocol protocol = p->is_tcp() ? IpProtocol::TCP : IpProtocol::UDP;
-        int direction = p->is_from_client() ? APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
+        AppidSessionDirection direction = p->is_from_client() ? APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
         asd = AppIdSession::allocate_session(p, protocol, direction,
             client->get_handler().get_inspector());
     }
@@ -490,7 +490,7 @@ void SipEventHandler::client_handler(SipEvent& sip_event, AppIdSession& asd)
         asd.set_session_flags(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
     }
 
-    int direction = (sip_event.get_packet()->is_from_client()) ?
+    AppidSessionDirection direction = (sip_event.get_packet()->is_from_client()) ?
         APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
 
     if ( sip_event.is_invite() && direction == APP_ID_FROM_INITIATOR )
@@ -540,7 +540,7 @@ void SipEventHandler::service_handler(SipEvent& sip_event, AppIdSession& asd)
     }
 
     ss->serverPkt = 0;
-    int direction = sip_event.get_packet()->is_from_client() ? APP_ID_FROM_INITIATOR :
+    AppidSessionDirection direction = sip_event.get_packet()->is_from_client() ? APP_ID_FROM_INITIATOR :
         APP_ID_FROM_RESPONDER;
 
     if ( direction == APP_ID_FROM_RESPONDER )
diff --git a/src/network_inspectors/appid/http_xff_fields.h b/src/network_inspectors/appid/http_xff_fields.h
new file mode 100644 (file)
index 0000000..f840c5b
--- /dev/null
@@ -0,0 +1,43 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2014-2018 Cisco and/or its affiliates. All rights reserved.
+// Copyright (C) 2005-2013 Sourcefire, Inc.
+//
+// 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.
+//--------------------------------------------------------------------------
+                                                                            
+// http_xff_fields.h author Sourcefire Inc.                                
+#ifndef HTTP_XFF_FIELDS_H
+#define HTTP_XFF_FIELDS_H
+
+#include <string>
+
+// FIXIT-L refactor
+#define HTTP_XFF_FIELD_X_FORWARDED_FOR  "X-Forwarded-For"
+#define HTTP_XFF_FIELD_TRUE_CLIENT_IP   "True-Client-IP"
+/* #define HTTP_MAX_XFF_FIELDS             8 */
+/* #define HTTP_XFF_FIELD_X_FORWARDED_FOR "" */
+/* #define HTTP_XFF_FIELD_TRUE_CLIENT_IP "" */
+
+#define HTTP_MAX_XFF_FIELDS 8
+
+struct XffFieldValue
+{
+    std::string field;
+    std::string value;
+};
+
+
+#endif
index 0e5df2f7dba91acaa0562ae34986183b4a5593f0..05c3d5c864c89d0afdacd553583898696d3db02d 100644 (file)
@@ -22,8 +22,9 @@
 #ifndef LENGTH_APP_CACHE_H
 #define LENGTH_APP_CACHE_H
 
-#include "application_ids.h"
 #include "protocols/protocol_ids.h"
+#include "appid_types.h"
+#include "application_ids.h"
 
 #define LENGTH_SEQUENCE_CNT_MAX (5)
 
@@ -34,7 +35,7 @@ enum class IpProtocol : uint8_t;
 
 struct LengthSequenceEntry
 {
-    uint8_t direction = 0;     /* APP_ID_FROM_INITIATOR or APP_ID_FROM_RESPONDER */
+    AppidSessionDirection direction = APP_ID_FROM_INITIATOR;
     uint16_t length = 0;       /* payload size (bytes) */
 };
 
index a7ea071c3eac0963b314c75996770fb3023209a6..9f23efb8feb083692e39e3994568d23b87a277be 100644 (file)
@@ -284,7 +284,8 @@ static int service_analyze_payload(lua_State* L)
 }
 
 // FIXIT-M - the comments and code below for service_get_service_id don't appear to be useful
-//           the ud->server.service_id field is set to APP_ID_UNKNOWN at init time and never updated
+//           the ud->server.service_id field is set to APP_ID_UNKNOWN at init time and never
+// updated
 //           is this function ever used?
 /**design: don't store service_id in detector structure since a single detector
  * can get service_id for multiple protocols. For example SIP which gets Id for RTP and
@@ -930,7 +931,7 @@ static int detector_add_http_pattern(lua_State* L)
     const uint8_t* pattern_str = (const uint8_t*)lua_tolstring(L, ++index, &pattern_size);
     uint32_t app_id = lua_tointeger(L, ++index);
     DetectorHTTPPattern pattern;
-    if( pattern.init(pattern_str, pattern_size, seq, service_id, client_id,
+    if ( pattern.init(pattern_str, pattern_size, seq, service_id, client_id,
         payload_id, app_id) )
     {
         HttpPatternMatchers::get_instance()->insert_http_pattern(pat_type, pattern);
@@ -1299,7 +1300,6 @@ static int detector_add_chp_action(lua_State* L)
     auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, index);
     ud->validate_lua_state(false);
 
-
     // Parameter 1
     AppId appId = lua_tointeger(L, ++index);
     AppId appIdInstance = CHP_APPID_SINGLE_INSTANCE(appId); // Last instance for the old API
@@ -1864,7 +1864,7 @@ static int add_http_pattern(lua_State* L)
     size_t pattern_size = 0;
     const uint8_t* pattern_str = (const uint8_t*)lua_tolstring(L, ++index, &pattern_size);
     DetectorHTTPPattern pattern;
-    if( pattern.init(pattern_str, pattern_size, seq, service_id, client_id,
+    if ( pattern.init(pattern_str, pattern_size, seq, service_id, client_id,
         payload_id, APP_ID_NONE) )
     {
         HttpPatternMatchers::get_instance()->insert_http_pattern(pat_type, pattern);
@@ -2151,12 +2151,25 @@ static const luaL_Reg detector_methods[] =
 {
     /* Obsolete API names.  No longer use these!  They are here for backward
      * compatibility and will eventually be removed. */
-    { "memcmp",                   detector_memcmp },                 //  - "memcmp" is now "matchSimplePattern" (below)
-    { "getProtocolType",          detector_get_protocol_type },      //  - "getProtocolType" is now "getL4Protocol" (below)
-    { "inCompatibleData",         service_set_incompatible_data },   //  - "inCompatibleData" is now "markIncompleteData" (below)
-    { "addDataId",                service_add_data_id },             //  - "addDataId" is now "addAppIdDataToFlow" (below)
-    { "service_inCompatibleData", service_set_incompatible_data },   //  - "service_inCompatibleData" is now "service_markIncompleteData" (below)
-    { "service_addDataId",        service_add_data_id },             //  - "service_addDataId" is now "service_addAppIdDataToFlow" (below)
+    { "memcmp",                   detector_memcmp },                 //  - "memcmp" is now
+                                                                     // "matchSimplePattern"
+                                                                     // (below)
+    { "getProtocolType",          detector_get_protocol_type },      //  - "getProtocolType" is now
+                                                                     // "getL4Protocol" (below)
+    { "inCompatibleData",         service_set_incompatible_data },   //  - "inCompatibleData" is
+                                                                     // now "markIncompleteData"
+                                                                     // (below)
+    { "addDataId",                service_add_data_id },             //  - "addDataId" is now
+                                                                     // "addAppIdDataToFlow"
+                                                                     // (below)
+    { "service_inCompatibleData", service_set_incompatible_data },   //  - "service_inCompatibleData"
+                                                                     // is now
+                                                                     // "service_markIncompleteData"
+                                                                     // (below)
+    { "service_addDataId",        service_add_data_id },             //  - "service_addDataId" is
+                                                                     // now
+                                                                     // "service_addAppIdDataToFlow"
+                                                                     // (below)
 
     { "getPacketSize",            detector_get_packet_size },
     { "getPacketDir",             detector_get_packet_direction },
@@ -2379,14 +2392,15 @@ int LuaStateDescriptor::lua_validate(AppIdDiscoveryArgs& args)
     return rc;
 }
 
-static inline void init_lsd(LuaStateDescriptor* lsd, const std::string& detector_name, lua_State* L)
+static inline void init_lsd(LuaStateDescriptor* lsd, const std::string& detector_name,
+    lua_State* L)
 {
-       lsd->service_id = APP_ID_UNKNOWN;
-       get_lua_field(L, -1, "init", lsd->package_info.initFunctionName);
-       get_lua_field(L, -1, "clean", lsd->package_info.cleanFunctionName);
-       get_lua_field(L, -1, "validate", lsd->package_info.validateFunctionName);
-       get_lua_field(L, -1, "minimum_matches", lsd->package_info.minimum_matches);
-       lsd->package_info.name = detector_name;
+    lsd->service_id = APP_ID_UNKNOWN;
+    get_lua_field(L, -1, "init", lsd->package_info.initFunctionName);
+    get_lua_field(L, -1, "clean", lsd->package_info.cleanFunctionName);
+    get_lua_field(L, -1, "validate", lsd->package_info.validateFunctionName);
+    get_lua_field(L, -1, "minimum_matches", lsd->package_info.minimum_matches);
+    lsd->package_info.name = detector_name;
     lua_pop(L, 1);    // pop client table
     lua_pop(L, 1);    // pop DetectorPackageInfo table
     lsd->my_lua_state = L;
@@ -2394,21 +2408,21 @@ static inline void init_lsd(LuaStateDescriptor* lsd, const std::string& detector
 
 static inline bool lua_params_validator(LuaDetectorParameters& ldp, bool packet_context)
 {
-       if ( packet_context )
-       {
-               assert(ldp.asd);
-               assert(ldp.pkt);
-       }
-       else
-       {
-               assert(!ldp.pkt);
-       }
+    if ( packet_context )
+    {
+        assert(ldp.asd);
+        assert(ldp.pkt);
+    }
+    else
+    {
+        assert(!ldp.pkt);
+    }
 
 #ifdef NDEBUG
     UNUSED(ldp);
 #endif
 
-       return true;
+    return true;
 }
 
 LuaServiceDetector::LuaServiceDetector(AppIdDiscovery* sdm, const std::string& detector_name,
@@ -2418,7 +2432,7 @@ LuaServiceDetector::LuaServiceDetector(AppIdDiscovery* sdm, const std::string& d
     name = detector_name;
     proto = protocol;
     handler->register_detector(name, this, proto);
-       init_lsd(&lsd, detector_name, L);
+    init_lsd(&lsd, detector_name, L);
     UserData<AppIdDetector>::push(L, DETECTOR, this);
     // add a lua reference so the detector doesn't get garbage-collected
     lua_pushvalue(L, -1);
@@ -2427,8 +2441,8 @@ LuaServiceDetector::LuaServiceDetector(AppIdDiscovery* sdm, const std::string& d
 
 LuaStateDescriptor* LuaServiceDetector::validate_lua_state(bool packet_context)
 {
-       lua_params_validator(lsd.ldp, packet_context);
-       return &lsd;
+    lua_params_validator(lsd.ldp, packet_context);
+    return &lsd;
 }
 
 int LuaServiceDetector::validate(AppIdDiscoveryArgs& args)
@@ -2438,22 +2452,22 @@ int LuaServiceDetector::validate(AppIdDiscoveryArgs& args)
 
 LuaClientDetector::LuaClientDetector(AppIdDiscovery* cdm, const std::string& detector_name,
     IpProtocol protocol, lua_State* L)
- {
-     handler = cdm;
-     name = detector_name;
-     proto = protocol;
-     handler->register_detector(name, this, proto);
-     init_lsd(&lsd, detector_name, L);
-     UserData<AppIdDetector>::push(L, DETECTOR, this);
-     // add a lua reference so the detector doesn't get garbage-collected
-     lua_pushvalue(L, -1);
-     lsd.detector_user_data_ref = luaL_ref(L, LUA_REGISTRYINDEX);
- }
+{
+    handler = cdm;
+    name = detector_name;
+    proto = protocol;
+    handler->register_detector(name, this, proto);
+    init_lsd(&lsd, detector_name, L);
+    UserData<AppIdDetector>::push(L, DETECTOR, this);
+    // add a lua reference so the detector doesn't get garbage-collected
+    lua_pushvalue(L, -1);
+    lsd.detector_user_data_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+}
 
 LuaStateDescriptor* LuaClientDetector::validate_lua_state(bool packet_context)
 {
-       lua_params_validator(lsd.ldp, packet_context);
-       return &lsd;
+    lua_params_validator(lsd.ldp, packet_context);
+    return &lsd;
 }
 
 int LuaClientDetector::validate(AppIdDiscoveryArgs& args)
index 36f7f3e201837526f17412f36db3cd75a6cd0673..8a408dd5784cde0aaf6652ca5611629b8efae08f 100644 (file)
@@ -66,7 +66,7 @@ struct LuaDetectorParameters
 
     const uint8_t* data = nullptr;
     uint16_t size = 0;
-    int dir = 0;
+    AppidSessionDirection dir = APP_ID_FROM_INITIATOR;
     AppIdSession* asd;
     snort::Packet* pkt = nullptr;
     uint8_t macAddress[6] = { 0 };
@@ -75,7 +75,7 @@ struct LuaDetectorParameters
 class LuaStateDescriptor
 {
 public:
-       LuaStateDescriptor() = default;
+    LuaStateDescriptor() = default;
     virtual ~LuaStateDescriptor();
 
     LuaDetectorParameters ldp;
@@ -91,7 +91,7 @@ class LuaServiceDetector : public ServiceDetector
 {
 public:
     LuaServiceDetector(AppIdDiscovery* sdm, const std::string& detector_name, IpProtocol protocol,
-            lua_State* L);
+        lua_State* L);
     int validate(AppIdDiscoveryArgs&) override;
     LuaStateDescriptor* validate_lua_state(bool packet_context) override;
 
index 44e598a1257f6472529d6ffe6786c47c05664074..678a5376130f6aa252a0181f85ecb140656191ae 100644 (file)
@@ -210,7 +210,7 @@ static int create_detector_flow(lua_State* L)
     LuaDetectorManager::add_detector_flow(detector_flow);
 
     detector_flow->asd = AppIdSession::create_future_session(lsd->ldp.pkt, &saddr, sport,
-               &daddr, dport, proto, 0, 0, ud->get_handler().get_inspector());
+        &daddr, dport, proto, 0, 0, ud->get_handler().get_inspector());
 
     if (!detector_flow->asd)
     {
index 09cb9087e554cd7e7ece76e7105f89cd6908fd70..5a4241f4a82e2bd20b25c5ebb3978b185e43f5cf 100644 (file)
@@ -64,7 +64,7 @@ void ServiceDetector::register_appid(AppId appId, unsigned extractsInfo)
     pEntry->flags |= extractsInfo;
 }
 
-int ServiceDetector::service_inprocess(AppIdSession& asd, const Packet* pkt, int dir)
+int ServiceDetector::service_inprocess(AppIdSession& asd, const Packet* pkt, AppidSessionDirection dir)
 {
     if (dir == APP_ID_FROM_INITIATOR ||
         asd.get_session_flags(APPID_SESSION_IGNORE_HOST | APPID_SESSION_UDP_REVERSED))
@@ -80,7 +80,7 @@ int ServiceDetector::service_inprocess(AppIdSession& asd, const Packet* pkt, int
     return APPID_SUCCESS;
 }
 
-int ServiceDetector::update_service_data(AppIdSession& asd, const Packet* pkt, int dir, AppId appId,
+int ServiceDetector::update_service_data(AppIdSession& asd, const Packet* pkt, AppidSessionDirection dir, AppId appId,
     const char* vendor, const char* version)
 {
     uint16_t port = 0;
@@ -132,15 +132,16 @@ int ServiceDetector::update_service_data(AppIdSession& asd, const Packet* pkt, i
     return APPID_SUCCESS;
 }
 
-int ServiceDetector::add_service_consume_subtype(AppIdSession& asd, const Packet* pkt, int dir,
-    AppId appId, const char* vendor, const char* version, AppIdServiceSubtype* subtype)
+int ServiceDetector::add_service_consume_subtype(AppIdSession& asd, const Packet* pkt,
+    AppidSessionDirection dir, AppId appId, const char* vendor, const char* version,
+    AppIdServiceSubtype* subtype)
 {
     asd.subtype = subtype;
     return update_service_data(asd, pkt, dir, appId, vendor, version);
 }
 
-int ServiceDetector::add_service(AppIdSession& asd, const Packet* pkt, int dir, AppId appId,
-    const char* vendor, const char* version, const AppIdServiceSubtype* subtype)
+int ServiceDetector::add_service(AppIdSession& asd, const Packet* pkt, AppidSessionDirection dir,
+    AppId appId, const char* vendor, const char* version, const AppIdServiceSubtype* subtype)
 {
     AppIdServiceSubtype* new_subtype = nullptr;
 
@@ -164,18 +165,18 @@ int ServiceDetector::add_service(AppIdSession& asd, const Packet* pkt, int dir,
     return update_service_data(asd, pkt, dir, appId, vendor, version);
 }
 
-int ServiceDetector::incompatible_data(AppIdSession& asd, const Packet* pkt, int dir)
+int ServiceDetector::incompatible_data(AppIdSession& asd, const Packet* pkt, AppidSessionDirection dir)
 {
     return static_cast<ServiceDiscovery*>(handler)->incompatible_data(asd, pkt, dir, this);
 }
 
-int ServiceDetector::fail_service(AppIdSession& asd, const Packet* pkt, int dir)
+int ServiceDetector::fail_service(AppIdSession& asd, const Packet* pkt, AppidSessionDirection dir)
 {
     return static_cast<ServiceDiscovery*>(handler)->fail_service(asd, pkt, dir, this);
 }
 
 void ServiceDetector::initialize_expected_session(AppIdSession& parent, AppIdSession& expected,
-    uint64_t flags, APPID_SESSION_DIRECTION dir)
+    uint64_t flags, AppidSessionDirection dir)
 {
     if (dir == APP_ID_FROM_INITIATOR)
     {
index 93733181e5105dac6c78148a760c7eba742734e1..f772193bf359165d3e3a2f3c11990f72e40173ee 100644 (file)
@@ -34,13 +34,13 @@ public:
 
     void do_custom_init() override { }
     void register_appid(AppId, unsigned extractsInfo) override;
-    int service_inprocess(AppIdSession&, const snort::Packet*, int dir);
-    int add_service(AppIdSession&, const snort::Packet*, int dir, AppId, const char* vendor = nullptr,
+    int service_inprocess(AppIdSession&, const snort::Packet*, AppidSessionDirection dir);
+    int add_service(AppIdSession&, const snort::Packet*, AppidSessionDirection dir, AppId, const char* vendor = nullptr,
         const char* version = nullptr, const snort::AppIdServiceSubtype* = nullptr);
-    int add_service_consume_subtype(AppIdSession&, const snort::Packet*, int dir, AppId,
+    int add_service_consume_subtype(AppIdSession&, const snort::Packet*, AppidSessionDirection dir, AppId,
         const char* vendor, const char* version, snort::AppIdServiceSubtype*);
-    int incompatible_data(AppIdSession&, const snort::Packet*, int dir);
-    int fail_service(AppIdSession&, const snort::Packet*, int dir);
+    int incompatible_data(AppIdSession&, const snort::Packet*, AppidSessionDirection dir);
+    int fail_service(AppIdSession&, const snort::Packet*, AppidSessionDirection dir);
 
     void add_host_info(AppIdSession&, SERVICE_HOST_INFO_CODE, const void*)
     {
@@ -52,10 +52,10 @@ public:
         asd.misc_app_id = miscId;
     }
 
-    void initialize_expected_session(AppIdSession&, AppIdSession&, uint64_t flags, APPID_SESSION_DIRECTION dir);
+    void initialize_expected_session(AppIdSession&, AppIdSession&, uint64_t flags, AppidSessionDirection dir);
 
 private:
-    int update_service_data(AppIdSession&, const snort::Packet*, int dir, AppId, const char* vendor,
+    int update_service_data(AppIdSession&, const snort::Packet*, AppidSessionDirection dir, AppId, const char* vendor,
         const char* version);
 };
 #endif
index ae1f46adf13c4aeb2bbc0c81f45c944bf95d0f97..8ea469bb92900d07cd10ce4e1ae4898a629e82d8 100644 (file)
@@ -116,7 +116,7 @@ int DirectConnectServiceDetector::validate(AppIdDiscoveryArgs& args)
         return udp_validate(data, size, args.dir, args.asd, args.pkt, fd);
 }
 
-int DirectConnectServiceDetector::tcp_validate(const uint8_t* data, uint16_t size, const int dir,
+int DirectConnectServiceDetector::tcp_validate(const uint8_t* data, uint16_t size, const AppidSessionDirection dir,
     AppIdSession& asd, const Packet* pkt, ServiceData* serviceData)
 {
     switch (serviceData->state)
@@ -222,7 +222,7 @@ fail:
     return APPID_NOMATCH;
 }
 
-int DirectConnectServiceDetector::udp_validate(const uint8_t* data, uint16_t size, const int dir,
+int DirectConnectServiceDetector::udp_validate(const uint8_t* data, uint16_t size, const AppidSessionDirection dir,
     AppIdSession& asd, const Packet* pkt, ServiceData* serviceData)
 {
     if (dir == APP_ID_FROM_RESPONDER && serviceData->state == CONN_STATE_SERVICE_DETECTED)
index 9f060a2e6ebb772686374e5b3230120a512bc616..7befc565eb4d4888ae18d07f299c95f5786eaa34 100644 (file)
@@ -36,9 +36,9 @@ public:
     int validate(AppIdDiscoveryArgs&) override;
 
 private:
-    int tcp_validate(const uint8_t* data, uint16_t size, const int dir, AppIdSession&,
+    int tcp_validate(const uint8_t* data, uint16_t size, const AppidSessionDirection dir, AppIdSession&,
         const snort::Packet*, ServiceData*);
-    int udp_validate(const uint8_t* data, uint16_t size, const int dir, AppIdSession&,
+    int udp_validate(const uint8_t* data, uint16_t size, const AppidSessionDirection dir, AppIdSession&,
         const snort::Packet*, ServiceData*);
 };
 
index 04fcd36ed2028d53cbefa3f75613371eff962607..d639d91f9ca9caa17985657978ea102943054adf 100644 (file)
 #include "service_tftp.h"
 #include "service_timbuktu.h"
 #include "service_tns.h"
-#include "thirdparty_appid_utils.h"
 
 #ifdef REG_TEST
 #include "service_regtest.h"
 #endif
 
+#ifdef ENABLE_APPID_THIRD_PARTY
+#include "tp_appid_session_api.h"
+#endif
+
 using namespace snort;
 
 static THREAD_LOCAL ServiceDetector* ftp_service = nullptr;
@@ -346,7 +349,7 @@ void ServiceDiscovery::get_port_based_services(IpProtocol protocol, uint16_t por
  * been specified (service_detector).  Basically, this function handles going
  * through the main port/pattern search (and returning which detector to add
  * next to the list of detectors to try (even if only 1)). */
-void ServiceDiscovery::get_next_service(const Packet* p, const int dir, AppIdSession& asd)
+void ServiceDiscovery::get_next_service(const Packet* p, const AppidSessionDirection dir, AppIdSession& asd)
 {
     auto proto = asd.protocol;
 
@@ -394,7 +397,7 @@ void ServiceDiscovery::get_next_service(const Packet* p, const int dir, AppIdSes
     }
 }
 
-int ServiceDiscovery::identify_service(AppIdSession& asd, Packet* p, int dir)
+int ServiceDiscovery::identify_service(AppIdSession& asd, Packet* p, AppidSessionDirection dir)
 {
     ServiceDiscoveryState* sds = nullptr;
     bool got_brute_force = false;
@@ -562,7 +565,7 @@ int ServiceDiscovery::add_ftp_service_state(AppIdSession& asd)
     return asd.add_flow_data_id(21, ftp_service);
 }
 
-bool ServiceDiscovery::do_service_discovery(AppIdSession& asd, Packet* p, int direction)
+bool ServiceDiscovery::do_service_discovery(AppIdSession& asd, Packet* p, AppidSessionDirection direction)
 {
     bool isTpAppidDiscoveryDone = false;
 
@@ -593,7 +596,7 @@ bool ServiceDiscovery::do_service_discovery(AppIdSession& asd, Packet* p, int di
                 asd.service_disco_state = APPID_DISCO_STATE_FINISHED;
             }
         }
-        else if (is_third_party_appid_available(asd.tpsession))
+        else if (asd.is_third_party_appid_available())
         {
             if (asd.tp_app_id > APP_ID_NONE)
             {
@@ -623,10 +626,10 @@ bool ServiceDiscovery::do_service_discovery(AppIdSession& asd, Packet* p, int di
 
     //stop rna inspection as soon as tp has classified a valid AppId later in the session
     if ( asd.service_disco_state == APPID_DISCO_STATE_STATEFUL &&
-        prevRnaServiceState == APPID_DISCO_STATE_STATEFUL &&
-        !asd.get_session_flags(APPID_SESSION_NO_TPI) &&
-        is_third_party_appid_available(asd.tpsession) &&
-        asd.tp_app_id > APP_ID_NONE && asd.tp_app_id < SF_APPID_MAX)
+         prevRnaServiceState == APPID_DISCO_STATE_STATEFUL &&
+         !asd.get_session_flags(APPID_SESSION_NO_TPI) &&
+         asd.is_third_party_appid_available() &&
+         asd.tp_app_id > APP_ID_NONE && asd.tp_app_id < SF_APPID_MAX)
     {
         AppInfoTableEntry* entry = asd.app_info_mgr->get_app_info_entry(asd.tp_app_id);
         if ( entry && entry->service_detector &&
@@ -660,7 +663,10 @@ bool ServiceDiscovery::do_service_discovery(AppIdSession& asd, Packet* p, int di
             asd.stop_rna_service_inspection(p, direction);
             asd.service_disco_state = APPID_DISCO_STATE_FINISHED;
             //  - Shut down TP.
-            thirdparty_appid_module->session_state_set(asd.tpsession, TP_STATE_TERMINATED);
+
+#ifdef ENABLE_APPID_THIRD_PARTY
+            asd.tpsession->set_state(TP_STATE_TERMINATED);
+#endif
             //  - Just ignore everything from now on.
             asd.set_session_flags(APPID_SESSION_IGNORE_FLOW);
         }
@@ -707,7 +713,7 @@ bool ServiceDiscovery::do_service_discovery(AppIdSession& asd, Packet* p, int di
  * client ultimately we will have to fail the service. If the same behavior is seen from different
  * clients going to same service then this most likely the service is something else.
  */
-int ServiceDiscovery::incompatible_data(AppIdSession& asd, const Packet* pkt, int dir,
+int ServiceDiscovery::incompatible_data(AppIdSession& asd, const Packet* pkt, AppidSessionDirection dir,
     ServiceDetector* service)
 {
     if (service)
@@ -744,7 +750,7 @@ int ServiceDiscovery::incompatible_data(AppIdSession& asd, const Packet* pkt, in
     return APPID_SUCCESS;
 }
 
-int ServiceDiscovery::fail_service(AppIdSession& asd, const Packet* pkt, int dir,
+int ServiceDiscovery::fail_service(AppIdSession& asd, const Packet* pkt, AppidSessionDirection dir,
     ServiceDetector* service, ServiceDiscoveryState* sds)
 {
     if ( service )
index ce368077454f531f200c3fe888ef6d6fcd9b4029..7d2728be53392803263e6519b53cf8c3022080d2 100644 (file)
@@ -31,6 +31,8 @@
 #include "log/messages.h"
 #include "utils/sflsq.h"
 
+#include "appid_types.h"
+
 class AppIdConfig;
 class AppIdSession;
 class ServiceDetector;
@@ -75,17 +77,16 @@ public:
     ServiceDetector* get_next_tcp_detector(AppIdDetectorsIterator&);
     ServiceDetector* get_next_udp_detector(AppIdDetectorsIterator&);
 
-    bool do_service_discovery(AppIdSession&, snort::Packet*, int);
-    int identify_service(AppIdSession&, snort::Packet*, int dir);
-    int fail_service(AppIdSession&, const snort::Packet*, int dir, ServiceDetector*,
-        ServiceDiscoveryState* sds = nullptr);
-    int incompatible_data(AppIdSession&, const snort::Packet*, int dir, ServiceDetector*);
+    bool do_service_discovery(AppIdSession&, snort::Packet*, AppidSessionDirection dir);
+    int identify_service(AppIdSession&, snort::Packet*, AppidSessionDirection dir);
+    int fail_service(AppIdSession&, const snort::Packet*, AppidSessionDirection dir, ServiceDetector*, ServiceDiscoveryState* sds = nullptr);
+    int incompatible_data(AppIdSession&, const snort::Packet*, AppidSessionDirection dir, ServiceDetector*);
     static int add_ftp_service_state(AppIdSession&);
 
 private:
     ServiceDiscovery(AppIdInspector& ins);
     void initialize() override;
-    void get_next_service(const snort::Packet*, const int dir, AppIdSession&);
+    void get_next_service(const snort::Packet*, const AppidSessionDirection dir, AppIdSession&);
     void get_port_based_services(IpProtocol, uint16_t port, AppIdSession&);
     void match_by_pattern(AppIdSession&, const snort::Packet*, IpProtocol);
 
index 892a2c8ac958891272dc6dffa6168e86f5aa2ba4..cb66a9463ce56ef7c5b92afb0ce025dde5556bea 100644 (file)
@@ -796,7 +796,7 @@ static inline void WatchForCommandResult(ServiceFTPData* fd, AppIdSession& asd,
 
 void FtpServiceDetector::create_expected_session(AppIdSession& asd, const Packet* pkt, const SfIp* cliIp,
     uint16_t cliPort, const SfIp* srvIp, uint16_t srvPort, IpProtocol proto,
-    int flags, APPID_SESSION_DIRECTION dir)
+    int flags, AppidSessionDirection dir)
 {
     if(ftp_data_snort_protocol_id == UNKNOWN_PROTOCOL_ID)
         ftp_data_snort_protocol_id = SnortConfig::get_conf()->proto_ref->find("ftp-data");
index 3b867e551149effed740f0708da2117bc9bac2c6..7bd6283614c6d1c9196113f4d2c41c7f91c7d7c0 100644 (file)
@@ -36,7 +36,7 @@ public:
 private:
     void create_expected_session(AppIdSession& asd,const snort::Packet* pkt,
         const snort::SfIp* cliIp, uint16_t cliPort, const snort::SfIp* srvIp,
-        uint16_t srvPort, IpProtocol proto, int flags, APPID_SESSION_DIRECTION dir);
+        uint16_t srvPort, IpProtocol proto, int flags, AppidSessionDirection dir);
 
     SnortProtocolId ftp_data_snort_protocol_id = UNKNOWN_PROTOCOL_ID;
 };
index 6624f028e3623ad8ecae2330a85d7c8c80deafd6..76f2c17a726fcacb37c54177a0392bfba52b0752 100644 (file)
@@ -463,7 +463,7 @@ int NbnsServiceDetector::validate(AppIdDiscoveryArgs& args)
     const uint8_t* begin;
     const uint8_t* end;
     const uint8_t* data = args.data;
-    const int dir = args.dir;
+    const AppidSessionDirection dir = args.dir;
     uint16_t size = args.size;
 
     if (!size)
@@ -795,7 +795,7 @@ int NbssServiceDetector::validate(AppIdDiscoveryArgs& args)
     uint32_t tmp;
     int retval = -1;
     const uint8_t* data = args.data;
-    const int dir = args.dir;
+    const AppidSessionDirection dir = args.dir;
     uint16_t size = args.size;
 
     if (dir != APP_ID_FROM_RESPONDER)
@@ -1043,7 +1043,7 @@ int NbdgmServiceDetector::validate(AppIdDiscoveryArgs& args)
     AppId serviceAppId = APP_ID_NETBIOS_DGM;
     AppId miscAppId = APP_ID_NONE;
     const uint8_t* data = args.data;
-    const int dir = args.dir;
+    const AppidSessionDirection dir = args.dir;
     uint16_t size = args.size;
 
     if (!size)
index c2b0eaa4aeacbef919ad1a1913a74ef0d37cb093..7448ffdb1be7e2ecb465bf52e6768227d5862884 100644 (file)
@@ -272,7 +272,7 @@ static const RPCProgram* FindRPCProgram(uint32_t program)
     return rpc;
 }
 
-int RpcServiceDetector::validate_packet(const uint8_t* data, uint16_t size, int dir,
+int RpcServiceDetector::validate_packet(const uint8_t* data, uint16_t size, AppidSessionDirection dir,
     AppIdSession& asd, Packet* pkt, ServiceRPCData* rd, const char** pname, uint32_t* program)
 {
     const ServiceRPCCall* call = nullptr;
@@ -463,7 +463,7 @@ int RpcServiceDetector::rpc_udp_validate(AppIdDiscoveryArgs& args)
     int rval;
     const uint8_t* data = args.data;
     Packet* pkt = args.pkt;
-    const int dir = args.dir;
+    const AppidSessionDirection dir = args.dir;
     uint16_t size = args.size;
 
     if (!size)
@@ -553,7 +553,7 @@ int RpcServiceDetector::rpc_tcp_validate(AppIdDiscoveryArgs& args)
     const char* pname = nullptr;
     const uint8_t* data = args.data;
     Packet* pkt = args.pkt;
-    const int dir = args.dir;
+    const AppidSessionDirection dir = args.dir;
     uint16_t size = args.size;
 
     if (!size)
index fdd63b3b08ee6191a89910468a3dfcba9fc33254..9b0fa46cae1f0db569aa5b22ab74f9d9cd859d7d 100644 (file)
@@ -39,7 +39,7 @@ public:
 private:
     int rpc_udp_validate(AppIdDiscoveryArgs&);
     int rpc_tcp_validate(AppIdDiscoveryArgs&);
-    int validate_packet(const uint8_t* data, uint16_t size, int dir, AppIdSession&,
+    int validate_packet(const uint8_t* data, uint16_t size, AppidSessionDirection dir, AppIdSession&,
         snort::Packet*, ServiceRPCData*, const char** pname, uint32_t* program);
     SnortProtocolId sunrpc_snort_protocol_id = UNKNOWN_PROTOCOL_ID;
 };
index 02ce122b3780acf0267175e94cf6168564b614b6..91eef3598b9e3ec3f06ba3df825e6014e4d45edd 100644 (file)
@@ -1,10 +1,6 @@
-
 add_library(appid_cpputest_deps OBJECT ../appid_peg_counts.cc ../../../sfip/sf_ip.cc ../../../utils/util_cstring.cc)
-include_directories ( appid PRIVATE ${APPID_INCLUDE_DIR} )
 
-# add_cpputest( app_info_table_test
-#     SOURCES $<TARGET_OBJECTS:appid_cpputest_deps>
-# )
+include_directories ( appid PRIVATE ${APPID_INCLUDE_DIR} )
 
 add_cpputest( appid_api_test
     SOURCES $<TARGET_OBJECTS:appid_cpputest_deps>
@@ -30,3 +26,19 @@ add_cpputest( service_state_test
     SOURCES $<TARGET_OBJECTS:appid_cpputest_deps>
 )
 
+if ( ENABLE_APPID_THIRD_PARTY )
+  add_library(tp_mock MODULE tp_mock.cc)
+
+  add_cpputest( tp_lib_handler_test
+    SOURCES tp_lib_handler_test.cc
+    ../tp_lib_handler.cc
+    LIBS dl
+    )
+
+  add_cpputest( tp_appid_types_test
+    SOURCES tp_appid_types_test.cc
+    )
+
+  set_property(TARGET tp_mock PROPERTY ENABLE_EXPORTS 1)
+endif()
+
index b458afc90f7a4aa7d66acb87e62e3912d8932695..a4f9024002a0ade2144375df488771a8f098fb90 100644 (file)
@@ -29,7 +29,9 @@
 #include "framework/data_bus.h"
 #include "protocols/protocol_ids.h"
 #include "service_inspectors/http_inspect/http_msg_header.h"
-#include "thirdparty_appid_api.h"
+#include "tp_appid_module_api.h"
+#include "tp_appid_session_api.h"
+#include "appid_http_session.h"
 
 #include "appid_mock_definitions.h"
 #include "appid_mock_http_session.h"
index 7472aaa2ebd3897f4c3fc23c5f4e8ea8d06b3405..db1d4ef0a24578c149100b7b717198a5a782f20d 100644 (file)
@@ -188,8 +188,13 @@ TEST(appid_debug, ipv6_test)
     CHECK_EQUAL(appidDebug->is_active(), true);
 
     // get_debug_session()
+#ifdef REG_TEST
     const char* str = "2001:0db8:85a3:0000:0000:8a2e:0370:7334 1234 -> "
             "2001:0db8:85a3:0000:0000:8a2e:0370:7335 443 17 AS=100 ID=3";
+#else
+    const char* str = "2001:db8:85a3::8a2e:370:7334 1234 -> "
+            "2001:db8:85a3::8a2e:370:7335 443 17 AS=100 ID=3";
+#endif
     CHECK_TRUE(strcmp(appidDebug->get_debug_session(), str) == 0);
 }
 
index 1deab698763e3abe1a56bb9213884b0259c40b9a..e62da1b8b106f57ea02f335b927efb72c557c430 100644 (file)
@@ -29,7 +29,8 @@
 #include "network_inspectors/appid/appid_http_event_handler.cc"
 #include "protocols/protocol_ids.h"
 #include "service_inspectors/http_inspect/http_msg_header.h"
-#include "thirdparty_appid_api.h"
+#include "tp_appid_module_api.h"
+#include "tp_appid_session_api.h"
 
 #include "appid_mock_definitions.h"
 #include "appid_mock_inspector.h"
index c6f8dcb898ed09d420e8e07865fbe524d98df04f..c4f72c744910fb3ae861defc0b3f1e72f09d6376 100644 (file)
@@ -27,7 +27,7 @@ class Inspector;
 struct ThirdPartyAppIDModule;
 
 AppIdConfig* pAppidActiveConfig = nullptr;
-THREAD_LOCAL ThirdPartyAppIDModule* thirdparty_appid_module = nullptr;
+ThirdPartyAppIDModule* tp_appid_module = nullptr;
 
 char* snort_strndup(const char* src, size_t dst_size)
 {
@@ -87,13 +87,12 @@ ServiceDiscoveryState* AppIdServiceState::add(SfIp const*, IpProtocol, unsigned
 void ServiceDiscoveryState::set_service_id_valid(ServiceDetector*) { }
 
 // Stubs for service_plugins/service_discovery.h
-int ServiceDiscovery::incompatible_data(AppIdSession&, const Packet*, int, ServiceDetector*)
+int ServiceDiscovery::incompatible_data(AppIdSession&, const Packet*, AppidSessionDirection, ServiceDetector*)
 {
   return 0;
 }
 
-int ServiceDiscovery::fail_service(AppIdSession&, const Packet*, int, ServiceDetector*,
-    ServiceDiscoveryState*)
+int ServiceDiscovery::fail_service(AppIdSession&, const Packet*, AppidSessionDirection, ServiceDetector*, ServiceDiscoveryState*)
 {
   return 0;
 }
index 8876c788eb72f96f1d454033d761718635348e54..fcb57e13eaccb33d3ee1229f9b62b0da61317952 100644 (file)
@@ -34,7 +34,7 @@ AppIdHttpSession::~AppIdHttpSession()
     delete xff_addr;
 }
 
-int AppIdHttpSession::process_http_packet(int) { return 0; }
+int AppIdHttpSession::process_http_packet(AppidSessionDirection) { return 0; }
 
 char const* APPID_UT_XFF_IP_ADDR = "192.168.0.1";
 char const* CONTENT_TYPE = "html/text";
index dbb9826bd2f1aba3971a6127cd0e5226eb71309d..8f654e29d4ba11a4ed85a4a8b9b08d2c80a17225 100644 (file)
@@ -241,5 +241,15 @@ AppIdDnsSession* AppIdSession::get_dns_session()
     return dsession;
 }
 
+bool AppIdSession::is_third_party_appid_done() const
+{
+    return true;
+}
+
+bool AppIdSession::is_third_party_appid_available() const
+{
+    return false;
+}
+
 #endif
 
diff --git a/src/network_inspectors/appid/test/log_message_mock.h b/src/network_inspectors/appid/test/log_message_mock.h
new file mode 100644 (file)
index 0000000..54fce50
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef LOG_MESSGE_MOCK
+#define LOG_MESSAGE_MOCK
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cstdarg>
+
+using namespace std;
+
+// Note: without SO_PUBLIC this is not being exported so tp_mock.so won't
+// load because of undefined symbol error. 
+SO_PUBLIC void ErrorMessage(const char* format,...)
+{
+    va_list ap;
+    va_start(ap,format);
+    vfprintf(stderr, format, ap);
+    va_end(ap);
+}
+
+SO_PUBLIC [[noreturn]] void FatalError(const char* format,...)
+{
+    ErrorMessage(format);
+    exit(1);
+}
+
+
+SO_PUBLIC void WarningMessage(const char* format,...)
+{
+    va_list ap;
+    va_start(ap, format);
+        vfprintf(stderr, format, ap);
+    va_end(ap);
+}
+
+SO_PUBLIC void LogMessage(const char* format,...)
+{
+    va_list ap;
+    va_start(ap, format);
+    vfprintf(stdout, format, ap);
+    va_end(ap);
+}
+
+// void Debug::print(const char*, int, uint64_t, const char*, ...) { }
+
+#endif
+
index 09269cc207b7f4331efd632a71f1394a57cbf60e..2d05fec9021a59340b035b27aa6fcca397b103c7 100644 (file)
@@ -76,13 +76,13 @@ void ServiceDiscovery::initialize() {}
 void ServiceDiscovery::finalize_service_patterns() {}
 void ServiceDiscovery::match_by_pattern(AppIdSession&, const Packet*, IpProtocol) {}
 void ServiceDiscovery::get_port_based_services(IpProtocol, uint16_t, AppIdSession&) {}
-void ServiceDiscovery::get_next_service(const Packet*, const int, AppIdSession&) {}
-int ServiceDiscovery::identify_service(AppIdSession&, Packet*, int) { return 0; }
+void ServiceDiscovery::get_next_service(const Packet*, const AppidSessionDirection, AppIdSession&) {}
+int ServiceDiscovery::identify_service(AppIdSession&, Packet*, AppidSessionDirection) { return 0; }
 int ServiceDiscovery::add_ftp_service_state(AppIdSession&) { return 0; }
-bool ServiceDiscovery::do_service_discovery(AppIdSession&, Packet*, int) { return 0; }
-int ServiceDiscovery::incompatible_data(AppIdSession&, const Packet*,int,
+bool ServiceDiscovery::do_service_discovery(AppIdSession&, Packet*, AppidSessionDirection) { return 0; }
+int ServiceDiscovery::incompatible_data(AppIdSession&, const Packet*,AppidSessionDirection,
     ServiceDetector*) { return 0; }
-int ServiceDiscovery::fail_service(AppIdSession&, const Packet*, int,
+int ServiceDiscovery::fail_service(AppIdSession&, const Packet*, AppidSessionDirection,
     ServiceDetector*, ServiceDiscoveryState*) { return 0; }
 int ServiceDiscovery::add_service_port(AppIdDetector*,
     const ServiceDetectorPort&) { return APPID_EINVALID; }
diff --git a/src/network_inspectors/appid/test/tp_appid_types_test.cc b/src/network_inspectors/appid/test/tp_appid_types_test.cc
new file mode 100644 (file)
index 0000000..aa73c23
--- /dev/null
@@ -0,0 +1,111 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2016-2018 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.
+//--------------------------------------------------------------------------
+
+// tp_appid_types_test.cc author Silviu Minut <sminut@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <iostream>
+#include <string>
+
+#include "tp_appid_types.h"
+
+#include <CppUTest/CommandLineTestRunner.h>
+#include <CppUTest/TestHarness.h>
+
+// 1st CHECK_EQUAL checks that what comes out is what went in
+// 2nd CHECK_EQUAL checks that AttributeData still has it
+// 3rd CHECK_EQUAL checks that AttributeData doesn't leak memory upon consecutive sets
+// finally check that we don't leak or double free memory when caller owns it
+#define SET_GET_MACRO(func)                                             \
+    ad.set_ ## func(abc.c_str(), abc.size());                           \
+    outField=ad.func(0);                                                \
+    CHECK_EQUAL(*outField,abc);                                         \
+    outField=ad.func(0);                                                \
+    CHECK_EQUAL(*outField,abc);                                         \
+    ad.set_ ## func(def.c_str(), def.size());                           \
+    outField=ad.func(0);                                                \
+    CHECK_EQUAL(*outField,def);                                         \
+    outField=ad.func(1);                                                \
+    delete outField;
+
+#define SET_GET_OFFSET_MACRO(func)                                      \
+    ad.set_ ## func(abc.c_str(), abc.size(), start, end);               \
+    outField=ad.func(0);                                                \
+    CHECK_EQUAL(*outField,abc);                                         \
+    outField=ad.func(0);                                                \
+    CHECK_EQUAL(*outField,abc);                                         \
+    ad.set_ ## func(def.c_str(), def.size(), start, end);               \
+    outField=ad.func(0);                                                \
+    CHECK_EQUAL(*outField,def);                                         \
+    outField=ad.func(1);                                                \
+    delete outField;
+
+TEST_GROUP(tp_appid_types)
+{
+    void setup() override
+    {
+    }
+
+    void teardown() override
+    {
+    }
+};
+
+TEST(tp_appid_types, get_set)
+{
+    ThirdPartyAppIDAttributeData ad;
+    uint16_t start=0, end=3;
+    string abc("abc");
+    string def("def");
+    const string* outField=nullptr;
+
+    SET_GET_OFFSET_MACRO(spdy_request_path);
+    SET_GET_MACRO(spdy_request_scheme);
+    SET_GET_OFFSET_MACRO(spdy_request_host);
+    SET_GET_MACRO(http_request_url);
+    SET_GET_OFFSET_MACRO(http_request_uri);
+    SET_GET_OFFSET_MACRO(http_request_host);
+    SET_GET_OFFSET_MACRO(http_request_cookie);
+    SET_GET_MACRO(http_request_via);
+    SET_GET_MACRO(http_response_via);
+    SET_GET_MACRO(http_response_upgrade);
+    SET_GET_OFFSET_MACRO(http_request_user_agent);
+    SET_GET_MACRO(http_response_version);
+    SET_GET_MACRO(http_response_code);
+    SET_GET_MACRO(http_response_content);
+    SET_GET_MACRO(http_response_location);
+    SET_GET_MACRO(http_response_body);
+    SET_GET_MACRO(http_request_body);
+    SET_GET_MACRO(http_response_server);
+    SET_GET_MACRO(http_request_x_working_with);
+    SET_GET_MACRO(tls_host);
+    SET_GET_MACRO(tls_cname);
+    SET_GET_MACRO(tls_org_unit);
+    SET_GET_OFFSET_MACRO(http_request_referer);
+    SET_GET_MACRO(ftp_command_user);
+}
+
+int main(int argc, char** argv)
+{
+    int rc = CommandLineTestRunner::RunAllTests(argc, argv);
+    return rc;
+}
+
diff --git a/src/network_inspectors/appid/test/tp_lib_handler_test.cc b/src/network_inspectors/appid/test/tp_lib_handler_test.cc
new file mode 100644 (file)
index 0000000..857ccf9
--- /dev/null
@@ -0,0 +1,109 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2018-2018 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.
+//--------------------------------------------------------------------------
+
+// tp_lib_handler_test.cc author Silviu Minut <sminut@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <iostream>
+#include <string>
+
+#define TP_SUPPORTED 1
+
+#include "tp_lib_handler.h"
+#include "appid_config.h"
+#include "main/snort_debug.h"
+#include "log_message_mock.h"
+
+#include <CppUTest/CommandLineTestRunner.h>
+#include <CppUTest/TestHarness.h>
+
+using namespace std;
+
+TPLibHandler* tph = nullptr;
+AppIdModuleConfig config;
+
+AppIdModuleConfig::~AppIdModuleConfig() { }
+
+#ifdef DEBUG_MSGS
+void Debug::print(const char*, int, uint64_t, const char*, ...) { }
+#endif
+
+TEST_GROUP(tp_lib_handler)
+{
+};
+
+TEST(tp_lib_handler, load_unload)
+{
+    tph->pinit(&config);
+    CHECK_TRUE(tph->have_tp());
+
+    CreateThirdPartyAppIDSession_t asf = tph->tpsession_factory();
+    ThirdPartyAppIDSession* tpsession = asf();
+
+    CHECK_TRUE(tpsession != nullptr);
+
+    delete tpsession;
+
+    tph->pfini();
+}
+
+TEST(tp_lib_handler, tp_lib_handler_get)
+{
+    TPLibHandler* tph2=TPLibHandler::get();
+    CHECK_EQUAL(tph,tph2);
+}
+
+TEST(tp_lib_handler, load_error)
+{
+    // Trigger load error:
+    AppIdModuleConfig config;
+    config.tp_appid_path="nonexistent.so";
+    tph=TPLibHandler::get();
+    tph->pinit(&config);
+    CHECK_FALSE(tph->have_tp());
+    tph->pfini();
+}
+
+TEST(tp_lib_handler, tp_appid_module_pinit_error)
+{
+    // Trigger MODULE pinit error:
+    AppIdModuleConfig config;
+    config.tp_appid_path="./libtp_mock.so";
+    config.tp_appid_config="";  // forces MODULE::pinit() to return 1.
+    tph=TPLibHandler::get();
+    tph->pinit(&config);
+    CHECK_FALSE(tph->have_tp());
+    tph->pfini(1);                      // print stats too.
+}
+
+int main(int argc, char** argv)
+{
+    config.tp_appid_path="./libtp_mock.so";
+    config.tp_appid_config="./tp.config";
+    tph=TPLibHandler::get();
+
+    int rc = CommandLineTestRunner::RunAllTests(argc, argv);
+
+    TPLibHandler::destroy(tph);
+
+    return rc;
+}
+
diff --git a/src/network_inspectors/appid/test/tp_mock.cc b/src/network_inspectors/appid/test/tp_mock.cc
new file mode 100644 (file)
index 0000000..0dc7409
--- /dev/null
@@ -0,0 +1,115 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2016-2018 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.
+//--------------------------------------------------------------------------
+
+// tp_mock.cc author Silviu Minut <sminut@cisco.com>
+
+// Standalone compilation:
+// g++ -g -Wall -I.. -I/path/to/snort3/src -c tp_mock.cc
+// g++ -std=c++11 -g -Wall -I.. -I/path/to/snort3/src -shared -fPIC -o libtp_mock.so tp_mock.cc
+// As a module (dynamically loaded)  - see CMakeLists.txt
+
+#include <iostream>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "main/snort_types.h"
+
+#include "tp_appid_module_api.h"
+#include "tp_appid_session_api.h"
+
+#define THIRD_PARTY_APPID_MODULE_NAME "NAVL"
+
+#define WhereMacro __FILE__ << ": " << __FUNCTION__ << ": " << __LINE__
+
+using namespace std;
+
+class ThirdPartyAppIDModuleImpl : public ThirdPartyAppIDModule
+{
+public:
+    ThirdPartyAppIDModuleImpl(uint32_t ver, const char* mname)
+        : ThirdPartyAppIDModule(ver, mname)
+    {
+        cerr << WhereMacro << endl;
+    }
+
+    ~ThirdPartyAppIDModuleImpl()
+    {
+        cerr << WhereMacro << endl;
+    }
+
+    // Hack: use cfg to manipulate pinit to return 1, so we can hit the
+    // if (ret != 0) case in tp_lib_handler.cc.
+    int pinit(ThirdPartyConfig& cfg)
+    {
+        cerr << WhereMacro << endl;
+        return cfg.tp_appid_config.empty() ? 1 : 0;
+    }
+
+    int tinit() { return 0; }
+    int reconfigure(const ThirdPartyConfig&) { return 0; }
+    int pfini()
+    {
+        cerr << WhereMacro << endl;
+        return 0;
+    }
+
+    int tfini() { return 0; }
+    int print_stats() { return 0; }
+    int reset_stats() { return 0; }
+};
+
+class ThirdPartyAppIDSessionImpl : public ThirdPartyAppIDSession
+{
+public:
+
+    bool reset() { return 1; }
+    bool process(const snort::Packet&, AppidSessionDirection, vector<AppId>&,
+        ThirdPartyAppIDAttributeData&) { return 1; }
+
+    int disable_flags(uint32_t) { return 0; }
+    TPState get_state() { return state; }
+    void set_state(TPState s) { state=s; }
+    void clear_attr(TPSessionAttr attr) { flags &= ~attr; }
+    void set_attr(TPSessionAttr attr) { flags |= attr; }
+    unsigned get_attr(TPSessionAttr attr) { return flags & attr; }
+
+private:
+    unsigned flags = 0;
+};
+
+// Object factories to create module and session.
+// This is the only way for outside callers to create module and session
+// once the .so has been loaded.
+extern "C"
+{
+    SO_PUBLIC ThirdPartyAppIDModuleImpl* create_third_party_appid_module();
+    SO_PUBLIC ThirdPartyAppIDSessionImpl* create_third_party_appid_session();
+
+    SO_PUBLIC ThirdPartyAppIDModuleImpl* create_third_party_appid_module()
+    {
+        return new ThirdPartyAppIDModuleImpl(1,"foobar");
+    }
+
+    SO_PUBLIC ThirdPartyAppIDSessionImpl* create_third_party_appid_session()
+    {
+        return new ThirdPartyAppIDSessionImpl;
+    }
+}
+
diff --git a/src/network_inspectors/appid/thirdparty_appid_api.h b/src/network_inspectors/appid/thirdparty_appid_api.h
deleted file mode 100644 (file)
index 7fc804c..0000000
+++ /dev/null
@@ -1,98 +0,0 @@
-//--------------------------------------------------------------------------
-// Copyright (C) 2014-2018 Cisco and/or its affiliates. All rights reserved.
-// Copyright (C) 2005-2013 Sourcefire, Inc.
-//
-// 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.
-//--------------------------------------------------------------------------
-
-// thirdparty_appid_api.h author Sourcefire Inc.
-
-#ifndef THIRDPARTY_APPID_API_H
-#define THIRDPARTY_APPID_API_H
-
-#include "application_ids.h"
-#include "thirdparty_appid_types.h"
-
-namespace snort
-{
-struct Packet;
-}
-
-#define THIRD_PARTY_APP_ID_API_VERSION 1
-
-#define TP_PATH_MAX 4096
-
-struct ThirdPartyConfig
-{
-    unsigned chp_body_collection_max;
-    unsigned ftp_userid_disabled : 1;
-    unsigned chp_body_collection_disabled : 1;
-    unsigned tp_allow_probes : 1;
-    unsigned http_upgrade_reporting_enabled : 1;
-    char appid_tp_dir[TP_PATH_MAX];
-    unsigned numXffFields;
-    char** xffFields;
-    unsigned oldNumXffFields;
-    char** oldXffFields;
-};
-
-struct ThirdPartyUtils
-{
-    void (* logMsg)(const char*, ...);
-    uint32_t (* getSnortInstance)();
-};
-
-using ThirdPartyAppIDModInit = int (*)(ThirdPartyConfig*, ThirdPartyUtils*);
-using ThirdPartyAppIDModReconfigure = int (*)(ThirdPartyConfig*);
-using ThirdPartyAppIDModFini = int (*)();
-using ThirdPartyAppIDSessionCreate = void*(*)();
-using ThirdPartyAppIDSessionDelete = int (*)(void* tpsession, int just_reset_state);
-using ThirdPartyAppIDSessionProcess = int (*)(void* tpsession, snort::Packet*, int direction,                                  // in
-    AppId*, int* confidence, AppId** proto_list, ThirdPartyAppIDAttributeData** attribute_data);
-using ThirdPartyAppIDPrintStats = int (*)();
-using ThirdPartyAppIDResetStats = int (*)();
-using ThirdPartyAppIDDisableFlags = int (*)(void* tpsession, uint32_t session_flags);
-using ThirdPartyAppIDSessionStateGet = TPState (*)(void* tpsession);
-using ThirdPartyAppIDSessionStateSet = void (*)(void* tpsession, TPState);
-using ThirdPartyAppIDSessionAttrSet = void (*)(void* tpsession, TPSessionAttr);
-using ThirdPartyAppIDSessionAttrClear = void (*)(void* tpsession, TPSessionAttr);
-using ThirdPartyAppIDSessionAttrGet = unsigned (*)(void* tpsession, TPSessionAttr);
-using ThirdPartyAppIDSessionCurrenAppIdGet = AppId (*)(void* tpsession);
-
-// SO_PUBLIC const ThirdPartyAppIDModule thirdparty_appid_impl_module
-struct ThirdPartyAppIDModule
-{
-    const uint32_t api_version;
-    const char* module_name;
-    ThirdPartyAppIDModInit init;
-    ThirdPartyAppIDModReconfigure reconfigure;
-    ThirdPartyAppIDModFini fini;
-    ThirdPartyAppIDSessionCreate session_create;
-    ThirdPartyAppIDSessionDelete session_delete;
-    ThirdPartyAppIDSessionProcess session_process;
-    ThirdPartyAppIDPrintStats print_stats;
-    ThirdPartyAppIDResetStats reset_stats;
-    ThirdPartyAppIDDisableFlags disable_flags;
-
-    ThirdPartyAppIDSessionStateGet session_state_get;
-    ThirdPartyAppIDSessionStateSet session_state_set;
-    ThirdPartyAppIDSessionAttrSet session_attr_set;
-    ThirdPartyAppIDSessionAttrClear session_attr_clear;
-    ThirdPartyAppIDSessionAttrGet session_attr_get;
-    ThirdPartyAppIDSessionCurrenAppIdGet session_appid_get;
-};
-
-#endif
-
diff --git a/src/network_inspectors/appid/thirdparty_appid_types.h b/src/network_inspectors/appid/thirdparty_appid_types.h
deleted file mode 100644 (file)
index 7b17009..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-//--------------------------------------------------------------------------
-// Copyright (C) 2014-2018 Cisco and/or its affiliates. All rights reserved.
-// Copyright (C) 2005-2013 Sourcefire, Inc.
-//
-// 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.
-//--------------------------------------------------------------------------
-
-// thirdparty_appid_types.h author Sourcefire Inc.
-
-#ifndef THIRDPARTY_APPID_TYPES_H
-#define THIRDPARTY_APPID_TYPES_H
-
-//#define BUILD_NAVL_SUPPORT 1
-
-#include <cstdint>
-
-#include "appid_http_session.h"
-
-#define TP_SESSION_FLAG_DPI        0x00000001
-#define TP_SESSION_FLAG_MUTABLE    0x00000002
-#define TP_SESSION_FLAG_FUTUREFLOW 0x00000004
-#define TP_SESSION_FLAG_ATTRIBUTE  0x00000008
-#define TP_SESSION_FLAG_TUNNELING  0x00000010
-
-#define HTTP_XFF_FIELD_X_FORWARDED_FOR ""
-#define HTTP_XFF_FIELD_TRUE_CLIENT_IP ""
-#define HTTP_MAX_XFF_FIELDS 255
-
-enum TPState
-{
-    TP_STATE_INIT,
-    TP_STATE_TERMINATED,
-    TP_STATE_INSPECTING,
-    TP_STATE_MONITORING,
-    TP_STATE_CLASSIFIED,
-    TP_STATE_HA = 21
-};
-
-enum TPSessionAttr
-{
-    TP_ATTR_CONTINUE_MONITORING     = (1 << 0),
-    TP_ATTR_COPY_RESPONSE_CONTENT   = (1 << 1),
-    TP_ATTR_COPY_RESPONSE_LOCATION  = (1 << 2),
-    TP_ATTR_COPY_RESPONSE_BODY      = (1 << 3),
-};
-
-struct ThirdPartyAppIDAttributeData
-{
-    char* spdyRequestPath;
-    char* spdyRequestScheme;
-    char* spdyRequestHost;
-    char* httpRequestUrl;
-    char* httpRequestUri;
-    uint16_t httpRequestUriLen;
-    uint16_t httpRequestUriOffset;
-    uint16_t httpRequestUriEndOffset;
-    char* httpRequestHost;
-    uint16_t httpRequestHostLen;
-    char* httpRequestCookie;
-    uint16_t httpRequestCookieLen;
-    uint16_t httpRequestCookieOffset;
-    uint16_t httpRequestCookieEndOffset;
-    char* httpRequestVia;
-    char* httpResponseVia;
-    char* httpResponseUpgrade;
-    char* httpRequestUserAgent;
-    uint16_t httpRequestUserAgentLen;
-    char* httpResponseVersion;
-    char* httpResponseCode;
-    uint16_t httpResponseCodeLen;
-    char* httpResponseContent;
-    uint16_t httpResponseContentLen;
-    char* httpResponseLocation;
-    uint16_t httpResponseLocationLen;
-    char* httpResponseBody;
-    uint16_t httpResponseBodyLen;
-    char* httpRequestBody;
-    uint16_t httpRequestBodyLen;
-    char* httpResponseServer;
-    char* httpRequestXWorkingWith;
-    char* tlsHost;
-    char* tlsCname;
-    char* tlsOrgUnit;
-    char* httpRequestReferer;
-    uint16_t httpRequestRefererLen;
-    char* ftpCommandUser;
-    struct XffFieldValue xffFieldValue[HTTP_MAX_XFF_FIELDS];
-    uint8_t numXffFields;
-    uint16_t httpRequestUserAgentOffset;
-    uint16_t httpRequestUserAgentEndOffset;
-    uint16_t httpRequestHostOffset;
-    uint16_t httpRequestHostEndOffset;
-    uint16_t httpRequestRefererOffset;
-    uint16_t httpRequestRefererEndOffset;
-    uint16_t spdyRequestHostOffset;
-    uint16_t spdyRequestHostEndOffset;
-    uint16_t spdyRequestPathOffset;
-    uint16_t spdyRequestPathEndOffset;
-};
-
-#endif
-
diff --git a/src/network_inspectors/appid/thirdparty_appid_utils.cc b/src/network_inspectors/appid/thirdparty_appid_utils.cc
deleted file mode 100644 (file)
index 0642f17..0000000
+++ /dev/null
@@ -1,1019 +0,0 @@
-//--------------------------------------------------------------------------
-// Copyright (C) 2014-2018 Cisco and/or its affiliates. All rights reserved.
-// Copyright (C) 2005-2013 Sourcefire, Inc.
-//
-// 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.
-//--------------------------------------------------------------------------
-
-// thirdparty_appid_utils.cc author Sourcefire Inc.
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "thirdparty_appid_utils.h"
-
-#include <dlfcn.h>
-
-#include "log/messages.h"
-#include "profiler/profiler.h"
-#include "protocols/packet.h"
-#include "stream/stream.h"
-
-#include "app_info_table.h"
-#include "appid_config.h"
-#include "appid_debug.h"
-#include "appid_http_session.h"
-#include "appid_inspector.h"
-#include "detector_plugins/http_url_patterns.h"
-#include "service_plugins/service_ssl.h"
-
-using namespace snort;
-
-#define MODULE_SYMBOL "thirdparty_appid_impl_module"
-
-static THREAD_LOCAL void* module_handle = nullptr;
-static THREAD_LOCAL struct ThirdPartyConfig thirdpartyConfig;
-THREAD_LOCAL ThirdPartyAppIDModule* thirdparty_appid_module = nullptr;
-
-static char const* defaultXffFields[] = { HTTP_XFF_FIELD_X_FORWARDED_FOR,
-                                          HTTP_XFF_FIELD_TRUE_CLIENT_IP };
-
-ProfileStats tpLibPerfStats;
-ProfileStats tpPerfStats;
-
-inline int testSSLAppIdForReinspect(AppId app_id)
-{
-    if (app_id <= SF_APPID_MAX &&
-        (app_id == APP_ID_SSL || AppInfoManager::get_instance().get_app_info_flags(app_id,
-        APPINFO_FLAG_SSL_INSPECT)))
-        return 1;
-    else
-        return 0;
-}
-
-#ifdef BUILD_NAVL_SUPPORT
-static int LoadCallback(const char* const path, int /* indent */)
-{
-    void* handle;
-    ThirdPartyAppIDModule* tp_module;
-
-    if (thirdparty_appid_module != nullptr)
-    {
-        ErrorMessage("Ignoring additional 3rd party AppID module (%s)!\n", path);
-        return 0;
-    }
-
-    handle = dlopen(path, RTLD_NOW | RTLD_LOCAL);
-    if (handle == nullptr)
-    {
-        ErrorMessage("Failed to load 3rd party AppID module: %s - %s\n", path, dlerror());
-        return 0;
-    }
-
-    tp_module = (ThirdPartyAppIDModule*)dlsym(handle, MODULE_SYMBOL);
-    if (tp_module == nullptr)
-    {
-        ErrorMessage("Failed to fine symbol %s in library %s\n", MODULE_SYMBOL, path);
-        dlclose(handle);
-        return 0;
-    }
-
-    if ( (tp_module->api_version != THIRD_PARTY_APP_ID_API_VERSION)
-        || ((tp_module->module_name == nullptr) || (tp_module->module_name[0] == 0))
-        || (tp_module->init == nullptr)
-        || (tp_module->fini == nullptr)
-        || (tp_module->session_create == nullptr)
-        || (tp_module->session_delete == nullptr)
-        || (tp_module->session_process == nullptr)
-        || (tp_module->print_stats == nullptr)
-        || (tp_module->reset_stats == nullptr)
-        || (tp_module->disable_flags == nullptr) )
-    {
-        ErrorMessage("Ignoring incomplete 3rd party AppID module (%s)!\n", path);
-        dlclose(handle);
-        return 0;
-    }
-
-    module_handle = handle;
-    thirdparty_appid_module = tp_module;
-    return 0;
-}
-
-#endif
-
-static void getXffFields()
-{
-    // FIXIT-M need to get xff fields from http config
-    const char** xffFields = nullptr; // = _dpd.getHttpXffFields(&thirdpartyConfig.numXffFields);
-    //if (!xffFields)  FIXIT-W always true
-    {
-        xffFields = defaultXffFields;
-        thirdpartyConfig.numXffFields = sizeof(defaultXffFields) / sizeof(defaultXffFields[0]);
-    }
-    thirdpartyConfig.xffFields = (char**)snort_alloc(thirdpartyConfig.numXffFields *
-        sizeof(char*));
-    for (unsigned i = 0; i < thirdpartyConfig.numXffFields; i++)
-        thirdpartyConfig.xffFields[i] = snort_strndup(xffFields[i], UINT8_MAX);
-}
-
-void ThirdPartyAppIDInit(const AppIdModuleConfig* config)
-{
-    const char* thirdparty_appid_dir = config->thirdparty_appid_dir;
-    int ret;
-    struct ThirdPartyUtils thirdpartyUtils;
-
-    if ( ( thirdparty_appid_module != nullptr ) || ( thirdparty_appid_dir == nullptr )
-        || ( thirdparty_appid_dir[0] == 0 ) )
-        return;
-
-    // FIXIT-L need to port loadAllLibs function to snort3
-    // _dpd.loadAllLibs(thirdparty_appid_dir, LoadCallback);
-    if (thirdparty_appid_module == nullptr)
-    {
-        return;
-    }
-    memset(&thirdpartyConfig, 0, sizeof(thirdpartyConfig));
-    thirdpartyConfig.chp_body_collection_max = config->chp_body_collection_max;
-    thirdpartyConfig.ftp_userid_disabled = config->ftp_userid_disabled;
-    thirdpartyConfig.chp_body_collection_disabled =
-        config->chp_body_collection_disabled;
-    thirdpartyConfig.tp_allow_probes = config->tp_allow_probes;
-    if (config->http2_detection_enabled)
-        thirdpartyConfig.http_upgrade_reporting_enabled = 1;
-    else
-        thirdpartyConfig.http_upgrade_reporting_enabled = 0;
-    thirdpartyConfig.appid_tp_dir[0] = '\0';    // use default path
-
-    // FIXIT-M need to provide log function and getSnortInstance function to 3rd party utils
-#ifdef BUILD_NAVL_SUPPORT
-    //thirdpartyUtils.logMsg           = &DebugFormat;
-    //thirdpartyUtils.getSnortInstance = _dpd.getSnortInstance;
-#endif
-
-    getXffFields();
-
-    ret = thirdparty_appid_module->init(&thirdpartyConfig, &thirdpartyUtils);
-    if (ret != 0)
-    {
-        ErrorMessage("Unable to initialize 3rd party AppID module (%d)!\n", ret);
-        dlclose(module_handle);
-        module_handle = nullptr;
-        thirdparty_appid_module = nullptr;
-        return;
-    }
-}
-
-void ThirdPartyAppIDReconfigure()
-{
-    int ret;
-
-    if (thirdparty_appid_module == nullptr)
-    {
-        return;
-    }
-
-    thirdpartyConfig.oldNumXffFields = thirdpartyConfig.numXffFields;
-    thirdpartyConfig.oldXffFields = thirdpartyConfig.xffFields;
-    getXffFields();
-
-    ret = thirdparty_appid_module->reconfigure(&thirdpartyConfig);
-    for (unsigned i = 0; i < thirdpartyConfig.oldNumXffFields; i++)
-        snort_free(thirdpartyConfig.oldXffFields[i]);
-    snort_free(thirdpartyConfig.oldXffFields);
-
-    if (ret != 0)
-    {
-        ErrorMessage("Unable to reconfigure 3rd party AppID module (%d)!\n", ret);
-        return;
-    }
-}
-
-void ThirdPartyAppIDFini()
-{
-    if (thirdparty_appid_module != nullptr)
-    {
-        int ret = thirdparty_appid_module->fini();
-
-        if (ret != 0)
-            ErrorMessage("Could not finalize 3rd party AppID module (%d)!\n", ret);
-
-        dlclose(module_handle);
-        module_handle = nullptr;
-        thirdparty_appid_module = nullptr;
-
-    }
-}
-
-#ifdef BUILD_NAVL_SUPPORT
-
-// FIXIT-L bogus placeholder for this func, need to find out what it should do
-static inline bool TPIsAppIdDone(void*)
-{
-    return false;
-}
-
-inline int ThirdPartyAppIDFoundProto(AppId proto, AppId* proto_list)
-{
-    unsigned int proto_cnt = 0;
-    while (proto_list[proto_cnt] != APP_ID_NONE)
-        if (proto_list[proto_cnt++] == proto)
-            return 1;
-    // found
-
-    return 0;            // not found
-}
-
-bool checkThirdPartyReinspect(const Packet* p, AppIdSession& asd)
-{
-    return p->dsize && !asd.get_session_flags(APPID_SESSION_NO_TPI) &&
-           asd.get_session_flags(APPID_SESSION_HTTP_SESSION) && TPIsAppIdDone(asd.tpsession);
-}
-
-static void ProcessThirdPartyResults(AppIdSession& asd, int confidence,  AppId* proto_list,
-    ThirdPartyAppIDAttributeData* attribute_data)
-{
-    AppId serviceAppId = 0;
-    AppId client_id = 0;
-    AppId payload_id = 0;
-    AppId referred_payload_app_id = 0;
-
-    if (ThirdPartyAppIDFoundProto(APP_ID_EXCHANGE, proto_list))
-    {
-        if (!payload_id)
-            payload_id = APP_ID_EXCHANGE;
-    }
-
-    if (ThirdPartyAppIDFoundProto(APP_ID_HTTP, proto_list))
-    {
-        if (appidDebug->is_active())
-            LogMessage("AppIdDbg %s HTTP flow\n", appidDebug->get_debug_session());
-        asd.set_session_flags(APPID_SESSION_HTTP_SESSION);
-    }
-    if (ThirdPartyAppIDFoundProto(APP_ID_SPDY, proto_list))
-    {
-        if (appidDebug->is_active())
-            LogMessage("AppIdDbg %s SPDY flow\n", appidDebug->get_debug_session());
-
-        asd.set_session_flags(APPID_SESSION_HTTP_SESSION | APPID_SESSION_SPDY_SESSION);
-    }
-
-    if (asd.get_session_flags(APPID_SESSION_HTTP_SESSION))
-    {
-        AppIdHttpSession* hsession = asd.get_http_session();
-        hsession->reset_ptype_scan_counts();
-
-        if (asd.get_session_flags(APPID_SESSION_SPDY_SESSION))
-        {
-            if (attribute_data->spdyRequestScheme &&
-                attribute_data->spdyRequestHost &&
-                attribute_data->spdyRequestPath)
-            {
-                static const char httpsScheme[] = "https";
-                static const char httpScheme[] = "http";
-                std::string url;
-                if (asd.get_session_flags(APPID_SESSION_DECRYPTED)
-                    &&
-                    memcmp(attribute_data->spdyRequestScheme, httpScheme,
-                       sizeof(httpScheme) - 1) == 0)
-                {
-                    url = httpsScheme;
-                }
-                else
-                {
-                    url = attribute_data->spdyRequestScheme;
-                }
-
-
-                if (hsession->get_url())
-                    hsession->set_chp_finished(false);
-
-                url += "://";
-                url += attribute_data->spdyRequestHost;
-                url += attribute_data->spdyRequestPath;
-                hsession->set_url(url.c_str());
-                asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
-
-                snort_free(attribute_data->spdyRequestScheme);
-                attribute_data->spdyRequestScheme = nullptr;
-            }
-            else if (attribute_data->spdyRequestScheme)
-            {
-                snort_free(attribute_data->spdyRequestScheme);
-                attribute_data->spdyRequestScheme = nullptr;
-            }
-
-            if (attribute_data->spdyRequestHost)
-            {
-                if (hsession->get_host())
-                    hsession->set_chp_finished(false);
-
-                hsession->update_host((const uint8_t*)attribute_data->spdyRequestHost,
-                    strlen(attribute_data->spdyRequestHost));
-                // FIXIT-M do we need to free this memory and set to null
-                // attribute_data->spdyRequestHost = nullptr;
-                hsession->set_field_offset(REQ_HOST_FID, attribute_data->spdyRequestHostOffset);
-                hsession->set_field_end_offset(REQ_HOST_FID,
-                    attribute_data->spdyRequestHostEndOffset);
-                if (appidDebug->is_active())
-                    LogMessage("AppIdDbg %s SPDY host (%u-%u) is %s\n", appidDebug->get_debug_session(),
-                        hsession->get_field_offset(REQ_HOST_FID),
-                        hsession->get_field_end_offset(REQ_HOST_FID), hsession->get_host());
-                asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
-            }
-
-            if (attribute_data->spdyRequestPath)
-            {
-                if (hsession->get_uri())
-                    hsession->set_chp_finished(false);
-
-                hsession->update_uri((const uint8_t*)attribute_data->spdyRequestPath,
-                    strlen(attribute_data->spdyRequestPath));
-                // FIXIT-M do we need to free this memory and set to null
-                //attribute_data->spdyRequestPath = nullptr;
-                hsession->set_field_offset(REQ_URI_FID, attribute_data->spdyRequestPathOffset);
-                hsession->set_field_end_offset(REQ_URI_FID, attribute_data->spdyRequestPathEndOffset);
-                if (appidDebug->is_active())
-                    LogMessage("AppIdDbg %s SPDY URI (%u-%u) is %s\n", appidDebug->get_debug_session(),
-                        hsession->get_field_offset(REQ_URI_FID),
-                        hsession->get_field_end_offset(REQ_URI_FID), hsession->get_uri());
-            }
-        }
-        else
-        {
-            if (attribute_data->httpRequestHost)
-            {
-                if (hsession->get_host())
-                    if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
-                        hsession->set_chp_finished(false);
-
-                hsession->update_host((const uint8_t*)attribute_data->httpRequestHost,
-                    attribute_data->httpRequestHostLen);
-                hsession->set_field_offset(REQ_HOST_FID, attribute_data->httpRequestHostOffset);
-                hsession->set_field_end_offset(REQ_HOST_FID, attribute_data->httpRequestHostEndOffset);
-                // FIXIT-M do we need to free this memory and set to null
-                //attribute_data->httpRequestHost = nullptr;
-                if (appidDebug->is_active())
-                    LogMessage("AppIdDbg %s HTTP host (%u-%u) is %s\n",
-                        appidDebug->get_debug_session(), hsession->get_field_offset(REQ_HOST_FID),
-                        hsession->get_field_end_offset(REQ_HOST_FID), attribute_data->httpRequestHost);
-                asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
-            }
-
-            if (attribute_data->httpRequestUrl)
-            {
-                static const char httpScheme[] = "http://";
-
-                if (hsession->get_url())
-                    if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
-                        hsession->set_chp_finished(false);
-
-                //change http to https if session was decrypted.
-                if (asd.get_session_flags(APPID_SESSION_DECRYPTED)
-                    &&
-                    memcmp(attribute_data->httpRequestUrl, httpScheme, sizeof(httpScheme)-1) == 0)
-                {
-                    char* req_url = attribute_data->httpRequestUrl + sizeof(httpScheme) - 1;
-                    std::string url = "https://";
-                    url += req_url;
-
-                    snort_free(attribute_data->httpRequestUrl);
-                    attribute_data->httpRequestUrl = nullptr;
-                }
-                else
-                {
-                    hsession->set_url(attribute_data->httpRequestUrl);
-                    snort_free(attribute_data->httpRequestUrl);
-                    attribute_data->httpRequestUrl = nullptr;
-                }
-
-                asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
-            }
-
-            if (attribute_data->httpRequestUri)
-            {
-                if (hsession->get_uri())
-                    if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
-                        hsession->set_chp_finished(false);
-
-                hsession->update_uri((const uint8_t*)attribute_data->httpRequestUri,
-                    attribute_data->httpRequestUriLen);
-                hsession->set_field_offset(REQ_URI_FID, attribute_data->httpRequestUriOffset);
-                hsession->set_field_end_offset(REQ_URI_FID, attribute_data->httpRequestUriEndOffset);
-                snort_free(attribute_data->httpRequestUri);
-                attribute_data->httpRequestUri = nullptr;
-                if (appidDebug->is_active())
-                    LogMessage("AppIdDbg %s URI (%u-%u) is %s\n", appidDebug->get_debug_session(),
-                        hsession->get_field_offset(REQ_URI_FID),
-                        hsession->get_field_end_offset(REQ_URI_FID), hsession->get_uri());
-            }
-        }
-
-        if (attribute_data->httpRequestVia)
-        {
-            if (hsession->get_via())
-                if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
-                    hsession->set_chp_finished(false);
-
-            hsession->update_via((const uint8_t*)attribute_data->httpRequestVia,
-                strlen(attribute_data->httpRequestVia));
-            snort_free(attribute_data->httpRequestVia);
-            attribute_data->httpRequestVia = nullptr;
-            asd.scan_flags |= SCAN_HTTP_VIA_FLAG;
-        }
-        else if (attribute_data->httpResponseVia)
-        {
-            if (hsession->get_via())
-                if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
-                    hsession->set_chp_finished(false);
-
-            hsession->update_via((const uint8_t*)attribute_data->httpResponseVia,
-                strlen(attribute_data->httpResponseVia));
-            snort_free(attribute_data->httpResponseVia);
-            attribute_data->httpResponseVia = nullptr;
-            asd.scan_flags |= SCAN_HTTP_VIA_FLAG;
-        }
-
-        if (attribute_data->httpRequestUserAgent)
-        {
-            if (hsession->get_user_agent())
-                if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
-                    hsession->set_chp_finished(false);
-
-            hsession->update_useragent((const uint8_t*)attribute_data->httpRequestUserAgent,
-                strlen(attribute_data->httpRequestUserAgent));
-            snort_free(attribute_data->httpRequestUserAgent);
-            attribute_data->httpRequestUserAgent = nullptr;
-            if (appidDebug->is_active())
-                LogMessage("AppIdDbg %s User Agent (%u-%u) is %s\n",
-                    appidDebug->get_debug_session(), hsession->get_field_offset(REQ_AGENT_FID),
-                    hsession->get_field_end_offset(REQ_AGENT_FID), hsession->get_user_agent());
-            asd.scan_flags |= SCAN_HTTP_USER_AGENT_FLAG;
-        }
-
-        // Check to see if third party discovered HTTP/2. - once it supports it...
-        if (attribute_data->httpResponseVersion)
-        {
-            if (appidDebug->is_active())
-                LogMessage("AppIdDbg %s HTTP response version is %s\n", appidDebug->get_debug_session(),
-                    attribute_data->httpResponseVersion);
-            if (strncmp(attribute_data->httpResponseVersion, "HTTP/2", 6) == 0)
-            {
-                if (appidDebug->is_active())
-                    LogMessage("AppIdDbg %s 3rd party detected and parsed HTTP/2\n",
-                        appidDebug->get_debug_session());
-                asd.is_http2 = true;
-            }
-            snort_free(attribute_data->httpResponseVersion);
-            attribute_data->httpResponseVersion = nullptr;
-        }
-        if (attribute_data->httpResponseCode)
-        {
-            if (appidDebug->is_active())
-                LogMessage("AppIdDbg %s HTTP response code is %s\n", appidDebug->get_debug_session(),
-                    attribute_data->httpResponseCode);
-            if (hsession->get_response_code())
-                if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
-                    hsession->set_chp_finished(false);
-
-            hsession->update_response_code((const char*)attribute_data->httpResponseCode);
-            snort_free(attribute_data->httpResponseCode);
-            attribute_data->httpResponseCode = nullptr;
-        }
-        // Check to see if we've got an upgrade to HTTP/2 (if enabled).
-        //  - This covers the "without prior knowledge" case (i.e., the client
-        //    asks the server to upgrade to HTTP/2).
-        if (attribute_data->httpResponseUpgrade)
-        {
-            if (appidDebug->is_active())
-                LogMessage("AppIdDbg %s HTTP response upgrade is %s\n", appidDebug->get_debug_session(),
-                    attribute_data->httpResponseUpgrade);
-            if (asd.config->mod_config->http2_detection_enabled)
-                if ( hsession->get_response_code()
-                    && (strncmp(hsession->get_response_code(), "101", 3) == 0) )
-                    if (strncmp(attribute_data->httpResponseUpgrade, "h2c", 3) == 0)
-                    {
-                        if (appidDebug->is_active())
-                            LogMessage("AppIdDbg %s Got an upgrade to HTTP/2\n",
-                                appidDebug->get_debug_session());
-                        asd.is_http2 = true;
-                    }
-            snort_free(attribute_data->httpResponseUpgrade);
-            attribute_data->httpResponseUpgrade = nullptr;
-        }
-        if (attribute_data->httpRequestReferer)
-        {
-            if (hsession->get_referer())
-                if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
-                    hsession->set_chp_finished(false);
-
-            hsession->update_referer((const uint8_t*)attribute_data->httpRequestReferer,
-                attribute_data->httpRequestRefererLen);
-            snort_free(attribute_data->httpRequestReferer);
-            attribute_data->httpRequestReferer = nullptr;
-            hsession->set_field_offset(REQ_REFERER_FID, attribute_data->httpRequestRefererOffset);
-            hsession->set_field_end_offset(REQ_REFERER_FID, attribute_data->httpRequestRefererEndOffset);
-            if (appidDebug->is_active())
-                LogMessage("AppIdDbg %s Referrer (%u-%u) is %s\n", appidDebug->get_debug_session(),
-                    hsession->get_field_offset(REQ_REFERER_FID),
-                    hsession->get_field_end_offset(REQ_REFERER_FID),
-                    hsession->get_referer());
-        }
-
-        if (attribute_data->httpRequestCookie)
-        {
-            if (hsession->get_cookie())
-                if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
-                    hsession->set_chp_finished(false);
-
-            hsession->update_cookie((const uint8_t*)attribute_data->httpRequestCookie,
-                attribute_data->httpRequestCookieLen);
-            hsession->set_field_offset(REQ_COOKIE_FID, attribute_data->httpRequestCookieOffset);
-            hsession->set_field_end_offset(REQ_COOKIE_FID, attribute_data->httpRequestCookieEndOffset);
-            snort_free(attribute_data->httpRequestCookie);
-            attribute_data->httpRequestCookie = nullptr;
-            attribute_data->httpRequestCookieOffset = 0;
-            attribute_data->httpRequestCookieEndOffset = 0;
-            if (appidDebug->is_active())
-                LogMessage("AppIdDbg %s Cookie (%u-%u) is %s\n", appidDebug->get_debug_session(),
-                    hsession->get_field_offset(REQ_COOKIE_FID),
-                    hsession->get_field_offset(REQ_COOKIE_FID),
-                    hsession->get_cookie());
-        }
-
-        if (attribute_data->httpResponseContent)
-        {
-            if (hsession->get_content_type())
-                if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
-                    hsession->set_chp_finished(false);
-
-            hsession->update_content_type((const uint8_t*)attribute_data->httpResponseContent,
-                attribute_data->httpResponseContentLen);
-            snort_free(attribute_data->httpResponseContent);
-            attribute_data->httpResponseContent = nullptr;
-            asd.scan_flags |= SCAN_HTTP_CONTENT_TYPE_FLAG;
-        }
-
-        if (hsession->get_ptype_scan_count(RSP_LOCATION_FID) && attribute_data->httpResponseLocation)
-        {
-            if (hsession->get_location())
-                if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
-                    hsession->set_chp_finished(false);
-
-            hsession->update_location((const uint8_t*)attribute_data->httpResponseLocation,
-                attribute_data->httpResponseLocationLen);
-            snort_free(attribute_data->httpResponseLocation);
-            attribute_data->httpResponseLocation = nullptr;
-        }
-
-        if (attribute_data->httpRequestBody)
-        {
-            if (appidDebug->is_active())
-                LogMessage("AppIdDbg %s Got a request body %s\n", appidDebug->get_debug_session(),
-                    attribute_data->httpRequestBody);
-            if (hsession->get_req_body())
-                if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
-                    hsession->set_chp_finished(false);
-
-            hsession->update_req_body((const uint8_t*)attribute_data->httpRequestBody,
-                attribute_data->httpRequestBodyLen);
-            snort_free(attribute_data->httpRequestBody);
-            attribute_data->httpRequestBody = nullptr;
-        }
-
-        if (hsession->get_ptype_scan_count(RSP_BODY_FID) && attribute_data->httpResponseBody)
-        {
-            if (hsession->get_body())
-                if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
-                    hsession->set_chp_finished(false);
-
-            hsession->update_body((const uint8_t*)attribute_data->httpResponseBody,
-                attribute_data->httpResponseBodyLen);
-            snort_free(attribute_data->httpResponseBody);
-            attribute_data->httpResponseBody = nullptr;
-        }
-
-        if (attribute_data->numXffFields)
-            hsession->update_http_xff_address(attribute_data->xffFieldValue, attribute_data->numXffFields);
-
-        if (!hsession->is_chp_finished() || hsession->is_chp_hold_flow())
-        {
-            asd.set_session_flags(APPID_SESSION_CHP_INSPECTING);
-            if (thirdparty_appid_module)
-                thirdparty_appid_module->session_attr_set(asd.tpsession,
-                    TP_ATTR_CONTINUE_MONITORING);
-        }
-
-        if (attribute_data->httpResponseServer)
-        {
-            hsession->update_server((const uint8_t*)attribute_data->httpResponseServer,
-                strlen(attribute_data->httpResponseServer));
-            snort_free(attribute_data->httpResponseServer);
-            attribute_data->httpResponseServer = nullptr;
-            asd.scan_flags |= SCAN_HTTP_VENDOR_FLAG;
-        }
-
-        if (attribute_data->httpRequestXWorkingWith)
-        {
-            hsession->update_x_working_with((const uint8_t*)attribute_data->httpRequestXWorkingWith,
-                strlen(attribute_data->httpRequestXWorkingWith));
-            snort_free(attribute_data->httpRequestXWorkingWith);
-            attribute_data->httpRequestXWorkingWith = nullptr;
-            asd.scan_flags |= SCAN_HTTP_XWORKINGWITH_FLAG;
-        }
-    }
-    else if (ThirdPartyAppIDFoundProto(APP_ID_RTMP, proto_list) ||
-        ThirdPartyAppIDFoundProto(APP_ID_RTSP, proto_list))
-    {
-        AppIdHttpSession* hsession = asd.get_http_session();
-
-        if (!hsession->get_url())
-        {
-            if (attribute_data->httpRequestUrl)
-            {
-                hsession->set_url(attribute_data->httpRequestUrl);
-                snort_free(attribute_data->httpRequestUrl);
-                attribute_data->httpRequestUrl = nullptr;
-                asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
-            }
-        }
-
-        if ( !asd.config->mod_config->referred_appId_disabled && !hsession->get_referer() )
-        {
-            if (attribute_data->httpRequestReferer)
-            {
-                hsession->update_referer((const uint8_t*)attribute_data->httpRequestReferer, strlen(attribute_data->httpRequestReferer));
-                snort_free(attribute_data->httpRequestReferer);
-                attribute_data->httpRequestReferer = nullptr;
-            }
-        }
-
-        if (hsession->get_url() || (confidence == 100 &&
-            asd.session_packet_count > asd.config->mod_config->rtmp_max_packets))
-        {
-            if (hsession->get_url())
-            {
-                HttpPatternMatchers* http_matchers = HttpPatternMatchers::get_instance();
-
-                if ( ( ( http_matchers->get_appid_from_url(nullptr, hsession->get_url(),
-                    nullptr, hsession->get_referer(), &client_id, &serviceAppId,
-                    &payload_id, &referred_payload_app_id, 1) )
-                    ||
-                    ( http_matchers->get_appid_from_url(nullptr, hsession->get_url(), nullptr,
-                        hsession->get_referer(), &client_id, &serviceAppId, &payload_id,
-                    &referred_payload_app_id, 0) ) ) == 1 )
-                {
-                    // do not overwrite a previously-set client or service
-                    if (client_id <= APP_ID_NONE)
-                        asd.set_client_appid_data(client_id, nullptr);
-                    if (serviceAppId <= APP_ID_NONE)
-                        asd.set_service_appid_data(serviceAppId, nullptr, nullptr);
-
-                    // DO overwrite a previously-set data
-                    asd.set_payload_appid_data(payload_id, nullptr);
-                    asd.set_referred_payload_app_id_data(referred_payload_app_id);
-                }
-            }
-
-            if (thirdparty_appid_module)
-            {
-                thirdparty_appid_module->disable_flags(asd.tpsession,
-                    TP_SESSION_FLAG_ATTRIBUTE | TP_SESSION_FLAG_TUNNELING |
-                    TP_SESSION_FLAG_FUTUREFLOW);
-                thirdparty_appid_module->session_delete(asd.tpsession, 1);
-            }
-            asd.tpsession = nullptr;
-            asd.clear_session_flags(APPID_SESSION_APP_REINSPECT);
-        }
-    }
-    else if (ThirdPartyAppIDFoundProto(APP_ID_SSL, proto_list))
-    {
-        AppId tmpAppId = APP_ID_NONE;
-
-        if (thirdparty_appid_module && asd.tpsession)
-            tmpAppId = thirdparty_appid_module->session_appid_get(asd.tpsession);
-
-        asd.set_session_flags(APPID_SESSION_SSL_SESSION);
-
-        if (!asd.tsession)
-            asd.tsession = (TlsSession*)snort_calloc(sizeof(TlsSession));
-
-        if (!client_id)
-            asd.set_client_appid_data(APP_ID_SSL_CLIENT, nullptr);
-
-        if (attribute_data->tlsHost)
-        {
-            if (asd.tsession->tls_host)
-                snort_free(asd.tsession->tls_host);
-            asd.tsession->tls_host = attribute_data->tlsHost;
-            attribute_data->tlsHost = nullptr;
-            if (testSSLAppIdForReinspect(tmpAppId))
-                asd.scan_flags |= SCAN_SSL_HOST_FLAG;
-        }
-        if (testSSLAppIdForReinspect(tmpAppId))
-        {
-            if (attribute_data->tlsCname)
-            {
-                if (asd.tsession->tls_cname)
-                    snort_free(asd.tsession->tls_cname);
-                asd.tsession->tls_cname = attribute_data->tlsCname;
-                attribute_data->tlsCname = nullptr;
-            }
-            if (attribute_data->tlsOrgUnit)
-            {
-                if (asd.tsession->tls_orgUnit)
-                    snort_free(asd.tsession->tls_orgUnit);
-                asd.tsession->tls_orgUnit = attribute_data->tlsOrgUnit;
-                attribute_data->tlsOrgUnit = nullptr;
-            }
-        }
-    }
-    else if (ThirdPartyAppIDFoundProto(APP_ID_FTP_CONTROL, proto_list))
-    {
-        if (!asd.config->mod_config->ftp_userid_disabled && attribute_data->ftpCommandUser)
-        {
-            asd.client.update_user(APP_ID_FTP_CONTROL, attribute_data->ftpCommandUser);
-            asd.set_session_flags(APPID_SESSION_LOGIN_SUCCEEDED);
-            attribute_data->ftpCommandUser = nullptr;
-        }
-    }
-}
-
-void checkTerminateTpModule(AppIdSession& asd, uint16_t tpPktCount)
-{
-    AppIdHttpSession* hsession = asd.get_http_session();
-
-    if ((tpPktCount >= asd.config->mod_config->max_tp_flow_depth) ||
-        (asd.get_session_flags(APPID_SESSION_HTTP_SESSION | APPID_SESSION_APP_REINSPECT) ==
-        (APPID_SESSION_HTTP_SESSION | APPID_SESSION_APP_REINSPECT) &&
-        hsession->get_uri() && (!hsession->get_chp_candidate() || hsession->is_chp_finished())))
-    {
-        if (asd.tp_app_id == APP_ID_NONE)
-            asd.tp_app_id = APP_ID_UNKNOWN;
-        if (asd.payload.get_id() == APP_ID_NONE)
-            asd.payload.set_id(APP_ID_UNKNOWN);
-        if (thirdparty_appid_module)
-            thirdparty_appid_module->session_delete(asd.tpsession, 1);
-    }
-}
-
-bool do_third_party_discovery(AppIdSession& asd, IpProtocol protocol, const SfIp* ip,
-    Packet* p, int& direction)
-{
-    ThirdPartyAppIDAttributeData* tp_attribute_data;
-    AppId* tp_proto_list;
-    int tp_confidence;
-    bool isTpAppidDiscoveryDone = false;
-
-    //restart inspection by 3rd party
-    if (!asd.tp_reinspect_by_initiator && (direction == APP_ID_FROM_INITIATOR) &&
-        checkThirdPartyReinspect(p, asd))
-    {
-        asd.tp_reinspect_by_initiator = true;
-        asd.set_session_flags(APPID_SESSION_APP_REINSPECT);
-        if (appidDebug->is_active())
-            LogMessage("AppIdDbg %s 3rd party allow reinspect http\n",
-                appidDebug->get_debug_session());
-        asd.reset_session_data();
-    }
-
-    if (asd.tp_app_id == APP_ID_SSH && asd.payload.get_id() != APP_ID_SFTP &&
-        asd.session_packet_count >= MIN_SFTP_PACKET_COUNT &&
-        asd.session_packet_count < MAX_SFTP_PACKET_COUNT)
-    {
-        if ( p->ptrs.ip_api.tos() == 8 )
-        {
-            asd.payload.set_id(APP_ID_SFTP);
-            if (appidDebug->is_active())
-                LogMessage("AppIdDbg %s Payload is SFTP\n", appidDebug->get_debug_session());
-        }
-    }
-
-    Profile tpPerfStats_profile_context(tpPerfStats);
-
-    /*** Start of third-party processing. ***/
-    if (thirdparty_appid_module && !asd.get_session_flags(APPID_SESSION_NO_TPI)
-        && (!TPIsAppIdDone(asd.tpsession)
-        || asd.get_session_flags(APPID_SESSION_APP_REINSPECT | APPID_SESSION_APP_REINSPECT_SSL)))
-    {
-        // First SSL decrypted packet is now being inspected. Reset the flag so that SSL decrypted
-        // traffic gets processed like regular traffic from next packet onwards
-        if (asd.get_session_flags(APPID_SESSION_APP_REINSPECT_SSL))
-            asd.clear_session_flags(APPID_SESSION_APP_REINSPECT_SSL);
-
-        if (p->dsize || asd.config->mod_config->tp_allow_probes)
-        {
-            if (protocol != IpProtocol::TCP || (p->packet_flags & PKT_STREAM_ORDER_OK)
-                || asd.config->mod_config->tp_allow_probes)
-            {
-                Profile tpLibPerfStats_profile_context(tpLibPerfStats);
-                if (!asd.tpsession)
-                {
-                    if (!(asd.tpsession = thirdparty_appid_module->session_create()))
-                        FatalError("Could not allocate asd.tpsession data");
-                }  // debug output of packet content
-                thirdparty_appid_module->session_process(asd.tpsession, p, direction,
-                    &asd.tp_app_id, &tp_confidence,
-                    &tp_proto_list, &tp_attribute_data);
-
-                isTpAppidDiscoveryDone = true;
-                if (thirdparty_appid_module->session_state_get(asd.tpsession) ==
-                    TP_STATE_CLASSIFIED)
-                    asd.clear_session_flags(APPID_SESSION_APP_REINSPECT);
-
-                if (appidDebug->is_active())
-                    LogMessage("AppIdDbg %s 3rd party returned %d\n", appidDebug->get_debug_session(),
-                        asd.tp_app_id);
-
-                // For now, third party can detect HTTP/2 (w/o metadata) for
-                // some cases.  Treat it like HTTP w/ is_http2 flag set.
-                if ((asd.tp_app_id == APP_ID_HTTP2) && (tp_confidence == 100))
-                {
-                    if (appidDebug->is_active())
-                        LogMessage("AppIdDbg %s 3rd party saw HTTP/2\n", appidDebug->get_debug_session());
-
-                    asd.tp_app_id = APP_ID_HTTP;
-                    asd.is_http2 = true;
-                }
-                // if the third-party appId must be treated as a client, do it now
-                if (asd.app_info_mgr->get_app_info_flags(asd.tp_app_id, APPINFO_FLAG_TP_CLIENT))
-                    asd.client.set_id(asd.tp_app_id);
-
-                ProcessThirdPartyResults(asd, tp_confidence, tp_proto_list, tp_attribute_data);
-
-                if (asd.get_session_flags(APPID_SESSION_SSL_SESSION) &&
-                    !(asd.scan_flags & SCAN_SSL_HOST_FLAG))
-                {
-                    setSSLSquelch(p, 1, asd.tp_app_id, asd.get_inspector());
-                }
-
-                if (asd.app_info_mgr->get_app_info_flags(asd.tp_app_id, APPINFO_FLAG_IGNORE))
-                {
-                    if (appidDebug->is_active())
-                        LogMessage("AppIdDbg %s 3rd party ignored\n", appidDebug->get_debug_session());
-
-                    if (asd.get_session_flags(APPID_SESSION_HTTP_SESSION))
-                        asd.tp_app_id = APP_ID_HTTP;
-                    else
-                        asd.tp_app_id = APP_ID_NONE;
-                }
-            }
-            else
-            {
-                asd.tp_app_id = APP_ID_NONE;
-                if (appidDebug->is_active() && !asd.get_session_flags(
-                    APPID_SESSION_TPI_OOO_LOGGED))
-                {
-                    asd.set_session_flags(APPID_SESSION_TPI_OOO_LOGGED);
-                    LogMessage("AppIdDbg %s 3rd party packet out-of-order\n",
-                        appidDebug->get_debug_session());
-                }
-            }
-
-            if (thirdparty_appid_module->session_state_get(asd.tpsession) == TP_STATE_MONITORING)
-            {
-                thirdparty_appid_module->disable_flags(asd.tpsession,
-                    TP_SESSION_FLAG_ATTRIBUTE | TP_SESSION_FLAG_TUNNELING |
-                    TP_SESSION_FLAG_FUTUREFLOW);
-            }
-
-            if (asd.tp_app_id == APP_ID_SSL &&
-                (Stream::get_snort_protocol_id(p->flow) == snortId_for_ftp_data))
-            {
-                //  If we see SSL on an FTP data channel set tpAppId back
-                //  to APP_ID_NONE so the FTP preprocessor picks up the flow.
-                asd.tp_app_id = APP_ID_NONE;
-            }
-
-            if ( asd.tp_app_id > APP_ID_NONE
-                 && (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT)
-                 || asd.payload.get_id() > APP_ID_NONE) )
-            {
-                AppId snort_app_id;
-                AppIdHttpSession* hsession = asd.get_http_session();
-
-                // if the packet is HTTP, then search for via pattern
-                if ( asd.get_session_flags(APPID_SESSION_HTTP_SESSION) )
-                {
-                    snort_app_id = APP_ID_HTTP;
-                    //data should never be APP_ID_HTTP
-                    if (asd.tp_app_id != APP_ID_HTTP)
-                        asd.tp_payload_app_id = asd.tp_app_id;
-
-                    asd.tp_app_id = APP_ID_HTTP;
-                    // Handle HTTP tunneling and SSL possibly then being used in that tunnel
-                    if (asd.tp_app_id == APP_ID_HTTP_TUNNEL)
-                        asd.set_payload_appid_data(APP_ID_HTTP_TUNNEL, NULL);
-                    if ((asd.payload.get_id() == APP_ID_HTTP_TUNNEL) && (asd.tp_app_id ==
-                        APP_ID_SSL))
-                        asd.set_payload_appid_data(APP_ID_HTTP_SSL_TUNNEL, NULL);
-
-                    hsession->process_http_packet(direction);
-
-                    // If SSL over HTTP tunnel, make sure Snort knows that it's encrypted.
-                    if (asd.payload.get_id() == APP_ID_HTTP_SSL_TUNNEL)
-                        snort_app_id = APP_ID_SSL;
-
-                    if (is_third_party_appid_available(asd.tpsession) && asd.tp_app_id ==
-                        APP_ID_HTTP
-                        && !asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
-                    {
-                        asd.client_disco_state = APPID_DISCO_STATE_FINISHED;
-                        asd.set_session_flags(APPID_SESSION_CLIENT_DETECTED |
-                            APPID_SESSION_SERVICE_DETECTED);
-                        asd.client_disco_state = APPID_DISCO_STATE_FINISHED;
-                        asd.clear_session_flags(APPID_SESSION_CONTINUE);
-                        if (direction == APP_ID_FROM_INITIATOR)
-                        {
-                            ip = p->ptrs.ip_api.get_dst();
-                            asd.service_ip = *ip;
-                            asd.service_port = p->ptrs.dp;
-                        }
-                        else
-                        {
-                            ip = p->ptrs.ip_api.get_src();
-                            asd.service_ip = *ip;
-                            asd.service_port = p->ptrs.sp;
-                        }
-                    }
-                }
-                else if (asd.get_session_flags(APPID_SESSION_SSL_SESSION) && asd.tsession)
-                {
-                    asd.examine_ssl_metadata(p);
-                    uint16_t serverPort;
-                    AppId porAppId;
-                    serverPort = (direction == APP_ID_FROM_INITIATOR) ? p->ptrs.dp : p->ptrs.sp;
-                    porAppId = serverPort;
-                    if (asd.tp_app_id == APP_ID_SSL)
-                    {
-                        asd.tp_app_id = porAppId;
-                        //SSL policy determines IMAPS/POP3S etc before appId sees first server
-                        // packet
-                        asd.service.set_port_service_id(porAppId);
-                        if (appidDebug->is_active())
-                            LogMessage("AppIdDbg %s SSL is service %d, portServiceAppId %d\n",
-                                appidDebug->get_debug_session(),
-                                asd.tp_app_id, asd.service.get_port_service_id());
-                    }
-                    else
-                    {
-                        asd.tp_payload_app_id = asd.tp_app_id;
-                        asd.tp_app_id = porAppId;
-                        if (appidDebug->is_active())
-                            LogMessage("AppIdDbg %s SSL is %d\n", appidDebug->get_debug_session(),
-                                asd.tp_app_id);
-                    }
-                    snort_app_id = APP_ID_SSL;
-                }
-                else
-                {
-                    //for non-http protocols, tp id is treated like serviceId
-                    snort_app_id = asd.tp_app_id;
-                }
-
-                asd.sync_with_snort_protocol_id(snort_app_id, p);
-            }
-            else
-            {
-                if (protocol != IpProtocol::TCP ||
-                    (p->packet_flags & (PKT_STREAM_ORDER_OK | PKT_STREAM_ORDER_BAD)))
-                {
-                    if (direction == APP_ID_FROM_INITIATOR)
-                    {
-                        asd.init_tpPackets++;
-                        checkTerminateTpModule(asd, asd.init_tpPackets);
-                    }
-                    else
-                    {
-                        asd.resp_tpPackets++;
-                        checkTerminateTpModule(asd, asd.resp_tpPackets);
-                    }
-                }
-            }
-        }
-    }
-
-    if ( asd.tp_reinspect_by_initiator && checkThirdPartyReinspect(p, asd) )
-    {
-        asd.clear_session_flags(APPID_SESSION_APP_REINSPECT);
-        if (direction == APP_ID_FROM_RESPONDER)
-            asd.tp_reinspect_by_initiator = false; //toggle at OK response
-    }
-
-    return isTpAppidDiscoveryDone;
-}
-
-#endif
-
diff --git a/src/network_inspectors/appid/thirdparty_appid_utils.h b/src/network_inspectors/appid/thirdparty_appid_utils.h
deleted file mode 100644 (file)
index 7761c52..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-//--------------------------------------------------------------------------
-// Copyright (C) 2014-2018 Cisco and/or its affiliates. All rights reserved.
-// Copyright (C) 2005-2013 Sourcefire, Inc.
-//
-// 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.
-//--------------------------------------------------------------------------
-
-// thirdparty_appid_utils.h author Sourcefire Inc.
-
-#ifndef THIRDPARTY_APPID_UTILS_H
-#define THIRDPARTY_APPID_UTILS_H
-
-#include "thirdparty_appid_api.h"
-
-#include "main/thread.h"
-#include "flow/flow.h"
-#include "protocols/protocol_ids.h"
-#include "sfip/sf_ip.h"
-
-class AppIdModuleConfig;
-class AppIdSession;
-struct ThirdPartyAppIDModule;
-struct ThirdPartyAppIDAttributeData;
-namespace snort
-{
-struct Packet;
-}
-
-extern THREAD_LOCAL ThirdPartyAppIDModule* thirdparty_appid_module;
-
-void ThirdPartyAppIDInit(const AppIdModuleConfig*);
-void ThirdPartyAppIDReconfigure();
-void ThirdPartyAppIDFini();
-bool do_third_party_discovery(AppIdSession&, IpProtocol, const snort::SfIp*,  snort::Packet*, int&);
-
-inline bool is_third_party_appid_done(void* tp_session)
-{
-    if (thirdparty_appid_module)
-    {
-        unsigned state;
-
-        if (tp_session)
-            state = thirdparty_appid_module->session_state_get(tp_session);
-        else
-            state = TP_STATE_INIT;
-
-        return (state  == TP_STATE_CLASSIFIED || state == TP_STATE_TERMINATED
-               || state == TP_STATE_HA);
-    }
-
-    return true;
-}
-
-inline bool is_third_party_appid_available(void* tp_session)
-{
-    if (thirdparty_appid_module)
-    {
-        unsigned state;
-
-        if (tp_session)
-            state = thirdparty_appid_module->session_state_get(tp_session);
-        else
-            state = TP_STATE_INIT;
-
-        return (state == TP_STATE_CLASSIFIED || state == TP_STATE_TERMINATED
-               || state == TP_STATE_MONITORING);
-    }
-
-    return false;
-}
-
-#endif
-
diff --git a/src/network_inspectors/appid/tp_appid_module_api.h b/src/network_inspectors/appid/tp_appid_module_api.h
new file mode 100644 (file)
index 0000000..1b6ae75
--- /dev/null
@@ -0,0 +1,97 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2018-2018 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.
+//--------------------------------------------------------------------------
+
+// tp_appid_module_api.h author Silviu Minut <sminut@cisco.com>
+
+#ifndef TP_APPID_MODULE_API_H
+#define TP_APPID_MODULE_API_H
+
+#include <vector>
+#include <string>
+#include "tp_appid_types.h"
+
+#define THIRD_PARTY_APP_ID_API_VERSION 1
+
+class ThirdPartyConfig
+{
+public:
+    unsigned chp_body_collection_max;
+    unsigned ftp_userid_disabled : 1;
+    unsigned chp_body_collection_disabled : 1;
+    unsigned tp_allow_probes : 1;
+    unsigned http_upgrade_reporting_enabled : 1;
+    unsigned http_response_version_enabled : 1;
+    std::string tp_appid_config;
+    std::vector<std::string> xff_fields;
+    std::vector<std::string> old_xff_fields;
+
+    ThirdPartyConfig()
+    {
+        getXffFields();
+    }
+
+    void getXffFields()
+    {
+        xff_fields.clear();
+        xff_fields.push_back(HTTP_XFF_FIELD_X_FORWARDED_FOR);
+        xff_fields.push_back(HTTP_XFF_FIELD_TRUE_CLIENT_IP);
+    }
+};
+
+class ThirdPartyAppIDModule
+{
+public:
+
+    /* ThirdPartyAppIdConfig tpac; */
+
+    ThirdPartyAppIDModule(uint32_t ver, const char* mname)
+        : version(ver), name(mname) { }
+
+    virtual ~ThirdPartyAppIDModule() { }
+
+    uint32_t api_version() const { return version; }
+    const std::string& module_name() const { return name; }
+
+    virtual int pinit(ThirdPartyConfig&) = 0;
+    virtual int pfini() = 0;
+
+    virtual int tinit() = 0;
+    virtual int tfini() = 0;
+
+    virtual int reconfigure(const ThirdPartyConfig&) = 0;
+    virtual int print_stats() = 0;
+    virtual int reset_stats() = 0;
+
+private:
+
+    // No implicit constructor as derived classes need to provide
+    // version and name.
+    ThirdPartyAppIDModule() : version(0), name("") { }
+
+    const uint32_t version;
+    const std::string name;
+};
+
+// Function pointer to object factory that returns a pointer to a newly
+// created object of a derived class.
+// This needs to be exported (SO_PUBLIC) by any third party .so library.
+// Must return NULL if it fails to create the object.
+typedef ThirdPartyAppIDModule* (* CreateThirdPartyAppIDModule_t)();
+
+#endif
+
diff --git a/src/network_inspectors/appid/tp_appid_session_api.h b/src/network_inspectors/appid/tp_appid_session_api.h
new file mode 100644 (file)
index 0000000..9b1e3cc
--- /dev/null
@@ -0,0 +1,72 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2018-2018 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.
+//--------------------------------------------------------------------------
+
+// tp_appid_session_api.h author Silviu Minut <sminut@cisco.com>
+
+#ifndef TP_APPID_SESSION_API_H
+#define TP_APPID_SESSION_API_H
+
+#include <vector>
+#include <string>
+#include "appid_types.h"
+#include "application_ids.h"
+#include "tp_appid_types.h"
+
+namespace snort
+{
+struct Packet;
+}
+
+#define THIRD_PARTY_APP_ID_API_VERSION 1
+
+class ThirdPartyAppIDSession
+{
+public:
+
+    ThirdPartyAppIDSession()
+        : appid(APP_ID_NONE), confidence(100), state(TP_STATE_INIT) { }
+    virtual ~ThirdPartyAppIDSession() { }
+
+    virtual bool reset() = 0;            // just reset state
+    virtual bool process(const snort::Packet&,
+        AppidSessionDirection direction,
+        std::vector<AppId>& proto_list,
+        ThirdPartyAppIDAttributeData& attribute_data) = 0;
+
+    virtual int disable_flags(uint32_t session_flags) = 0;
+    virtual TPState get_state() { return state; }
+    virtual void set_state(TPState) = 0;
+    virtual void clear_attr(TPSessionAttr) = 0;
+    virtual void set_attr(TPSessionAttr) = 0;
+    virtual unsigned get_attr(TPSessionAttr) = 0;
+    virtual AppId get_appid(int& conf) { conf=confidence; return appid; }
+
+protected:
+    AppId appid;
+    int confidence;
+    TPState state;
+};
+
+// Function pointer to object factory that returns a pointer to a newly
+// created object of a derived class.
+// This needs to be exported (SO_PUBLIC) by any third party .so library.
+// Must return NULL if it fails to create the object.
+typedef ThirdPartyAppIDSession* (* CreateThirdPartyAppIDSession_t)();
+
+#endif
+
diff --git a/src/network_inspectors/appid/tp_appid_types.h b/src/network_inspectors/appid/tp_appid_types.h
new file mode 100644 (file)
index 0000000..b89b505
--- /dev/null
@@ -0,0 +1,265 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2014-2018 Cisco and/or its affiliates. All rights reserved.
+// Copyright (C) 2005-2013 Sourcefire, Inc.
+//
+// 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.
+//--------------------------------------------------------------------------
+
+// tp_appid_types.h author Sourcefire Inc.
+
+#ifndef TP_APPID_TYPES_H
+#define TP_APPID_TYPES_H
+
+#include <cstdint>
+#include <string>
+
+#include "http_xff_fields.h"
+
+using std::string;
+
+// FIXIT-L: these need to disappear from here and go to appid_navl.
+enum TPFlags
+{
+    TP_SESSION_FLAG_DPI        = 0x00000001,
+    TP_SESSION_FLAG_MUTABLE    = 0x00000002,
+    TP_SESSION_FLAG_FUTUREFLOW = 0x00000004,
+    TP_SESSION_FLAG_ATTRIBUTE  = 0x00000008,
+    TP_SESSION_FLAG_TUNNELING  = 0x00000010
+};
+
+enum TPState
+{
+    TP_STATE_INIT,
+    TP_STATE_TERMINATED,
+    TP_STATE_INSPECTING,
+    TP_STATE_MONITORING,
+    TP_STATE_CLASSIFIED,
+    TP_STATE_HA = 21
+};
+
+enum TPSessionAttr
+{
+    TP_ATTR_CONTINUE_MONITORING     = (1 << 0),
+    TP_ATTR_COPY_RESPONSE_CONTENT   = (1 << 1),
+    TP_ATTR_COPY_RESPONSE_LOCATION  = (1 << 2),
+    TP_ATTR_COPY_RESPONSE_BODY      = (1 << 3),
+};
+
+#define TPAD_GET(func)                                          \
+    const string* func(bool caller_owns_it = 0)                 \
+    {                                                           \
+        const string* tmp = func ## _buf;                       \
+        if (caller_owns_it)                                     \
+            func ## _buf = nullptr;                             \
+        return tmp;                                             \
+    }
+
+#define TPAD_SET_OFFSET(func)                                   \
+    void set_ ## func(const char* buf, size_t len, uint16_t offset, uint16_t endOffset)                                                         \
+    {                                                           \
+        if (func ## _buf)                                       \
+            delete func ## _buf;                                \
+        func ## _buf=new string(buf,len);                       \
+        func ## _offset=offset;                                 \
+        func ## _end_offset=endOffset;                          \
+    }
+
+#define TPAD_SET(func)                                          \
+    void set_ ## func(const char* buf, size_t len)              \
+    {                                                           \
+        if (func ## _buf)                                       \
+            delete func ## _buf;                                \
+        func ## _buf=new string(buf,len);                       \
+    }
+
+// The ThirdPartyAppIDAttributeData class acts as a per packet cache for
+// various fields coming out of that packet, that need to be analyzed
+// simultaneously.
+//
+// Consumers of these fields should grab the pointers and avoid an extra copy,
+// if speed is of the essence. Once they grab a string* pointer from
+// ThirdPartyAppIDAttributeData, then they own it. That is, the consumers
+// are responsible for deleting the pointers they grabbed.
+//
+// If you get it, you own it.
+//
+// However, currently tp_appid_utils.cc retrieves these, but the
+// AppIdHttpSession::set() functions make copies anyway.
+// Therefore, for now there is no need for any caller to own these
+// pointers yet. We therefore allow callers to just peek at the string*
+// buffers inside this class, without owning them. Hence the "caller_owns_it"
+// flag in the get functions below.
+//
+class ThirdPartyAppIDAttributeData
+{
+    string* spdy_request_path_buf = nullptr;
+    string* spdy_request_scheme_buf = nullptr;
+    string* spdy_request_host_buf = nullptr;
+    string* http_request_url_buf = nullptr;
+    string* http_request_uri_buf = nullptr;
+    string* http_request_host_buf = nullptr;
+    string* http_request_cookie_buf = nullptr;
+    string* http_request_via_buf = nullptr;
+    string* http_response_via_buf = nullptr;
+    string* http_response_upgrade_buf = nullptr;
+    string* http_request_user_agent_buf = nullptr;
+    string* http_response_version_buf = nullptr;
+    string* http_response_code_buf = nullptr;
+    string* http_response_content_buf = nullptr;
+    string* http_response_location_buf = nullptr;
+    string* http_response_body_buf = nullptr;
+    string* http_request_body_buf = nullptr;
+    string* http_response_server_buf = nullptr;
+    string* http_request_x_working_with_buf = nullptr;
+    string* tls_host_buf = nullptr;
+    string* tls_cname_buf = nullptr;
+    string* tls_org_unit_buf = nullptr;
+    string* http_request_referer_buf = nullptr;
+    string* ftp_command_user_buf = nullptr;
+
+    uint16_t http_request_uri_offset = 0;
+    uint16_t http_request_uri_end_offset = 0;
+
+    uint16_t http_request_cookie_offset = 0;
+    uint16_t http_request_cookie_end_offset = 0;
+
+    uint16_t http_request_user_agent_offset = 0;
+    uint16_t http_request_user_agent_end_offset = 0;
+
+    uint16_t http_request_host_offset = 0;
+    uint16_t http_request_host_end_offset = 0;
+
+    uint16_t http_request_referer_offset = 0;
+    uint16_t http_request_referer_end_offset = 0;
+
+    uint16_t spdy_request_host_offset = 0;
+    uint16_t spdy_request_host_end_offset = 0;
+
+    uint16_t spdy_request_path_offset = 0;
+    uint16_t spdy_request_path_end_offset = 0;
+
+    // FIXIT-L: make these private too. Figure out how these get set in tp.
+
+public:
+    XffFieldValue xffFieldValue[HTTP_MAX_XFF_FIELDS];
+    uint8_t numXffFields = 0;
+
+    ThirdPartyAppIDAttributeData() { }
+
+    ~ThirdPartyAppIDAttributeData()
+    {
+        // Only delete the pointers that we own (i.e. non null pointers).
+        if (spdy_request_path_buf) delete spdy_request_path_buf;
+        if (spdy_request_scheme_buf) delete spdy_request_scheme_buf;
+        if (spdy_request_host_buf) delete spdy_request_host_buf;
+        if (http_request_url_buf) delete http_request_url_buf;
+        if (http_request_uri_buf) delete http_request_uri_buf;
+        if (http_request_host_buf) delete http_request_host_buf;
+        if (http_request_cookie_buf) delete http_request_cookie_buf;
+        if (http_request_via_buf) delete http_request_via_buf;
+        if (http_response_via_buf) delete http_response_via_buf;
+        if (http_response_upgrade_buf) delete http_response_upgrade_buf;
+        if (http_request_user_agent_buf) delete http_request_user_agent_buf;
+        if (http_response_version_buf) delete http_response_version_buf;
+        if (http_response_code_buf) delete http_response_code_buf;
+        if (http_response_content_buf) delete http_response_content_buf;
+        if (http_response_location_buf) delete http_response_location_buf;
+        if (http_response_body_buf) delete http_response_body_buf;
+        if (http_request_body_buf) delete http_request_body_buf;
+        if (http_response_server_buf) delete http_response_server_buf;
+        if (http_request_x_working_with_buf) delete http_request_x_working_with_buf;
+        if (tls_host_buf) delete tls_host_buf;
+        if (tls_cname_buf) delete tls_cname_buf;
+        if (tls_org_unit_buf) delete tls_org_unit_buf;
+        if (http_request_referer_buf) delete http_request_referer_buf;
+        if (ftp_command_user_buf) delete ftp_command_user_buf;
+    }
+
+    // Note: calling these 2 times in a row, the 2nd time it returns null.
+    TPAD_GET(spdy_request_path)
+    TPAD_GET(spdy_request_scheme)
+    TPAD_GET(spdy_request_host)
+    TPAD_GET(http_request_url)
+    TPAD_GET(http_request_uri)
+    TPAD_GET(http_request_host)
+    TPAD_GET(http_request_cookie)
+    TPAD_GET(http_request_via)
+    TPAD_GET(http_response_via)
+    TPAD_GET(http_response_upgrade)
+    TPAD_GET(http_request_user_agent)
+    TPAD_GET(http_response_version)
+    TPAD_GET(http_response_code)
+    TPAD_GET(http_response_content)
+    TPAD_GET(http_response_location)
+    TPAD_GET(http_response_body)
+    TPAD_GET(http_request_body)
+    TPAD_GET(http_response_server)
+    TPAD_GET(http_request_x_working_with)
+    TPAD_GET(tls_host)
+    TPAD_GET(tls_cname)
+    TPAD_GET(tls_org_unit)
+    TPAD_GET(http_request_referer)
+    TPAD_GET(ftp_command_user)
+
+    uint16_t http_request_uri_begin() { return http_request_uri_offset; }
+    uint16_t http_request_uri_end() { return http_request_uri_end_offset; }
+
+    uint16_t http_request_cookie_begin() { return http_request_cookie_offset; }
+    uint16_t http_request_cookie_end() { return http_request_cookie_end_offset; }
+
+    uint16_t http_request_user_agent_begin() { return http_request_user_agent_offset; }
+    uint16_t http_request_user_agent_end() { return http_request_user_agent_end_offset; }
+
+    uint16_t http_request_host_begin() { return http_request_host_offset; }
+    uint16_t http_request_host_end() { return http_request_host_end_offset; }
+
+    uint16_t http_request_referer_begin() { return http_request_referer_offset; }
+    uint16_t http_request_referer_end() { return http_request_referer_end_offset; }
+
+    uint16_t spdy_request_host_begin() { return spdy_request_host_offset; }
+    uint16_t spdy_request_host_end() { return spdy_request_host_end_offset; }
+
+    uint16_t spdy_request_path_begin() { return spdy_request_path_offset; }
+    uint16_t spdy_request_path_end() { return spdy_request_path_end_offset; }
+
+    // set functions
+    TPAD_SET_OFFSET(spdy_request_path)
+    TPAD_SET(spdy_request_scheme)
+    TPAD_SET_OFFSET(spdy_request_host)
+    TPAD_SET(http_request_url)
+    TPAD_SET_OFFSET(http_request_uri)
+    TPAD_SET_OFFSET(http_request_host)
+    TPAD_SET_OFFSET(http_request_cookie)
+    TPAD_SET(http_request_via)
+    TPAD_SET(http_response_via)
+    TPAD_SET(http_response_upgrade)
+    TPAD_SET_OFFSET(http_request_user_agent)
+    TPAD_SET(http_response_version)
+    TPAD_SET(http_response_code)
+    TPAD_SET(http_response_content)
+    TPAD_SET(http_response_location)
+    TPAD_SET(http_response_body)
+    TPAD_SET(http_request_body)
+    TPAD_SET(http_response_server)
+    TPAD_SET(http_request_x_working_with)
+    TPAD_SET(tls_host)
+    TPAD_SET(tls_cname)
+    TPAD_SET(tls_org_unit)
+    TPAD_SET_OFFSET(http_request_referer)
+    TPAD_SET(ftp_command_user)
+};
+
+#endif
+
diff --git a/src/network_inspectors/appid/tp_appid_utils.cc b/src/network_inspectors/appid/tp_appid_utils.cc
new file mode 100644 (file)
index 0000000..0889118
--- /dev/null
@@ -0,0 +1,843 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2014-2018 Cisco and/or its affiliates. All rights reserved.
+// Copyright (C) 2005-2013 Sourcefire, Inc.
+//
+// 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.
+//--------------------------------------------------------------------------
+
+// tp_appid_utils.cc author Sourcefire Inc.
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <iostream>
+#include <dlfcn.h>
+
+#include "log/messages.h"
+#include "profiler/profiler.h"
+#include "protocols/packet.h"
+#include "stream/stream.h"
+
+#include "app_info_table.h"
+#include "appid_config.h"
+#include "appid_debug.h"
+#include "appid_http_session.h"
+#include "appid_inspector.h"
+#include "detector_plugins/http_url_patterns.h"
+#include "service_plugins/service_ssl.h"
+#include "protocols/packet.h"
+#include "main/snort_debug.h"
+#include "log/messages.h"
+#include "profiler/profiler.h"
+#include "stream/stream.h"
+#include "tp_appid_types.h"
+#include "tp_appid_session_api.h"
+#include "tp_lib_handler.h"
+
+using namespace std;
+using namespace snort;
+
+THREAD_LOCAL ProfileStats tpLibPerfStats;
+THREAD_LOCAL ProfileStats tpPerfStats;
+
+bool do_discovery(AppIdSession&, IpProtocol, Packet*, AppidSessionDirection&);
+
+// std::vector does not have a convenient find() function.
+// There is a generic std::find() in <algorithm>, but this might be faster.
+template<class Type_t, class ValType_t>
+static bool contains(const vector<Type_t>& vec, const ValType_t& val)
+{
+    const Type_t* v=&vec[0], * vend=v+vec.size();
+    while (v<vend)
+        if ( *(v++)==(Type_t)val )
+            return true;
+    return false;
+}
+
+// FIXIT-L bogus placeholder for this func, need to find out what it should do
+static inline bool is_appid_done(const ThirdPartyAppIDSession* tpsession)
+{
+    UNUSED(tpsession);
+    return false;
+}
+
+static inline bool check_reinspect(const Packet* p, const AppIdSession& asd)
+{
+    return p->dsize && !asd.get_session_flags(APPID_SESSION_NO_TPI) &&
+        asd.get_session_flags(APPID_SESSION_HTTP_SESSION) && is_appid_done(asd.tpsession);
+}
+
+static inline int check_ssl_appid_for_reinspect(AppId app_id)
+{
+    if (app_id <= SF_APPID_MAX &&
+        (app_id == APP_ID_SSL ||
+        AppInfoManager::get_instance().get_app_info_flags(app_id,
+        APPINFO_FLAG_SSL_INSPECT)))
+        return 1;
+    else
+        return 0;
+}
+
+// FIXIT-M: All the AppIdHttpSession::set/update functions make an
+// internal copy. That needs to change, as that's already the 2nd copy - the
+// first copy happens when third party calls ThirdPartyAppIDAttributeData::set
+// functions and that's unavoidable.
+// Consider passing all the metadata pointers (e.g. host, url, etc.)
+// to AppIdHttpSession directly from the thirdparty.so callbacks.
+//
+// Or, register observers with THirdPartyAppIDAttributeData and modify the
+// set functions to copy the tp buffers directly into the appropriate observer.
+static inline void process_http_session(AppIdSession& asd,
+    ThirdPartyAppIDAttributeData& attribute_data)
+{
+    AppIdHttpSession* hsession = asd.get_http_session();
+    const string* field=0;
+
+    hsession->reset_ptype_scan_counts();
+
+    if (asd.get_session_flags(APPID_SESSION_SPDY_SESSION))
+    {
+        const string* spdyRequestScheme=attribute_data.spdy_request_scheme();
+        const string* spdyRequestHost=attribute_data.spdy_request_host();
+        const string* spdyRequestPath=attribute_data.spdy_request_path();
+
+        if (spdyRequestScheme && spdyRequestHost && spdyRequestPath )
+        {
+            static const char httpsScheme[] = "https";
+            static const char httpScheme[] = "http";
+            std::string url;
+
+            if (asd.get_session_flags(APPID_SESSION_DECRYPTED)
+                &&
+                memcmp(spdyRequestScheme->c_str(), httpScheme,
+                sizeof(httpScheme) - 1) == 0)
+            {
+                url = httpsScheme;
+            }
+            else
+            {
+                url = *spdyRequestScheme;
+            }
+
+            if (hsession->get_url())
+                hsession->set_chp_finished(false);
+
+            url += "://" + *spdyRequestHost + *spdyRequestPath;
+            hsession->set_url(url.c_str());
+            asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
+        }
+
+        if (spdyRequestHost)
+        {
+            if (hsession->get_host())
+                hsession->set_chp_finished(false);
+
+            hsession->update_host((const uint8_t*)spdyRequestHost->c_str(),
+                spdyRequestHost->size());
+            hsession->set_field_offset(REQ_HOST_FID,
+                attribute_data.spdy_request_host_begin());
+            hsession->set_field_end_offset(REQ_HOST_FID,
+                attribute_data.spdy_request_host_end());
+            if (appidDebug->is_active())
+                LogMessage("AppIdDbg %s SPDY host (%u-%u) is %s\n",
+                    appidDebug->get_debug_session(),
+                    hsession->get_field_offset(REQ_HOST_FID),
+                    hsession->get_field_end_offset(REQ_HOST_FID), hsession->get_host());
+            asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
+        }
+
+        if (spdyRequestPath)
+        {
+            if (hsession->get_uri())
+                hsession->set_chp_finished(false);
+
+            hsession->update_uri((const uint8_t*)spdyRequestPath->c_str(),
+                spdyRequestPath->size());
+            hsession->set_field_offset(REQ_URI_FID, attribute_data.spdy_request_path_begin());
+            hsession->set_field_end_offset(REQ_URI_FID, attribute_data.spdy_request_path_end());
+            if (appidDebug->is_active())
+                LogMessage("AppIdDbg %s SPDY URI (%u-%u) is %s\n", appidDebug->get_debug_session(),
+                    hsession->get_field_offset(REQ_URI_FID),
+                    hsession->get_field_end_offset(REQ_URI_FID), hsession->get_uri());
+        }
+    }
+    else
+    {
+        if ( (field=attribute_data.http_request_host()) != nullptr )
+        {
+            if (hsession->get_host())
+                if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
+                    hsession->set_chp_finished(false);
+
+            hsession->update_host((const uint8_t*)field->c_str(),
+                field->size());
+            hsession->set_field_offset(REQ_HOST_FID, attribute_data.http_request_host_begin());
+            hsession->set_field_end_offset(REQ_HOST_FID, attribute_data.http_request_host_end());
+            if (appidDebug->is_active())
+                LogMessage("AppIdDbg %s HTTP host is %s\n",
+                    appidDebug->get_debug_session(), field->c_str());
+            asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
+        }
+
+        if ( (field=attribute_data.http_request_url()) != nullptr )
+        {
+            static const char httpScheme[] = "http://";
+
+            if (hsession->get_url() and !asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
+                hsession->set_chp_finished(false);
+
+            // Change http to https if session was decrypted.
+            if (asd.get_session_flags(APPID_SESSION_DECRYPTED) and
+                memcmp(field->c_str(), httpScheme, sizeof(httpScheme)-1)==0)
+            {
+                std::string url("https://");
+                url.append(field->c_str() + sizeof(httpScheme)-1);
+                hsession->set_url(url.c_str());
+            }
+            else
+                hsession->set_url(field->c_str());
+
+            asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
+        }
+
+        if ( (field=attribute_data.http_request_uri()) != nullptr)
+        {
+            if (hsession->get_uri())
+                if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
+                    hsession->set_chp_finished(false);
+
+            hsession->update_uri((const uint8_t*)field->c_str(),field->size());
+            hsession->set_field_offset(REQ_URI_FID, attribute_data.http_request_uri_begin());
+            hsession->set_field_end_offset(REQ_URI_FID, attribute_data.http_request_uri_end());
+            if (appidDebug->is_active())
+                LogMessage("AppIdDbg %s uri (%u-%u) is %s\n", appidDebug->get_debug_session(),
+                    hsession->get_field_offset(REQ_URI_FID),
+                    hsession->get_field_end_offset(REQ_URI_FID), hsession->get_uri());
+        }
+    }
+
+    // FIXIT-M: these cases are duplicate.
+    if ( (field=attribute_data.http_request_via()) != nullptr )
+    {
+        if (hsession->get_via())
+            if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
+                hsession->set_chp_finished(false);
+
+        hsession->update_via((const uint8_t*)field->c_str(),field->size());
+        asd.scan_flags |= SCAN_HTTP_VIA_FLAG;
+    }
+    else if ( (field=attribute_data.http_response_via()) != nullptr )
+    {
+        if (hsession->get_via())
+            if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
+                hsession->set_chp_finished(false);
+
+        hsession->update_via((const uint8_t*)field->c_str(),field->size());
+        asd.scan_flags |= SCAN_HTTP_VIA_FLAG;
+    }
+
+    if ( (field=attribute_data.http_request_user_agent()) != nullptr )
+    {
+        if (hsession->get_user_agent())
+            if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
+                hsession->set_chp_finished(false);
+
+        hsession->update_useragent((const uint8_t*)field->c_str(),field->size());
+        if (appidDebug->is_active())
+            LogMessage("AppIdDbg %s User Agent (%u-%u) is %s\n",
+                appidDebug->get_debug_session(), hsession->get_field_offset(REQ_AGENT_FID),
+                hsession->get_field_end_offset(REQ_AGENT_FID), hsession->get_user_agent());
+        asd.scan_flags |= SCAN_HTTP_USER_AGENT_FLAG;
+    }
+
+    // Check to see if third party discovered HTTP/2. - once it supports it...
+    if ( (field=attribute_data.http_response_version()) != nullptr )
+    {
+        if (appidDebug->is_active())
+            LogMessage("AppIdDbg %s HTTP response version is %s\n",
+                appidDebug->get_debug_session(), field->c_str());
+        if (strncmp(field->c_str(), "HTTP/2", 6) == 0)
+        {
+            if (appidDebug->is_active())
+                LogMessage("AppIdDbg %s 3rd party detected and parsed HTTP/2\n",
+                    appidDebug->get_debug_session());
+            asd.is_http2 = true;
+        }
+    }
+
+    if ( (field=attribute_data.http_response_code()) != nullptr )
+    {
+        if (appidDebug->is_active())
+            LogMessage("AppIdDbg %s HTTP response code is %s\n",
+                appidDebug->get_debug_session(), field->c_str());
+        if (hsession->get_response_code())
+            if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
+                hsession->set_chp_finished(false);
+
+        hsession->update_response_code((const char*)field->c_str());
+    }
+
+    // Check to see if we've got an upgrade to HTTP/2 (if enabled).
+    //  - This covers the "without prior knowledge" case (i.e., the client
+    //    asks the server to upgrade to HTTP/2).
+    if ( (field=attribute_data.http_response_upgrade()) != nullptr )
+    {
+        if (appidDebug->is_active())
+            LogMessage("AppIdDbg %s HTTP response upgrade is %s\n",
+                appidDebug->get_debug_session(),field->c_str());
+
+        if (asd.config->mod_config->http2_detection_enabled)
+            if ( hsession->get_response_code()
+                && (strncmp(hsession->get_response_code(), "101", 3) == 0) )
+                if (strncmp(field->c_str(), "h2c", 3) == 0)
+                {
+                    if (appidDebug->is_active())
+                        LogMessage("AppIdDbg %s Got an upgrade to HTTP/2\n",
+                            appidDebug->get_debug_session());
+                    asd.is_http2 = true;
+                }
+    }
+
+    if ( (field=attribute_data.http_request_referer()) != nullptr )
+    {
+        if (appidDebug->is_active())
+            LogMessage("AppIdDbg %s referrer is %s\n",
+                appidDebug->get_debug_session(), field->c_str());
+        if (hsession->get_referer())
+            if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
+                hsession->set_chp_finished(false);
+
+        hsession->update_referer((const uint8_t*)field->c_str(), field->size());
+        hsession->set_field_offset(REQ_REFERER_FID, attribute_data.http_request_referer_begin());
+        hsession->set_field_end_offset(REQ_REFERER_FID, attribute_data.http_request_referer_end());
+        if (appidDebug->is_active())
+            LogMessage("AppIdDbg %s Referer (%u-%u) is %s\n", appidDebug->get_debug_session(),
+                hsession->get_field_offset(REQ_REFERER_FID),
+                hsession->get_field_end_offset(REQ_REFERER_FID),
+                hsession->get_referer());
+    }
+
+    if ( (field=attribute_data.http_request_cookie()) != nullptr )
+    {
+        if (hsession->get_cookie())
+            if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
+                hsession->set_chp_finished(false);
+
+        hsession->update_cookie((const uint8_t*)field->c_str(), field->size());
+        hsession->set_field_offset(REQ_COOKIE_FID, attribute_data.http_request_cookie_begin());
+        hsession->set_field_end_offset(REQ_COOKIE_FID, attribute_data.http_request_cookie_end());
+        // FIXIT-M currently we're not doing this, check if necessary
+        // attribute_data.httpRequestCookie = nullptr;
+        // attribute_data.httpRequestCookieOffset = 0;
+        // attribute_data.httpRequestCookieEndOffset = 0;
+        if (appidDebug->is_active())
+            LogMessage("AppIdDbg %s cookie (%u-%u) is %s\n", appidDebug->get_debug_session(),
+                hsession->get_field_offset(REQ_COOKIE_FID),
+                hsession->get_field_offset(REQ_COOKIE_FID),
+                hsession->get_cookie());
+    }
+
+    if ( (field=attribute_data.http_response_content()) != nullptr )
+    {
+        if (hsession->get_content_type())
+            if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
+                hsession->set_chp_finished(false);
+
+        hsession->update_content_type((const uint8_t*)field->c_str(), field->size());
+        asd.scan_flags |= SCAN_HTTP_CONTENT_TYPE_FLAG;
+    }
+
+    if (hsession->get_ptype_scan_count(RSP_LOCATION_FID) &&
+        (field=attribute_data.http_response_location()) != nullptr)
+    {
+        if (hsession->get_location())
+            if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
+                hsession->set_chp_finished(false);
+
+        hsession->update_location((const uint8_t*)field->c_str(), field->size());
+    }
+
+    if ( (field=attribute_data.http_request_body()) != nullptr )
+    {
+        if (appidDebug->is_active())
+            LogMessage("AppIdDbg %s got a request body %s\n",
+                appidDebug->get_debug_session(), field->c_str());
+        if (hsession->get_req_body())
+            if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
+                hsession->set_chp_finished(false);
+        hsession->update_req_body((const uint8_t*)field->c_str(), field->size());
+    }
+
+    if (hsession->get_ptype_scan_count(RSP_BODY_FID) &&
+        (field=attribute_data.http_response_body()) != nullptr)
+    {
+        if (hsession->get_body())
+            if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
+                hsession->set_chp_finished(false);
+
+        hsession->update_body((const uint8_t*)field->c_str(), field->size());
+    }
+
+    if (attribute_data.numXffFields)
+        hsession->update_http_xff_address(attribute_data.xffFieldValue,
+            attribute_data.numXffFields);
+
+    if (!hsession->is_chp_finished() || hsession->is_chp_hold_flow())
+    {
+        asd.set_session_flags(APPID_SESSION_CHP_INSPECTING);
+        asd.tpsession->set_attr(TP_ATTR_CONTINUE_MONITORING);
+    }
+
+    if ( (field=attribute_data.http_response_server()) != nullptr)
+    {
+        hsession->update_server((const uint8_t*)field->c_str(), field->size());
+        asd.scan_flags |= SCAN_HTTP_VENDOR_FLAG;
+    }
+
+    if ( (field=attribute_data.http_request_x_working_with()) != nullptr )
+    {
+        hsession->update_x_working_with((const uint8_t*)field->c_str(), field->size());
+        asd.scan_flags |= SCAN_HTTP_XWORKINGWITH_FLAG;
+    }
+}
+
+static inline void process_rtmp(AppIdSession& asd,
+    ThirdPartyAppIDAttributeData& attribute_data, int confidence)
+{
+    AppIdHttpSession* hsession = asd.get_http_session();
+    AppId serviceAppId = 0;
+    AppId client_id = 0;
+    AppId payload_id = 0;
+    AppId referred_payload_app_id = 0;
+
+    const string* field=0;
+
+    if (!hsession->get_url())
+    {
+        if ( (field=attribute_data.http_request_url()) != nullptr )
+        {
+            hsession->set_url(field->c_str());
+            asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
+        }
+    }
+
+    if ( !asd.config->mod_config->referred_appId_disabled && !hsession->get_referer() )
+    {
+        if ( (field=attribute_data.http_request_referer()) != nullptr )
+        {
+            hsession->update_referer((const uint8_t*)field->c_str(), field->size());
+        }
+    }
+
+    if (hsession->get_url() || (confidence == 100 &&
+        asd.session_packet_count > asd.config->mod_config->rtmp_max_packets))
+    {
+        if (hsession->get_url())
+        {
+            HttpPatternMatchers* http_matchers = HttpPatternMatchers::get_instance();
+
+            if ( ( ( http_matchers->get_appid_from_url(nullptr, hsession->get_url(),
+                nullptr, hsession->get_referer(), &client_id, &serviceAppId,
+                &payload_id, &referred_payload_app_id, 1) )
+                ||
+                ( http_matchers->get_appid_from_url(nullptr, hsession->get_url(), nullptr,
+                hsession->get_referer(), &client_id, &serviceAppId, &payload_id,
+                &referred_payload_app_id, 0) ) ) == 1 )
+            {
+                // do not overwrite a previously-set client or service
+                if (client_id <= APP_ID_NONE)
+                    asd.set_client_appid_data(client_id, nullptr);
+                if (serviceAppId <= APP_ID_NONE)
+                    asd.set_service_appid_data(serviceAppId, nullptr, nullptr);
+
+                // DO overwrite a previously-set data
+                asd.set_payload_appid_data(payload_id, nullptr);
+                asd.set_referred_payload_app_id_data(referred_payload_app_id);
+            }
+        }
+
+        asd.tpsession->disable_flags(
+            TP_SESSION_FLAG_ATTRIBUTE | TP_SESSION_FLAG_TUNNELING |
+            TP_SESSION_FLAG_FUTUREFLOW);
+        asd.tpsession->reset();
+        asd.clear_session_flags(APPID_SESSION_APP_REINSPECT);
+    }
+}
+
+static inline void process_ssl(AppIdSession& asd,
+    ThirdPartyAppIDAttributeData& attribute_data)
+{
+    AppId tmpAppId = APP_ID_NONE;
+    int tmpConfidence = 0;
+    const string* field=0;
+
+    // if (tp_appid_module && asd.tpsession)
+    tmpAppId = asd.tpsession->get_appid(tmpConfidence);
+
+    asd.set_session_flags(APPID_SESSION_SSL_SESSION);
+
+    if (!asd.tsession)
+        asd.tsession = (TlsSession*)snort_calloc(sizeof(TlsSession));
+
+    if (!asd.client.get_id())
+        asd.set_client_appid_data(APP_ID_SSL_CLIENT, nullptr);
+
+    if ( (field=attribute_data.tls_host()) != nullptr )
+    {
+        if (asd.tsession->tls_host)
+            snort_free(asd.tsession->tls_host);
+        asd.tsession->tls_host = snort_strdup(field->c_str());
+        if (check_ssl_appid_for_reinspect(tmpAppId))
+            asd.scan_flags |= SCAN_SSL_HOST_FLAG;
+    }
+
+    if (check_ssl_appid_for_reinspect(tmpAppId))
+    {
+        if ( (field=attribute_data.tls_cname()) != nullptr )
+        {
+            if (asd.tsession->tls_cname)
+                snort_free(asd.tsession->tls_cname);
+            asd.tsession->tls_cname = snort_strdup(field->c_str());
+        }
+
+        if ( (field=attribute_data.tls_org_unit()) != nullptr )
+        {
+            if (asd.tsession->tls_orgUnit)
+                snort_free(asd.tsession->tls_orgUnit);
+            asd.tsession->tls_orgUnit = snort_strdup(field->c_str());
+        }
+    }
+}
+
+static inline void process_ftp_control(AppIdSession& asd,
+    ThirdPartyAppIDAttributeData& attribute_data)
+{
+    const string* field=0;
+    if (!asd.config->mod_config->ftp_userid_disabled &&
+        (field=attribute_data.ftp_command_user()) != nullptr)
+    {
+        asd.client.update_user(APP_ID_FTP_CONTROL, field->c_str());
+        asd.set_session_flags(APPID_SESSION_LOGIN_SUCCEEDED);
+        // attribute_data.ftpCommandUser = nullptr;
+    }
+}
+
+static inline void process_third_party_results(AppIdSession& asd, int confidence,
+    vector<AppId>& proto_list, ThirdPartyAppIDAttributeData& attribute_data)
+{
+    if ( asd.payload.get_id() == APP_ID_NONE and contains(proto_list, APP_ID_EXCHANGE) )
+        asd.payload.set_id(APP_ID_EXCHANGE);
+
+    if ( contains(proto_list, APP_ID_HTTP) )
+    {
+        if (appidDebug->is_active())
+            LogMessage("AppIdDbg %s flow is HTTP\n", appidDebug->get_debug_session());
+        asd.set_session_flags(APPID_SESSION_HTTP_SESSION);
+    }
+
+    if ( contains(proto_list, APP_ID_SPDY) )
+    {
+        if (appidDebug->is_active())
+            LogMessage("AppIdDbg %s flow is SPDY\n", appidDebug->get_debug_session());
+
+        asd.set_session_flags(APPID_SESSION_HTTP_SESSION | APPID_SESSION_SPDY_SESSION);
+    }
+
+    if (asd.get_session_flags(APPID_SESSION_HTTP_SESSION))
+        process_http_session(asd, attribute_data);
+
+    else if (contains(proto_list, APP_ID_RTMP) ||
+        contains(proto_list, APP_ID_RTSP) )
+        process_rtmp(asd, attribute_data, confidence);
+
+    else if (contains(proto_list, APP_ID_SSL))
+        process_ssl(asd, attribute_data);
+
+    else if (contains(proto_list, APP_ID_FTP_CONTROL))
+        process_ftp_control(asd, attribute_data);
+}
+
+static inline void check_terminate_tp_module(AppIdSession& asd, uint16_t tpPktCount)
+{
+    AppIdHttpSession* hsession = asd.get_http_session();
+
+    if ((tpPktCount >= asd.config->mod_config->max_tp_flow_depth) ||
+        (asd.get_session_flags(APPID_SESSION_HTTP_SESSION | APPID_SESSION_APP_REINSPECT) ==
+        (APPID_SESSION_HTTP_SESSION | APPID_SESSION_APP_REINSPECT) &&
+        hsession->get_uri() && (!hsession->get_chp_candidate() || hsession->is_chp_finished())))
+    {
+        if (asd.tp_app_id == APP_ID_NONE)
+            asd.tp_app_id = APP_ID_UNKNOWN;
+        if (asd.payload.get_id() == APP_ID_NONE)
+            asd.payload.set_id(APP_ID_UNKNOWN);
+
+        if (asd.tpsession)
+            asd.tpsession->reset();
+    }
+}
+
+bool do_discovery(AppIdSession& asd, IpProtocol protocol,
+    Packet* p, AppidSessionDirection& direction)
+{
+    ThirdPartyAppIDAttributeData tp_attribute_data;
+    vector<AppId> tp_proto_list;
+    bool isTpAppidDiscoveryDone = false;
+
+    if ( !asd.config->have_tp() )
+        return true;
+
+    //restart inspection by 3rd party
+    if (!asd.tp_reinspect_by_initiator && (direction == APP_ID_FROM_INITIATOR) &&
+        check_reinspect(p, asd))
+    {
+        asd.tp_reinspect_by_initiator = true;
+        asd.set_session_flags(APPID_SESSION_APP_REINSPECT);
+        if (appidDebug->is_active())
+            LogMessage("AppIdDbg %s 3rd party allow reinspect http\n",
+                appidDebug->get_debug_session());
+        asd.reset_session_data();
+    }
+
+    if (asd.tp_app_id == APP_ID_SSH && asd.payload.get_id() != APP_ID_SFTP &&
+        asd.session_packet_count >= MIN_SFTP_PACKET_COUNT &&
+        asd.session_packet_count < MAX_SFTP_PACKET_COUNT)
+    {
+        if ( p->ptrs.ip_api.tos() == 8 )
+        {
+            asd.payload.set_id(APP_ID_SFTP);
+            if (appidDebug->is_active())
+                LogMessage("AppIdDbg %s Payload is SFTP\n", appidDebug->get_debug_session());
+        }
+    }
+
+    Profile tpPerfStats_profile_context(tpPerfStats);
+
+    /*** Start of third-party processing. ***/
+    if ( asd.config->have_tp()
+        && !asd.get_session_flags(APPID_SESSION_NO_TPI)
+        && (!is_appid_done(asd.tpsession)
+        || asd.get_session_flags(APPID_SESSION_APP_REINSPECT
+        | APPID_SESSION_APP_REINSPECT_SSL)))
+    {
+        // First SSL decrypted packet is now being inspected. Reset the flag so that SSL decrypted
+        // traffic gets processed like regular traffic from next packet onwards
+        if (asd.get_session_flags(APPID_SESSION_APP_REINSPECT_SSL))
+            asd.clear_session_flags(APPID_SESSION_APP_REINSPECT_SSL);
+
+        if (p->dsize || asd.config->mod_config->tp_allow_probes)
+        {
+            if (protocol != IpProtocol::TCP || (p->packet_flags & PKT_STREAM_ORDER_OK)
+                || asd.config->mod_config->tp_allow_probes)
+            {
+                Profile tpLibPerfStats_profile_context(tpLibPerfStats);
+                int tp_confidence;
+                if (!asd.tpsession)
+                {
+                   const TPLibHandler* tph = asd.config->tp_handler();
+                    CreateThirdPartyAppIDSession_t tpsf = tph->tpsession_factory();
+                    if ( !(asd.tpsession = tpsf()) )
+                        FatalError("Could not allocate asd.tpsession data");
+                }      // debug output of packet content
+
+                asd.tpsession->process(*p, direction,
+                    tp_proto_list, tp_attribute_data);
+                asd.tp_app_id=asd.tpsession->get_appid(tp_confidence);
+
+                isTpAppidDiscoveryDone = true;
+                if (asd.tpsession->get_state() == TP_STATE_CLASSIFIED)
+                    asd.clear_session_flags(APPID_SESSION_APP_REINSPECT);
+
+                if (appidDebug->is_active())
+                    LogMessage("AppIdDbg %s 3rd party returned %d\n",
+                        appidDebug->get_debug_session(),
+                        asd.tp_app_id);
+
+                // For now, third party can detect HTTP/2 (w/o metadata) for
+                // some cases.  Treat it like HTTP w/ is_http2 flag set.
+                if ((asd.tp_app_id == APP_ID_HTTP2) && (tp_confidence == 100))
+                {
+                    if (appidDebug->is_active())
+                        LogMessage("AppIdDbg %s 3rd party saw HTTP/2\n",
+                            appidDebug->get_debug_session());
+
+                    asd.tp_app_id = APP_ID_HTTP;
+                    asd.is_http2 = true;
+                }
+                // if the third-party appId must be treated as a client, do it now
+                if (asd.app_info_mgr->get_app_info_flags(asd.tp_app_id, APPINFO_FLAG_TP_CLIENT))
+                    asd.client.set_id(asd.tp_app_id);
+
+                process_third_party_results(asd, tp_confidence, tp_proto_list, tp_attribute_data);
+
+                if (asd.get_session_flags(APPID_SESSION_SSL_SESSION) &&
+                    !(asd.scan_flags & SCAN_SSL_HOST_FLAG))
+                {
+                    setSSLSquelch(p, 1, asd.tp_app_id, asd.get_inspector());
+                }
+
+                if (asd.app_info_mgr->get_app_info_flags(asd.tp_app_id, APPINFO_FLAG_IGNORE))
+                {
+                    if (appidDebug->is_active())
+                        LogMessage("AppIdDbg %s 3rd party ignored\n",
+                            appidDebug->get_debug_session());
+
+                    if (asd.get_session_flags(APPID_SESSION_HTTP_SESSION))
+                        asd.tp_app_id = APP_ID_HTTP;
+                    else
+                        asd.tp_app_id = APP_ID_NONE;
+                }
+            }
+            else
+            {
+                asd.tp_app_id = APP_ID_NONE;
+                if (appidDebug->is_active() && !asd.get_session_flags(
+                    APPID_SESSION_TPI_OOO_LOGGED))
+                {
+                    asd.set_session_flags(APPID_SESSION_TPI_OOO_LOGGED);
+                    LogMessage("AppIdDbg %s 3rd party packet out-of-order\n",
+                        appidDebug->get_debug_session());
+                }
+            }
+
+            if (asd.tpsession and asd.tpsession->get_state() == TP_STATE_MONITORING)
+            {
+                asd.tpsession->disable_flags(TP_SESSION_FLAG_ATTRIBUTE |
+                    TP_SESSION_FLAG_TUNNELING | TP_SESSION_FLAG_FUTUREFLOW);
+            }
+
+            if (asd.tp_app_id == APP_ID_SSL &&
+                (Stream::get_snort_protocol_id(p->flow) == snortId_for_ftp_data))
+            {
+                //  If we see SSL on an FTP data channel set tpAppId back
+                //  to APP_ID_NONE so the FTP preprocessor picks up the flow.
+                asd.tp_app_id = APP_ID_NONE;
+            }
+
+            if ( asd.tp_app_id > APP_ID_NONE
+                && (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT)
+                || asd.payload.get_id() > APP_ID_NONE) )
+            {
+                AppId snort_app_id;
+                AppIdHttpSession* hsession = asd.get_http_session();
+
+                // if the packet is HTTP, then search for via pattern
+                if ( asd.get_session_flags(APPID_SESSION_HTTP_SESSION) )
+                {
+                    snort_app_id = APP_ID_HTTP;
+                    //data should never be APP_ID_HTTP
+                    if (asd.tp_app_id != APP_ID_HTTP)
+                        asd.tp_payload_app_id = asd.tp_app_id;
+
+                    asd.tp_app_id = APP_ID_HTTP;
+                    // Handle HTTP tunneling and SSL possibly then being used in that tunnel
+                    if (asd.tp_app_id == APP_ID_HTTP_TUNNEL)
+                        asd.set_payload_appid_data(APP_ID_HTTP_TUNNEL, NULL);
+                    if ((asd.payload.get_id() == APP_ID_HTTP_TUNNEL) && (asd.tp_app_id ==
+                        APP_ID_SSL))
+                        asd.set_payload_appid_data(APP_ID_HTTP_SSL_TUNNEL, NULL);
+
+                    hsession->process_http_packet(direction);
+
+                    // If SSL over HTTP tunnel, make sure Snort knows that it's encrypted.
+                    if (asd.payload.get_id() == APP_ID_HTTP_SSL_TUNNEL)
+                        snort_app_id = APP_ID_SSL;
+
+                    if (asd.is_third_party_appid_available() && asd.tp_app_id ==
+                        APP_ID_HTTP
+                        && !asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
+                    {
+                        asd.client_disco_state = APPID_DISCO_STATE_FINISHED;
+                        asd.set_session_flags(APPID_SESSION_CLIENT_DETECTED |
+                            APPID_SESSION_SERVICE_DETECTED);
+                        asd.client_disco_state = APPID_DISCO_STATE_FINISHED;
+                        asd.clear_session_flags(APPID_SESSION_CONTINUE);
+                        if (direction == APP_ID_FROM_INITIATOR)
+                        {
+                            asd.service_ip = *p->ptrs.ip_api.get_dst();
+                            asd.service_port = p->ptrs.dp;
+                        }
+                        else
+                        {
+                            asd.service_ip = *p->ptrs.ip_api.get_src();
+                            asd.service_port = p->ptrs.sp;
+                        }
+                    }
+                }
+                else if (asd.get_session_flags(APPID_SESSION_SSL_SESSION) && asd.tsession)
+                {
+                    asd.examine_ssl_metadata(p);
+                    uint16_t serverPort;
+                    AppId porAppId;
+                    serverPort = (direction == APP_ID_FROM_INITIATOR) ? p->ptrs.dp : p->ptrs.sp;
+                    porAppId = serverPort;
+                    if (asd.tp_app_id == APP_ID_SSL)
+                    {
+                        asd.tp_app_id = porAppId;
+                        //SSL policy determines IMAPS/POP3S etc before appId sees first server
+                        // packet
+                        asd.service.set_port_service_id(porAppId);
+                        if (appidDebug->is_active())
+                            LogMessage("AppIdDbg %s SSL is service %d, portServiceAppId %d\n",
+                                appidDebug->get_debug_session(),
+                                asd.tp_app_id, asd.service.get_port_service_id());
+                    }
+                    else
+                    {
+                        asd.tp_payload_app_id = asd.tp_app_id;
+                        asd.tp_app_id = porAppId;
+                        if (appidDebug->is_active())
+                            LogMessage("AppIdDbg %s SSL is %d\n", appidDebug->get_debug_session(),
+                                asd.tp_app_id);
+                    }
+                    snort_app_id = APP_ID_SSL;
+                }
+                else
+                {
+                    //for non-http protocols, tp id is treated like serviceId
+                    snort_app_id = asd.tp_app_id;
+                }
+
+                asd.sync_with_snort_protocol_id(snort_app_id, p);
+            }
+            else
+            {
+                if (protocol != IpProtocol::TCP ||
+                    (p->packet_flags & (PKT_STREAM_ORDER_OK | PKT_STREAM_ORDER_BAD)))
+                {
+                    if (direction == APP_ID_FROM_INITIATOR)
+                    {
+                        asd.init_tpPackets++;
+                        check_terminate_tp_module(asd, asd.init_tpPackets);
+                    }
+                    else
+                    {
+                        asd.resp_tpPackets++;
+                        check_terminate_tp_module(asd, asd.resp_tpPackets);
+                    }
+                }
+            }
+        }
+    }
+
+    if ( asd.tp_reinspect_by_initiator && check_reinspect(p, asd) )
+    {
+        asd.clear_session_flags(APPID_SESSION_APP_REINSPECT);
+        if (direction == APP_ID_FROM_RESPONDER)
+            asd.tp_reinspect_by_initiator = false;     //toggle at OK response
+    }
+
+    return isTpAppidDiscoveryDone;
+}
diff --git a/src/network_inspectors/appid/tp_lib_handler.cc b/src/network_inspectors/appid/tp_lib_handler.cc
new file mode 100644 (file)
index 0000000..319a8b3
--- /dev/null
@@ -0,0 +1,171 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2018-2018 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.
+//--------------------------------------------------------------------------
+
+// tp_lib_handler.cc author Silviu Minut <sminut@cisco.com>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <dlfcn.h>
+
+#include "appid_config.h"
+
+#include "main/snort_debug.h"
+#include "log/messages.h"
+
+#include "tp_lib_handler.h"
+
+using namespace std;
+using namespace snort;
+
+#define TP_APPID_MODULE_SYMBOL "create_third_party_appid_module"
+#define TP_APPID_SESSION_SYMBOL "create_third_party_appid_session"
+
+TPLibHandler* TPLibHandler::handler = nullptr;
+
+int TPLibHandler::LoadCallback(const char* const path, int /* indent */)
+{
+    void* handle = 0;
+    ThirdPartyAppIDModule* tp_module = 0;
+    const char* error = nullptr;
+
+    if (tp_appid_module != nullptr)
+    {
+        ErrorMessage("Ignoring additional 3rd party AppID module (%s)!\n", path);
+        return 0;
+    }
+
+    // Load the tp library and get function pointers to the module and
+    // session object factories.
+    dlerror();
+    handle = dlopen(path, RTLD_NOW | RTLD_LOCAL);
+    if (handle == nullptr)
+    {
+        ErrorMessage("Failed to load 3rd party AppID library: %s - %s\n", path, dlerror());
+        return 0;
+    }
+
+    CreateThirdPartyAppIDModule_t createThirdPartyAppIDModule=
+        (CreateThirdPartyAppIDModule_t)dlsym(handle, TP_APPID_MODULE_SYMBOL);
+    if ((error=dlerror()) != nullptr)
+    {
+        ErrorMessage(
+            "Failed to get 3rd party AppID module object factory: %s - %s\n",
+            TP_APPID_MODULE_SYMBOL, error);
+        dlclose(handle);
+        return 0;
+    }
+
+    createThirdPartyAppIDSession=(CreateThirdPartyAppIDSession_t)dlsym(
+        handle,TP_APPID_SESSION_SYMBOL);
+    if ((error=dlerror()) != nullptr)
+    {
+        ErrorMessage(
+            "Failed to get 3rd party AppID session object factory: %s - %s\n",
+            TP_APPID_SESSION_SYMBOL, error);
+        dlclose(handle);
+        return 0;
+    }
+
+    // The tp module object is a singleton and gets created here in main thread.
+    // TP session objects get created per worker thread.
+    tp_module=createThirdPartyAppIDModule();
+    if (tp_module == nullptr)
+    {
+        ErrorMessage("Failed to create third party appId module.\n");
+        dlclose(handle);
+        return 0;
+    }
+
+    if ( (tp_module->api_version() != THIRD_PARTY_APP_ID_API_VERSION)
+        || (tp_module->module_name().empty()) )
+    {
+        ErrorMessage("Ignoring incomplete 3rd party AppID module (%s, %d, %s)!\n",
+            path, tp_module->api_version(),
+            tp_module->module_name().empty() ? "empty" : tp_module->module_name().c_str());
+
+        dlclose(handle);
+        delete tp_module;
+        return 0;
+    }
+
+    this->tp_so_handle = handle;
+    tp_appid_module = tp_module;
+    return 0;
+}
+
+void TPLibHandler::pinit(const AppIdModuleConfig* config)
+{
+    int ret;
+
+    if (config->tp_appid_path.empty())
+        return;
+
+    tp_config.tp_appid_config=config->tp_appid_config;
+
+    LoadCallback(config->tp_appid_path.c_str(),1);
+
+    if (tp_appid_module == nullptr)
+    {
+        // FIXIT-H error message
+        return;
+    }
+
+    tp_config.chp_body_collection_max = config->chp_body_collection_max;
+    tp_config.ftp_userid_disabled = config->ftp_userid_disabled;
+    tp_config.chp_body_collection_disabled =
+        config->chp_body_collection_disabled;
+    tp_config.tp_allow_probes = config->tp_allow_probes;
+    if (config->http2_detection_enabled)
+        tp_config.http_upgrade_reporting_enabled = 1;
+    else
+        tp_config.http_upgrade_reporting_enabled = 0;
+    // FIXIT-H: Init http_response_version_enabled
+
+    ret = tp_appid_module->pinit(tp_config);
+    if (ret != 0)
+    {
+        ErrorMessage("Unable to initialize 3rd party AppID module (%d)!\n", ret);
+        delete tp_appid_module;
+        dlclose(tp_so_handle);
+        tp_so_handle = nullptr;
+        tp_appid_module = nullptr;
+        return;
+    }
+}
+
+void TPLibHandler::pfini(bool print_stats_flag)
+{
+    if (tp_appid_module != nullptr)
+    {
+        if (print_stats_flag)
+            tp_appid_module->print_stats();
+
+        int ret = tp_appid_module->pfini();
+
+        if (ret != 0)
+            ErrorMessage("Could not finalize 3rd party AppID module (%d)!\n", ret);
+
+        delete tp_appid_module;
+        tp_appid_module = nullptr;
+        dlclose(tp_so_handle); // after delete, otherwise tpam will be dangling
+        tp_so_handle = nullptr;
+    }
+}
+
diff --git a/src/network_inspectors/appid/tp_lib_handler.h b/src/network_inspectors/appid/tp_lib_handler.h
new file mode 100644 (file)
index 0000000..d9f418c
--- /dev/null
@@ -0,0 +1,84 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2018-2018 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.
+//--------------------------------------------------------------------------
+
+// tp_lib_handler.h author Silviu Minut <sminut@cisco.com>
+
+#ifndef TP_LIB_HANDLER_H
+#define TP_LIB_HANDLER_H
+
+#include "tp_appid_module_api.h"
+#include "tp_appid_session_api.h"
+
+class AppIdModuleConfig;
+
+// Class responsible for loading/reloading the thirdparty.so library and
+// for holding pointers to objects that live inside thirdparty.so.
+class TPLibHandler
+{
+public:
+
+    bool have_tp() const
+    {
+       return tp_appid_module != nullptr;
+    }
+
+    static TPLibHandler* get()
+    {
+        if (handler)
+            return handler;
+        else
+            return (handler=new TPLibHandler());
+    }
+
+    static void destroy(TPLibHandler* tph)
+    {
+        delete tph->handler;
+        tph->handler=nullptr;
+    }
+
+    // called from AppIdConfig::init_appid() and cleanup(), respectively.
+    void pinit(const AppIdModuleConfig* config);
+    void pfini(bool print_stats_flag=0);
+
+    // called from AppIdInspector tinit/tterm via
+    // AppIdConfig::tp_appid_module_tinit/tterm.
+    void tinit() { if ( tp_appid_module ) tp_appid_module->tinit(); }
+    void tterm() { if ( tp_appid_module ) tp_appid_module->tfini(); }
+
+    CreateThirdPartyAppIDSession_t tpsession_factory() const
+    {
+        return createThirdPartyAppIDSession;
+    }
+
+private:
+
+    TPLibHandler() { }
+    ~TPLibHandler() { }
+
+    static TPLibHandler* handler;
+    void* tp_so_handle = nullptr;   // output of dlopen(thirdparty.so)
+    ThirdPartyAppIDModule* tp_appid_module = nullptr;
+    CreateThirdPartyAppIDSession_t createThirdPartyAppIDSession;
+
+    ThirdPartyConfig tp_config;
+
+    int LoadCallback(const char* path, int);
+};
+
+#endif
+