From: Shravan Rangarajuvenkata (shrarang) Date: Thu, 10 Dec 2020 22:41:39 +0000 (+0000) Subject: Merge pull request #2656 in SNORT/snort3 from ~KAMURTHI/snort3:ha_appid to master X-Git-Tag: 3.0.3-6~14 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b60fde2f7a127ce9a1941d74ab0bf019863913df;p=thirdparty%2Fsnort3.git Merge pull request #2656 in SNORT/snort3 from ~KAMURTHI/snort3:ha_appid to master Squashed commit of the following: commit 040522d0063caca6466e808eeeb0bbd44a9e277e Author: Kanimozhi Murthi Date: Sun Nov 15 11:58:35 2020 -0500 appid: add support for apps, http host, url and tls host in HA --- diff --git a/src/network_inspectors/appid/CMakeLists.txt b/src/network_inspectors/appid/CMakeLists.txt index e0246f137..0d0f37a85 100644 --- a/src/network_inspectors/appid/CMakeLists.txt +++ b/src/network_inspectors/appid/CMakeLists.txt @@ -163,6 +163,8 @@ set ( APPID_SOURCES appid_discovery.cc appid_discovery.h appid_dns_session.h + appid_ha.cc + appid_ha.h appid_http_session.cc appid_http_session.h appid_peg_counts.h diff --git a/src/network_inspectors/appid/appid_api.cc b/src/network_inspectors/appid/appid_api.cc index 82877ae89..b8ddccffd 100644 --- a/src/network_inspectors/appid/appid_api.cc +++ b/src/network_inspectors/appid/appid_api.cc @@ -115,122 +115,6 @@ AppId AppIdApi::get_application_id(const char* appName, const AppIdContext& ctxt return ctxt.get_odp_ctxt().get_app_info_mgr().get_appid_by_name(appName); } -#define APPID_HA_FLAGS_APP ( 1 << 0 ) -#define APPID_HA_FLAGS_TP_DONE ( 1 << 1 ) -#define APPID_HA_FLAGS_SVC_DONE ( 1 << 2 ) -#define APPID_HA_FLAGS_HTTP ( 1 << 3 ) - -uint32_t AppIdApi::produce_ha_state(const Flow& flow, uint8_t* buf) -{ - assert(buf); - AppIdSessionHA* appHA = (AppIdSessionHA*)buf; - AppIdSession* asd = get_appid_session(flow); - if (asd) - { - appHA->flags = APPID_HA_FLAGS_APP; - if (asd->is_tp_appid_available()) - appHA->flags |= APPID_HA_FLAGS_TP_DONE; - if (asd->is_service_detected()) - appHA->flags |= APPID_HA_FLAGS_SVC_DONE; - if (asd->get_session_flags(APPID_SESSION_HTTP_SESSION)) - appHA->flags |= APPID_HA_FLAGS_HTTP; - appHA->appId[0] = asd->get_tp_app_id(); - appHA->appId[1] = asd->get_service_id(); - appHA->appId[2] = asd->client_inferred_service_id; - appHA->appId[3] = asd->get_port_service_id(); - const AppIdHttpSession* hsession = asd->get_http_session(); - if (hsession) - appHA->appId[4] = hsession->payload.get_id(); - else - appHA->appId[4] = asd->get_payload_id(); - appHA->appId[5] = asd->get_tp_payload_app_id(); - if (hsession) - appHA->appId[6] = hsession->client.get_id(); - else - appHA->appId[6] = asd->get_client_id(); - appHA->appId[7] = asd->misc_app_id; - appHA->asid = asd->asid; - } - else - memset(appHA, 0, sizeof(*appHA)); - - return sizeof(*appHA); -} - -uint32_t AppIdApi::consume_ha_state(Flow& flow, const uint8_t* buf, uint8_t, IpProtocol proto, - SfIp* ip, uint16_t port) -{ - const AppIdSessionHA* appHA = (const AppIdSessionHA*)buf; - if (appHA->flags & APPID_HA_FLAGS_APP) - { - AppIdSession* asd = - (AppIdSession*)(flow.get_flow_data(AppIdSession::inspector_id)); - - if (!asd) - { - AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME, true); - if (inspector) - { - asd = new AppIdSession(proto, ip, port, *inspector, - inspector->get_ctxt().get_odp_ctxt(), appHA->asid); - flow.set_flow_data(asd); - asd->set_service_id(appHA->appId[1], asd->get_odp_ctxt()); - if (asd->get_service_id() == APP_ID_FTP_CONTROL) - { - asd->set_session_flags(APPID_SESSION_CLIENT_DETECTED | - APPID_SESSION_NOT_A_SERVICE | APPID_SESSION_SERVICE_DETECTED); - if (!ServiceDiscovery::add_ftp_service_state(*asd)) - asd->set_session_flags(APPID_SESSION_CONTINUE); - - asd->service_disco_state = APPID_DISCO_STATE_STATEFUL; - } - else - asd->service_disco_state = APPID_DISCO_STATE_FINISHED; - - asd->client_disco_state = APPID_DISCO_STATE_FINISHED; - if (asd->tpsession) - asd->tpsession->set_state(TP_STATE_HA); - } - } - - if (!asd) - { - return sizeof(*appHA); - } - - if((appHA->flags & APPID_HA_FLAGS_TP_DONE) && asd->tpsession) - { - asd->tpsession->set_state(TP_STATE_TERMINATED); - asd->set_session_flags(APPID_SESSION_NO_TPI); - } - - if (appHA->flags & APPID_HA_FLAGS_SVC_DONE) - asd->set_service_detected(); - - if (appHA->flags & APPID_HA_FLAGS_HTTP) - asd->set_session_flags(APPID_SESSION_HTTP_SESSION); - - asd->set_tp_app_id(appHA->appId[0]); - asd->set_service_id(appHA->appId[1], asd->get_odp_ctxt()); - asd->client_inferred_service_id = appHA->appId[2]; - asd->set_port_service_id(appHA->appId[3]); - AppIdHttpSession* hsession = nullptr; - if (appHA->appId[1] == APP_ID_HTTP or appHA->appId[1] == APP_ID_RTMP) - hsession = asd->create_http_session(); - if (hsession) - hsession->payload.set_id(appHA->appId[4]); - else - asd->set_payload_id(appHA->appId[4]); - asd->set_tp_payload_app_id(appHA->appId[5]); - if (hsession) - hsession->client.set_id(appHA->appId[6]); - else - asd->set_client_id(appHA->appId[6]); - asd->misc_app_id = appHA->appId[7]; - } - return sizeof(*appHA); -} - bool AppIdApi::ssl_app_group_id_lookup(Flow* flow, const char* server_name, const char* first_alt_name, const char* common_name, const char* org_unit, bool sni_mismatch, AppId& service_id, AppId& client_id, AppId& payload_id) diff --git a/src/network_inspectors/appid/appid_api.h b/src/network_inspectors/appid/appid_api.h index 2e49a1887..ab6c80b42 100644 --- a/src/network_inspectors/appid/appid_api.h +++ b/src/network_inspectors/appid/appid_api.h @@ -34,16 +34,6 @@ class AppIdSession; namespace snort { - -#define APPID_HA_SESSION_APP_NUM_MAX 8 // maximum number of appIds replicated for a flow/session - -struct AppIdSessionHA -{ - uint16_t flags; - uint16_t asid; - AppId appId[APPID_HA_SESSION_APP_NUM_MAX]; -}; - // ----------------------------------------------------------------------------- // AppId API // ----------------------------------------------------------------------------- @@ -58,9 +48,6 @@ public: const char* get_application_name(AppId app_id, const Flow& flow); const char* get_application_name(const Flow& flow, bool from_client); AppId get_application_id(const char* appName, const AppIdContext& ctxt); - uint32_t produce_ha_state(const Flow& flow, uint8_t* buf); - uint32_t consume_ha_state(Flow& flow, const uint8_t* buf, uint8_t length, IpProtocol, - SfIp*, uint16_t initiatorPort); bool ssl_app_group_id_lookup(Flow* flow, const char*, const char*, const char*, const char*, bool, AppId& service_id, AppId& client_id, AppId& payload_id); const AppIdSessionApi* get_appid_session_api(const Flow& flow) const; diff --git a/src/network_inspectors/appid/appid_ha.cc b/src/network_inspectors/appid/appid_ha.cc new file mode 100644 index 000000000..9b672e458 --- /dev/null +++ b/src/network_inspectors/appid/appid_ha.cc @@ -0,0 +1,354 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2020-2020 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. +//-------------------------------------------------------------------------- + +// appid_ha.cc author Kani Murthi + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "appid_ha.h" + +#include "flow/flow_key.h" +#include "managers/inspector_manager.h" + +#include "appid_debug.h" +#include "appid_session.h" +#include "tp_lib_handler.h" + +#define APPID_HA_FLAGS_TP_DONE ( 1 << 0 ) +#define APPID_HA_FLAGS_SVC_DONE ( 1 << 1 ) +#define APPID_HA_FLAGS_HTTP ( 1 << 2 ) + +using namespace snort; + +THREAD_LOCAL AppIdHAAppsClient* AppIdHAManager::ha_apps_client = nullptr; +THREAD_LOCAL AppIdHAHttpClient* AppIdHAManager::ha_http_client = nullptr; +THREAD_LOCAL AppIdHATlsHostClient* AppIdHAManager::ha_tls_host_client = nullptr; + +static AppIdSession* create_appid_session(Flow& flow, const FlowKey* key) +{ + AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME, true); + AppIdSession* asd = new AppIdSession(static_cast(key->ip_protocol), + flow.flags.client_initiated ? &flow.client_ip : &flow.server_ip, + flow.flags.client_initiated ? flow.client_port : flow.server_port, *inspector, + inspector->get_ctxt().get_odp_ctxt(), key->addressSpaceId); + if (appidDebug->is_active()) + LogMessage("AppIdDbg %s high-avail - New AppId session created in consume\n", + appidDebug->get_debug_session()); + + flow.set_flow_data(asd); + asd->flow = &flow; + + return asd; +} + +bool AppIdHAAppsClient::consume(Flow*& flow, const FlowKey* key, HAMessage& msg, + uint8_t size) +{ + assert(key and flow); + if (size != sizeof(AppIdSessionHAApps)) + return false; + + AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME, true); + if (!inspector) + return false; + + AppIdSession* asd = (AppIdSession*)(flow->get_flow_data(AppIdSession::inspector_id)); + const AppIdSessionHAApps* appHA = (const AppIdSessionHAApps*)msg.cursor; + + if (appidDebug->is_enabled()) + { + appidDebug->activate(flow, asd, inspector->get_ctxt().config.log_all_sessions); + LogMessage("AppIdDbg %s high-avail - Consuming app data - flags 0x%x, service %d, client %d, " + "payload %d, misc %d, referred %d, client_inferred_service %d, port_service %d, " + "tp_app %d, tp_payload %d\n", + appidDebug->get_debug_session(), appHA->flags, appHA->appId[APPID_HA_APP_SERVICE], + appHA->appId[APPID_HA_APP_CLIENT], appHA->appId[APPID_HA_APP_PAYLOAD], + appHA->appId[APPID_HA_APP_MISC], appHA->appId[APPID_HA_APP_REFERRED], + appHA->appId[APPID_HA_APP_CLIENT_INFERRED_SERVICE], + appHA->appId[APPID_HA_APP_PORT_SERVICE], appHA->appId[APPID_HA_APP_TP], + appHA->appId[APPID_HA_APP_TP_PAYLOAD]); + } + + if (!asd) + { + asd = create_appid_session(*flow, key); + asd->set_service_id(appHA->appId[APPID_HA_APP_SERVICE], asd->get_odp_ctxt()); + if (asd->get_service_id() == APP_ID_FTP_CONTROL) + { + asd->set_session_flags(APPID_SESSION_CLIENT_DETECTED | + APPID_SESSION_NOT_A_SERVICE | APPID_SESSION_SERVICE_DETECTED); + if (!ServiceDiscovery::add_ftp_service_state(*asd)) + asd->set_session_flags(APPID_SESSION_CONTINUE); + + asd->service_disco_state = APPID_DISCO_STATE_STATEFUL; + } + else + asd->service_disco_state = APPID_DISCO_STATE_FINISHED; + + asd->client_disco_state = APPID_DISCO_STATE_FINISHED; + if (asd->get_tp_appid_ctxt()) + { + const TPLibHandler* tph = TPLibHandler::get(); + TpAppIdCreateSession tpsf = tph->tpsession_factory(); + if ( !(asd->tpsession = tpsf(*asd->get_tp_appid_ctxt())) ) + ErrorMessage("appid: Could not allocate asd.tpsession data in consume"); + else + asd->tpsession->set_state(TP_STATE_HA); + } + } + + if ((appHA->flags & APPID_HA_FLAGS_TP_DONE) and asd->tpsession) + { + asd->tpsession->set_state(TP_STATE_TERMINATED); + asd->set_session_flags(APPID_SESSION_NO_TPI); + } + + if (appHA->flags & APPID_HA_FLAGS_SVC_DONE) + asd->set_service_detected(); + + if (appHA->flags & APPID_HA_FLAGS_HTTP) + asd->set_session_flags(APPID_SESSION_HTTP_SESSION); + asd->set_service_id(appHA->appId[APPID_HA_APP_SERVICE], asd->get_odp_ctxt()); + AppIdHttpSession* hsession = nullptr; + if (appHA->appId[APPID_HA_APP_SERVICE] == APP_ID_HTTP or + appHA->appId[APPID_HA_APP_SERVICE] == APP_ID_RTMP) + hsession = asd->create_http_session(); + if (hsession) + { + hsession->client.set_id(appHA->appId[APPID_HA_APP_CLIENT]); + hsession->payload.set_id(appHA->appId[APPID_HA_APP_PAYLOAD]); + hsession->misc_app_id = appHA->appId[APPID_HA_APP_MISC]; + hsession->referred_payload_app_id = appHA->appId[APPID_HA_APP_REFERRED]; + } + else + { + asd->set_client_id(appHA->appId[APPID_HA_APP_CLIENT]); + asd->set_payload_id(appHA->appId[APPID_HA_APP_PAYLOAD]); + asd->misc_app_id = appHA->appId[APPID_HA_APP_MISC]; + } + asd->client_inferred_service_id = appHA->appId[APPID_HA_APP_CLIENT_INFERRED_SERVICE]; + asd->set_port_service_id(appHA->appId[APPID_HA_APP_PORT_SERVICE]); + asd->set_tp_app_id(appHA->appId[APPID_HA_APP_TP]); + asd->set_tp_payload_app_id(appHA->appId[APPID_HA_APP_TP_PAYLOAD]); + + asd->set_consumed_ha_data(true); + + msg.advance_cursor(sizeof(AppIdSessionHAApps)); + return true; +} + +bool AppIdHAAppsClient::produce(Flow& flow, HAMessage& msg) +{ + if (!msg.fits(sizeof(AppIdSessionHAApps))) + return false; + assert(msg.cursor); + + AppIdSession* asd = (AppIdSession*)flow.get_flow_data(AppIdSession::inspector_id); + if (!asd) + return false; + + AppIdSessionHAApps* appHA = (AppIdSessionHAApps*)(msg.cursor); + if (asd->is_tp_appid_available()) + appHA->flags |= APPID_HA_FLAGS_TP_DONE; + if (asd->is_service_detected()) + appHA->flags |= APPID_HA_FLAGS_SVC_DONE; + if (asd->get_session_flags(APPID_SESSION_HTTP_SESSION)) + appHA->flags |= APPID_HA_FLAGS_HTTP; + appHA->appId[APPID_HA_APP_SERVICE] = asd->get_service_id(); + const AppIdHttpSession* hsession = asd->get_http_session(0); + if (hsession) + { + appHA->appId[APPID_HA_APP_CLIENT] = hsession->client.get_id(); + appHA->appId[APPID_HA_APP_PAYLOAD] = hsession->payload.get_id(); + appHA->appId[APPID_HA_APP_MISC] = hsession->misc_app_id; + appHA->appId[APPID_HA_APP_REFERRED] = hsession->referred_payload_app_id; + } + else + { + appHA->appId[APPID_HA_APP_CLIENT] = asd->get_client_id(); + appHA->appId[APPID_HA_APP_PAYLOAD] = asd->get_payload_id(); + appHA->appId[APPID_HA_APP_MISC] = asd->misc_app_id; + appHA->appId[APPID_HA_APP_REFERRED] = APP_ID_NONE; + } + appHA->appId[APPID_HA_APP_CLIENT_INFERRED_SERVICE] = asd->client_inferred_service_id; + appHA->appId[APPID_HA_APP_PORT_SERVICE] = asd->get_port_service_id(); + appHA->appId[APPID_HA_APP_TP] = asd->get_tp_app_id(); + appHA->appId[APPID_HA_APP_TP_PAYLOAD] = asd->get_tp_payload_app_id(); + + if (appidDebug->is_active()) + LogMessage("AppIdDbg %s high-avail - Producing app data - flags 0x%x, service %d, client %d, " + "payload %d, misc %d, referred %d, client_inferred_service %d, port_service %d, " + "tp_app %d, tp_payload %d\n", + appidDebug->get_debug_session(), appHA->flags, appHA->appId[APPID_HA_APP_SERVICE], + appHA->appId[APPID_HA_APP_CLIENT], appHA->appId[APPID_HA_APP_PAYLOAD], + appHA->appId[APPID_HA_APP_MISC], appHA->appId[APPID_HA_APP_REFERRED], + appHA->appId[APPID_HA_APP_CLIENT_INFERRED_SERVICE], + appHA->appId[APPID_HA_APP_PORT_SERVICE], appHA->appId[APPID_HA_APP_TP], + appHA->appId[APPID_HA_APP_TP_PAYLOAD]); + + msg.advance_cursor(sizeof(AppIdSessionHAApps)); + return true; +} + +bool AppIdHAHttpClient::consume(Flow*& flow, const FlowKey* key, HAMessage& msg, + uint8_t size) +{ + assert(key and flow); + + if (size != sizeof(AppIdSessionHAHttp)) + return false; + + AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME, true); + if (!inspector) + return false; + + AppIdSession* asd = appid_api.get_appid_session(*flow); + AppIdSessionHAHttp* appHA = (AppIdSessionHAHttp*)msg.cursor; + if (appidDebug->is_enabled()) + { + appidDebug->activate(flow, asd, inspector->get_ctxt().config.log_all_sessions); + LogMessage("AppIdDbg %s high-avail - Consuming HTTP data - URL %s, host %s\n", + appidDebug->get_debug_session(), appHA->url, appHA->host); + } + + if (!asd) + asd = create_appid_session(*flow, key); + + AppidChangeBits change_bits; + AppIdHttpSession* hsession = asd->get_http_session(); + if (!hsession) + hsession = asd->create_http_session(); + + hsession->set_field(MISC_URL_FID, new std::string(appHA->url), change_bits); + hsession->set_field(REQ_HOST_FID, new std::string(appHA->host), change_bits); + + asd->set_consumed_ha_data(true); + + msg.advance_cursor(sizeof(AppIdSessionHAHttp)); + return true; +} + +bool AppIdHAHttpClient::produce(Flow& flow, HAMessage& msg) +{ + if (!msg.fits(sizeof(AppIdSessionHAHttp))) + return false; + assert(msg.cursor); + + AppIdSession* asd = appid_api.get_appid_session(flow); + if (!asd) + return false; + + const AppIdHttpSession* hsession = asd->get_http_session(); + if (!hsession) + return false; + + const char* url = hsession->get_cfield(MISC_URL_FID); + const char* host = hsession->get_cfield(REQ_HOST_FID); + if (!url and !host) + return false; + + AppIdSessionHAHttp* appHA = (AppIdSessionHAHttp*)msg.cursor; + + if (url) + { + auto length = strlen(url); + if (length >= APPID_HA_MAX_FIELD_LEN) + length = APPID_HA_MAX_FIELD_LEN - 1; + memcpy(appHA->url, (void *)url, length); + appHA->url[length] = '\0'; + } + else + appHA->url[0] = '\0'; + + if (host) + { + auto length = strlen(host); + if (length >= APPID_HA_MAX_FIELD_LEN) + length = APPID_HA_MAX_FIELD_LEN - 1; + memcpy(appHA->host, (void *)host, length); + appHA->host[length] = '\0'; + } + else + appHA->host[0] = '\0'; + + if (appidDebug->is_active()) + LogMessage("AppIdDbg %s high-avail - Producing HTTP data - URL %s, host %s\n", + appidDebug->get_debug_session(), appHA->url, appHA->host); + + msg.advance_cursor(sizeof(AppIdSessionHAHttp)); + return true; +} + +bool AppIdHATlsHostClient::consume(Flow*& flow, const FlowKey* key, HAMessage& msg, + uint8_t size) +{ + assert(key and flow); + if (size != sizeof(AppIdSessionHATlsHost)) + return false; + + AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME, true); + if (!inspector) + return false; + + AppIdSession* asd = appid_api.get_appid_session(*flow); + AppIdSessionHATlsHost* appHA = (AppIdSessionHATlsHost*)msg.cursor; + if (appidDebug->is_enabled()) + { + appidDebug->activate(flow, asd, inspector->get_ctxt().config.log_all_sessions); + LogMessage("AppIdDbg %s high-avail - Consuming TLS host - %s\n", + appidDebug->get_debug_session(), appHA->tls_host); + } + + if (!asd) + asd = create_appid_session(*flow, key); + + asd->set_tls_host(appHA->tls_host); + + asd->set_consumed_ha_data(true); + + msg.advance_cursor(sizeof(AppIdSessionHATlsHost)); + return true; +} + +bool AppIdHATlsHostClient::produce(Flow& flow, HAMessage& msg) +{ + if (!msg.fits(sizeof(AppIdSessionHATlsHost))) + return false; + assert(msg.cursor); + + AppIdSession* asd = appid_api.get_appid_session(flow); + if (!asd or !asd->get_api().get_tls_host()) + return false; + + AppIdSessionHATlsHost* appHA = (AppIdSessionHATlsHost*)msg.cursor; + const char* tls_host = asd->get_api().get_tls_host(); + auto length = strlen(tls_host); + if (length >= APPID_HA_MAX_FIELD_LEN) + length = APPID_HA_MAX_FIELD_LEN - 1; + memcpy(appHA->tls_host, tls_host, length); + appHA->tls_host[length] = '\0'; + + if (appidDebug->is_active()) + LogMessage("AppIdDbg %s high-avail - Producing TLS host - %s\n", + appidDebug->get_debug_session(), appHA->tls_host); + + msg.advance_cursor(sizeof(AppIdSessionHATlsHost)); + return true; +} diff --git a/src/network_inspectors/appid/appid_ha.h b/src/network_inspectors/appid/appid_ha.h new file mode 100644 index 000000000..cf5596b62 --- /dev/null +++ b/src/network_inspectors/appid/appid_ha.h @@ -0,0 +1,112 @@ +//-------------------------------------------------------------------------- +// Copyright (C) 2020-2020 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. +//-------------------------------------------------------------------------- + +// appid_ha.h author Kani Murthi + +#ifndef APPID_HA_H +#define APPID_HA_H + +#include "flow/flow.h" +#include "flow/ha.h" +#include "appid_inspector.h" + +#define APPID_HA_MAX_FIELD_LEN 32 + +enum AppIdHAAppType +{ + APPID_HA_APP_SERVICE = 0, + APPID_HA_APP_CLIENT, + APPID_HA_APP_PAYLOAD, + APPID_HA_APP_MISC, + APPID_HA_APP_REFERRED, + APPID_HA_APP_CLIENT_INFERRED_SERVICE, + APPID_HA_APP_PORT_SERVICE, + APPID_HA_APP_TP, + APPID_HA_APP_TP_PAYLOAD, + APPID_HA_APP_MAX +}; + +struct AppIdSessionHAApps +{ + uint16_t flags; + AppId appId[APPID_HA_APP_MAX]; +}; + +struct AppIdSessionHAHttp +{ + char url[APPID_HA_MAX_FIELD_LEN]; + char host[APPID_HA_MAX_FIELD_LEN]; +}; + +struct AppIdSessionHATlsHost +{ + char tls_host[APPID_HA_MAX_FIELD_LEN]; +}; + +class AppIdHAAppsClient : public snort::FlowHAClient +{ +public: + AppIdHAAppsClient() : FlowHAClient(sizeof(AppIdSessionHAApps), false) { } + bool consume(snort::Flow*&, const snort::FlowKey*, snort::HAMessage&, uint8_t size) override; + bool produce(snort::Flow&, snort::HAMessage&) override; +}; + +class AppIdHAHttpClient : public snort::FlowHAClient +{ +public: + AppIdHAHttpClient() : FlowHAClient(sizeof(AppIdSessionHAHttp), false) { } + bool consume(snort::Flow*&, const snort::FlowKey*, snort::HAMessage&, uint8_t size) override; + bool produce(snort::Flow&, snort::HAMessage&) override; +}; + +class AppIdHATlsHostClient : public snort::FlowHAClient +{ +public: + AppIdHATlsHostClient() : FlowHAClient(sizeof(AppIdSessionHATlsHost), false) { } + bool consume(snort::Flow*&, const snort::FlowKey*, snort::HAMessage&, uint8_t size) override; + bool produce(snort::Flow&, snort::HAMessage&) override; +}; + +class AppIdHAManager +{ +public: + static void tinit() + { + if ( snort::HighAvailabilityManager::active() ) + { + ha_apps_client = new AppIdHAAppsClient; + ha_http_client = new AppIdHAHttpClient; + ha_tls_host_client = new AppIdHATlsHostClient; + } + } + static void tterm() + { + if ( snort::HighAvailabilityManager::active() ) + { + delete ha_apps_client; + delete ha_http_client; + delete ha_tls_host_client; + } + } + + static THREAD_LOCAL AppIdHAAppsClient* ha_apps_client; + static THREAD_LOCAL AppIdHAHttpClient* ha_http_client; + static THREAD_LOCAL AppIdHATlsHostClient* ha_tls_host_client; +}; + +#endif diff --git a/src/network_inspectors/appid/appid_http_session.cc b/src/network_inspectors/appid/appid_http_session.cc index 5607cc988..ca77eb4b0 100644 --- a/src/network_inspectors/appid/appid_http_session.cc +++ b/src/network_inspectors/appid/appid_http_session.cc @@ -25,6 +25,7 @@ #include "appid_http_session.h" +#include "flow/ha.h" #include "memory/memory_cap.h" #include "profiler/profiler.h" @@ -71,9 +72,15 @@ void AppIdHttpSession::set_http_change_bits(AppidChangeBits& change_bits, HttpFi { case REQ_HOST_FID: change_bits.set(APPID_HOST_BIT); + assert(asd.flow); + if (asd.flow->ha_state) + asd.flow->ha_state->add(FlowHAState::MODIFIED | FlowHAState::MAJOR); break; case MISC_URL_FID: change_bits.set(APPID_URL_BIT); + assert(asd.flow); + if (asd.flow->ha_state) + asd.flow->ha_state->add(FlowHAState::MODIFIED | FlowHAState::MAJOR); break; case REQ_AGENT_FID: change_bits.set(APPID_USERAGENT_BIT); @@ -401,14 +408,17 @@ void AppIdHttpSession::process_chp_buffers(AppidChangeBits& change_bits, HttpPat } } -void AppIdHttpSession::set_client(AppId app_id, AppidChangeBits& change_bits, const char* type, - const char* version) +void AppIdHttpSession::set_client(AppId app_id, AppidChangeBits& change_bits, + const char* type, const char* version) { if (app_id <= APP_ID_NONE or (app_id == client.get_id())) return; client.set_id(app_id); change_bits.set(APPID_CLIENT_BIT); + assert(asd.flow); + if (asd.flow->ha_state) + asd.flow->ha_state->add(FlowHAState::MODIFIED | FlowHAState::MAJOR); if (version) { client.set_version(version); @@ -423,14 +433,17 @@ void AppIdHttpSession::set_client(AppId app_id, AppidChangeBits& change_bits, co } } -void AppIdHttpSession::set_payload(AppId app_id, AppidChangeBits& change_bits, const char* type, - const char* version) +void AppIdHttpSession::set_payload(AppId app_id, AppidChangeBits& change_bits, + const char* type, const char* version) { if (app_id == APP_ID_NONE or (app_id == payload.get_id())) return; payload.set_id(app_id); change_bits.set(APPID_PAYLOAD_BIT); + assert(asd.flow); + if (asd.flow->ha_state) + asd.flow->ha_state->add(FlowHAState::MODIFIED | FlowHAState::MAJOR); payload.set_version(version); if (appidDebug->is_active()) diff --git a/src/network_inspectors/appid/appid_http_session.h b/src/network_inspectors/appid/appid_http_session.h index fff88a14d..ea7fbe38c 100644 --- a/src/network_inspectors/appid/appid_http_session.h +++ b/src/network_inspectors/appid/appid_http_session.h @@ -150,7 +150,8 @@ public: void clear_all_fields(); void set_client(AppId, AppidChangeBits&, const char*, const char* version = nullptr); - void set_payload(AppId, AppidChangeBits&, const char* type = nullptr, const char* version = nullptr); + void set_payload(AppId, AppidChangeBits&, const char* type = nullptr, + const char* version = nullptr); void set_referred_payload(AppId, AppidChangeBits&); uint32_t get_http2_stream_id() const diff --git a/src/network_inspectors/appid/appid_inspector.cc b/src/network_inspectors/appid/appid_inspector.cc index ffbde7530..238a45bb0 100644 --- a/src/network_inspectors/appid/appid_inspector.cc +++ b/src/network_inspectors/appid/appid_inspector.cc @@ -38,6 +38,7 @@ #include "appid_dcerpc_event_handler.h" #include "appid_debug.h" #include "appid_discovery.h" +#include "appid_ha.h" #include "appid_http_event_handler.h" #include "appid_peg_counts.h" #include "appid_session.h" @@ -160,6 +161,8 @@ void AppIdInspector::tinit() pkt_thread_tp_appid_ctxt->tinit(); if (ctxt->config.log_all_sessions) appidDebug->set_enabled(true); + if ( snort::HighAvailabilityManager::active() ) + AppIdHAManager::tinit(); } void AppIdInspector::tterm() @@ -171,6 +174,8 @@ void AppIdInspector::tterm() odp_thread_local_ctxt = nullptr; if (pkt_thread_tp_appid_ctxt) pkt_thread_tp_appid_ctxt->tfini(); + if ( snort::HighAvailabilityManager::active() ) + AppIdHAManager::tterm(); } void AppIdInspector::eval(Packet* p) diff --git a/src/network_inspectors/appid/appid_session.cc b/src/network_inspectors/appid/appid_session.cc index ba1b793c0..ed7bb5832 100644 --- a/src/network_inspectors/appid/appid_session.cc +++ b/src/network_inspectors/appid/appid_session.cc @@ -890,18 +890,21 @@ AppId AppIdSession::pick_ss_referred_payload_app_id() const void AppIdSession::set_ss_application_ids(AppId service_id, AppId client_id, AppId payload_id, AppId misc_id, AppId referred_id, AppidChangeBits& change_bits) { - api.set_ss_application_ids(service_id, client_id, payload_id, misc_id, referred_id, change_bits); + assert(flow); + api.set_ss_application_ids(service_id, client_id, payload_id, misc_id, referred_id, change_bits, *flow); } void AppIdSession::set_ss_application_ids(AppId client_id, AppId payload_id, AppidChangeBits& change_bits) { - api.set_ss_application_ids(client_id, payload_id, change_bits); + assert(flow); + api.set_ss_application_ids(client_id, payload_id, change_bits, *flow); } void AppIdSession::set_application_ids_service(AppId service_id, AppidChangeBits& change_bits) { - api.set_application_ids_service(service_id, change_bits); + assert(flow); + api.set_application_ids_service(service_id, change_bits, *flow); } void AppIdSession::reset_session_data(AppidChangeBits& change_bits) @@ -1071,6 +1074,23 @@ void AppIdSession::publish_appid_event(AppidChangeBits& change_bits, const Packe api.published = true; } + if (consumed_ha_data) + { + AppIdHttpSession* hsession = get_http_session(); + if (hsession) + { + if (hsession->get_field(MISC_URL_FID)) + change_bits.set(APPID_URL_BIT); + if (hsession->get_field(REQ_HOST_FID)) + change_bits.set(APPID_HOST_BIT); + } + + if (api.get_tls_host()) + change_bits.set(APPID_TLSHOST_BIT); + + consumed_ha_data = false; + } + if (change_bits.none()) return; diff --git a/src/network_inspectors/appid/appid_session.h b/src/network_inspectors/appid/appid_session.h index 4e4fd5344..2eb364d47 100644 --- a/src/network_inspectors/appid/appid_session.h +++ b/src/network_inspectors/appid/appid_session.h @@ -562,6 +562,11 @@ public: api.set_tls_host(tsession->get_tls_host()); } + void set_tls_host(const char* tls_host) + { + api.set_tls_host(tls_host); + } + OdpContext& get_odp_ctxt() const { return odp_ctxt; @@ -610,6 +615,11 @@ public: api.clear_user_logged_in(); } + void set_consumed_ha_data(bool val) + { + consumed_ha_data = val; + } + private: uint16_t prev_http2_raw_packet = 0; @@ -629,6 +639,7 @@ private: OdpContext& odp_ctxt; uint32_t odp_ctxt_version; ThirdPartyAppIdContext* tp_appid_ctxt = nullptr; + bool consumed_ha_data = false; }; #endif diff --git a/src/network_inspectors/appid/appid_session_api.cc b/src/network_inspectors/appid/appid_session_api.cc index aed49b888..8039bc96b 100644 --- a/src/network_inspectors/appid/appid_session_api.cc +++ b/src/network_inspectors/appid/appid_session_api.cc @@ -25,6 +25,7 @@ #include "appid_session_api.h" +#include "flow/ha.h" #include "managers/inspector_manager.h" #include "appid_inspector.h" #include "appid_session.h" @@ -306,27 +307,35 @@ bool AppIdSessionApi::is_http_inspection_done() const } void AppIdSessionApi::set_ss_application_ids(AppId service_id, AppId client_id, - AppId payload_id, AppId misc_id, AppId referred_id, AppidChangeBits& change_bits) + AppId payload_id, AppId misc_id, AppId referred_id, AppidChangeBits& change_bits, Flow& flow) { if (application_ids[APP_PROTOID_SERVICE] != service_id) { application_ids[APP_PROTOID_SERVICE] = service_id; change_bits.set(APPID_SERVICE_BIT); + if (flow.ha_state) + flow.ha_state->add(FlowHAState::MODIFIED | FlowHAState::MAJOR); } if (application_ids[APP_PROTOID_CLIENT] != client_id) { application_ids[APP_PROTOID_CLIENT] = client_id; change_bits.set(APPID_CLIENT_BIT); + if (flow.ha_state) + flow.ha_state->add(FlowHAState::MODIFIED | FlowHAState::MAJOR); } if (application_ids[APP_PROTOID_PAYLOAD] != payload_id) { application_ids[APP_PROTOID_PAYLOAD] = payload_id; change_bits.set(APPID_PAYLOAD_BIT); + if (flow.ha_state) + flow.ha_state->add(FlowHAState::MODIFIED | FlowHAState::MAJOR); } if (application_ids[APP_PROTOID_MISC] != misc_id) { application_ids[APP_PROTOID_MISC] = misc_id; change_bits.set(APPID_MISC_BIT); + if (flow.ha_state) + flow.ha_state->add(FlowHAState::MODIFIED | FlowHAState::MAJOR); } if (application_ids[APP_PROTOID_REFERRED] != referred_id) { @@ -336,26 +345,33 @@ void AppIdSessionApi::set_ss_application_ids(AppId service_id, AppId client_id, } void AppIdSessionApi::set_ss_application_ids(AppId client_id, AppId payload_id, - AppidChangeBits& change_bits) + AppidChangeBits& change_bits, Flow& flow) { if (application_ids[APP_PROTOID_CLIENT] != client_id) { application_ids[APP_PROTOID_CLIENT] = client_id; change_bits.set(APPID_CLIENT_BIT); + if (flow.ha_state) + flow.ha_state->add(FlowHAState::MODIFIED | FlowHAState::MAJOR); } if (application_ids[APP_PROTOID_PAYLOAD] != payload_id) { application_ids[APP_PROTOID_PAYLOAD] = payload_id; change_bits.set(APPID_PAYLOAD_BIT); + if (flow.ha_state) + flow.ha_state->add(FlowHAState::MODIFIED | FlowHAState::MAJOR); } } -void AppIdSessionApi::set_application_ids_service(AppId service_id, AppidChangeBits& change_bits) +void AppIdSessionApi::set_application_ids_service(AppId service_id, AppidChangeBits& change_bits, + Flow& flow) { if (application_ids[APP_PROTOID_SERVICE] != service_id) { application_ids[APP_PROTOID_SERVICE] = service_id; change_bits.set(APPID_SERVICE_BIT); + if (flow.ha_state) + flow.ha_state->add(FlowHAState::MODIFIED | FlowHAState::MAJOR); } } diff --git a/src/network_inspectors/appid/appid_session_api.h b/src/network_inspectors/appid/appid_session_api.h index 19a800bf4..042f3d11a 100644 --- a/src/network_inspectors/appid/appid_session_api.h +++ b/src/network_inspectors/appid/appid_session_api.h @@ -177,9 +177,9 @@ private: static THREAD_LOCAL uint32_t appid_flow_data_id; void set_ss_application_ids(AppId service, AppId client, AppId payload, AppId misc, - AppId referred, AppidChangeBits& change_bits); - void set_ss_application_ids(AppId client, AppId payload, AppidChangeBits& change_bits); - void set_application_ids_service(AppId service_id, AppidChangeBits& change_bits); + AppId referred, AppidChangeBits& change_bits, Flow& flow); + void set_ss_application_ids(AppId client, AppId payload, AppidChangeBits& change_bits, Flow& flow); + void set_application_ids_service(AppId service_id, AppidChangeBits& change_bits, Flow& flow); AppIdHttpSession* get_hsession(uint32_t stream_index = 0) const; diff --git a/src/network_inspectors/appid/test/appid_api_test.cc b/src/network_inspectors/appid/test/appid_api_test.cc index 38d167835..1a5c1f6e6 100644 --- a/src/network_inspectors/appid/test/appid_api_test.cc +++ b/src/network_inspectors/appid/test/appid_api_test.cc @@ -236,86 +236,6 @@ TEST(appid_api, get_application_id) CHECK_EQUAL(id, 1492); } -TEST(appid_api, produce_ha_state) -{ - AppIdSessionHA appHA, cmp_buf; - - memset((void*)&appHA, 0, sizeof(appHA)); - memset((void*)&cmp_buf, 0, sizeof(cmp_buf)); - mock_session->flags |= APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_HTTP_SESSION; - - mock_session->set_tp_app_id(APPID_UT_ID); - mock_session->set_service_id(APPID_UT_ID + 1, stub_odp_ctxt); - mock_session->client_inferred_service_id = APPID_UT_ID + 2; - mock_session->set_port_service_id(APPID_UT_ID + 3); - mock_session->set_payload_id(APPID_UT_ID + 4); - mock_session->set_tp_payload_app_id(APPID_UT_ID + 5); - mock_session->set_client_id(APPID_UT_ID + 6); - mock_session->misc_app_id = APPID_UT_ID + 7; - - uint32_t val = appid_api.produce_ha_state(*flow, (uint8_t*)&appHA); - CHECK_TRUE(val == sizeof(appHA)); - CHECK_TRUE(appHA.appId[0] == APPID_UT_ID); - CHECK_TRUE(appHA.appId[1] == APPID_UT_ID + 1); - CHECK_TRUE(appHA.appId[2] == APPID_UT_ID + 2); - CHECK_TRUE(appHA.appId[3] == APPID_UT_ID + 3); - CHECK_TRUE(appHA.appId[4] == APPID_UT_ID + 4); - CHECK_TRUE(appHA.appId[5] == APPID_UT_ID + 5); - CHECK_TRUE(appHA.appId[6] == APPID_UT_ID + 6); - CHECK_TRUE(appHA.appId[7] == APPID_UT_ID + 7); - CHECK_TRUE(appHA.flags == (APPID_HA_FLAGS_APP | APPID_HA_FLAGS_TP_DONE - | APPID_HA_FLAGS_SVC_DONE | APPID_HA_FLAGS_HTTP)); - - mock_flow_data= nullptr; - SfIp ip; - ip.pton(AF_INET, "192.168.1.222"); - val = appid_api.consume_ha_state(*flow, (uint8_t*)&appHA, 0, IpProtocol::TCP, &ip, 1066); - CHECK_TRUE(val == sizeof(appHA)); - - AppIdSession* session = (AppIdSession*)flow->get_flow_data(AppIdSession::inspector_id); - CHECK_TRUE(session); - CHECK_TRUE(session->get_tp_app_id() == appHA.appId[0]); - CHECK_TRUE(session->get_service_id() == appHA.appId[1]); - CHECK_TRUE(session->client_inferred_service_id == appHA.appId[2]); - CHECK_TRUE(session->get_port_service_id() == appHA.appId[3]); - CHECK_TRUE(session->get_payload_id() == appHA.appId[4]); - CHECK_TRUE(session->get_tp_payload_app_id() == appHA.appId[5]); - CHECK_TRUE(session->get_client_id() == appHA.appId[6]); - CHECK_TRUE(session->misc_app_id == appHA.appId[7]); - CHECK_TRUE(session->service_disco_state == APPID_DISCO_STATE_FINISHED); - CHECK_TRUE(session->client_disco_state == APPID_DISCO_STATE_FINISHED); - delete &session->get_api(); - delete session; - - // test logic when service app is ftp control - appHA.appId[1] = APP_ID_FTP_CONTROL; - mock_flow_data= nullptr; - val = appid_api.consume_ha_state(*flow, (uint8_t*)&appHA, 0, IpProtocol::TCP, &ip, 1066); - CHECK_TRUE(val == sizeof(appHA)); - - session = (AppIdSession*)flow->get_flow_data(AppIdSession::inspector_id); - CHECK_TRUE(session); - uint64_t flags = session->get_session_flags(APPID_SESSION_CLIENT_DETECTED | - APPID_SESSION_NOT_A_SERVICE | APPID_SESSION_SERVICE_DETECTED); - CHECK_TRUE(flags == (APPID_SESSION_CLIENT_DETECTED | APPID_SESSION_NOT_A_SERVICE - | APPID_SESSION_SERVICE_DETECTED)); - CHECK_TRUE(session->get_service_id() == APP_ID_FTP_CONTROL); - CHECK_TRUE(session->service_disco_state == APPID_DISCO_STATE_STATEFUL); - CHECK_TRUE(session->client_disco_state == APPID_DISCO_STATE_FINISHED); - delete &session->get_api(); - delete session; - - flow->set_flow_data(nullptr); - uint32_t val1 = appid_api.produce_ha_state(*flow, (uint8_t*)&appHA); - CHECK_TRUE(val1 == sizeof(appHA)); - CHECK_TRUE(appHA.flags == 0); - - val = appid_api.consume_ha_state(*flow, (uint8_t*)&appHA, 0, IpProtocol::TCP, &ip, 1066); - CHECK_TRUE(val == sizeof(appHA)); - session = (AppIdSession*)flow->get_flow_data(AppIdSession::inspector_id); - CHECK(session == nullptr); -} - TEST(appid_api, ssl_app_group_id_lookup) { mock().expectNCalls(4, "publish"); diff --git a/src/network_inspectors/appid/test/appid_http_session_test.cc b/src/network_inspectors/appid/test/appid_http_session_test.cc index 796680ae7..c046bd0a0 100644 --- a/src/network_inspectors/appid/test/appid_http_session_test.cc +++ b/src/network_inspectors/appid/test/appid_http_session_test.cc @@ -54,6 +54,7 @@ AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) : StashGenericObject(STASH_GENERIC_OBJECT_APPID) {} } +void FlowHAState::add(uint8_t) { } void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { } const char* AppInfoManager::get_app_name(AppId) { @@ -106,6 +107,7 @@ static AppIdConfig stub_config; static AppIdContext stub_ctxt(stub_config); static OdpContext stub_odp_ctxt(stub_config, nullptr); OdpContext* AppIdContext::odp_ctxt = &stub_odp_ctxt; +static Flow flow; // AppIdSession mock functions AppIdSession::AppIdSession(IpProtocol, const SfIp* ip, uint16_t, AppIdInspector& inspector, @@ -181,6 +183,7 @@ TEST_GROUP(appid_http_session) { SfIp sfip; session = new AppIdSession(IpProtocol::IP, &sfip, 0, dummy_appid_inspector, stub_odp_ctxt); + session->flow = &flow; mock_hsession = new AppIdHttpSession(*session, 0); appidDebug = new AppIdDebug(); } @@ -200,20 +203,20 @@ TEST(appid_http_session, http_field_ids_enum_order) // in appid_http_session.h. AppidChangeBits change_bits; - mock_hsession->set_field( (HttpFieldIds)0, new std::string("agent"), change_bits ); - mock_hsession->set_field( (HttpFieldIds)1, new std::string("host"), change_bits ); - mock_hsession->set_field( (HttpFieldIds)2, new std::string("referer"), change_bits ); - mock_hsession->set_field( (HttpFieldIds)3, new std::string("uri"), change_bits ); - mock_hsession->set_field( (HttpFieldIds)4, new std::string("cookie"), change_bits ); - mock_hsession->set_field( (HttpFieldIds)5, new std::string("req_body"), change_bits ); - mock_hsession->set_field( (HttpFieldIds)6, new std::string("content_type"), change_bits ); - mock_hsession->set_field( (HttpFieldIds)7, new std::string("location"), change_bits ); - mock_hsession->set_field( (HttpFieldIds)8, new std::string("rsp_body"), change_bits ); - mock_hsession->set_field( (HttpFieldIds)9, new std::string("via"), change_bits ); - mock_hsession->set_field( (HttpFieldIds)10, new std::string("response_code"), change_bits ); - mock_hsession->set_field( (HttpFieldIds)11, new std::string("server"), change_bits ); - mock_hsession->set_field( (HttpFieldIds)12, new std::string("xww"), change_bits ); - mock_hsession->set_field( (HttpFieldIds)13, new std::string("url"), change_bits ); + mock_hsession->set_field( (HttpFieldIds)0, new std::string("agent"), change_bits); + mock_hsession->set_field( (HttpFieldIds)1, new std::string("host"), change_bits); + mock_hsession->set_field( (HttpFieldIds)2, new std::string("referer"), change_bits); + mock_hsession->set_field( (HttpFieldIds)3, new std::string("uri"), change_bits); + mock_hsession->set_field( (HttpFieldIds)4, new std::string("cookie"), change_bits); + mock_hsession->set_field( (HttpFieldIds)5, new std::string("req_body"), change_bits); + mock_hsession->set_field( (HttpFieldIds)6, new std::string("content_type"), change_bits); + mock_hsession->set_field( (HttpFieldIds)7, new std::string("location"), change_bits); + mock_hsession->set_field( (HttpFieldIds)8, new std::string("rsp_body"), change_bits); + mock_hsession->set_field( (HttpFieldIds)9, new std::string("via"), change_bits); + mock_hsession->set_field( (HttpFieldIds)10, new std::string("response_code"), change_bits); + mock_hsession->set_field( (HttpFieldIds)11, new std::string("server"), change_bits); + mock_hsession->set_field( (HttpFieldIds)12, new std::string("xww"), change_bits); + mock_hsession->set_field( (HttpFieldIds)13, new std::string("url"), change_bits); const std::string* field; field = mock_hsession->get_field(REQ_AGENT_FID); @@ -308,7 +311,7 @@ TEST(appid_http_session, change_bits_for_referred_appid) session->set_service_id(APP_ID_HTTP, odp_ctxt); session->scan_flags |= SCAN_HTTP_HOST_URL_FLAG; mock_hsession->set_skip_simple_detect(false); - mock_hsession->set_field( (HttpFieldIds)2, new std::string("referer"), change_bits ); + mock_hsession->set_field( (HttpFieldIds)2, new std::string("referer"), change_bits); mock_hsession->process_http_packet(APP_ID_FROM_INITIATOR, change_bits, odp_ctxt.get_http_matchers()); // Detect changes in referred appid diff --git a/src/network_inspectors/appid/test/appid_mock_session.h b/src/network_inspectors/appid/test/appid_mock_session.h index b5cdc4076..eef95e2b7 100644 --- a/src/network_inspectors/appid/test/appid_mock_session.h +++ b/src/network_inspectors/appid/test/appid_mock_session.h @@ -21,6 +21,8 @@ #ifndef APPID_MOCK_SESSION_H #define APPID_MOCK_SESSION_H +#include "flow/ha.h" + #include "appid_dns_session.h" #include "appid_mock_flow.h" #include "appid_mock_http_session.h" @@ -75,6 +77,8 @@ AppIdConfig::~AppIdConfig() { } OdpContext::OdpContext(const AppIdConfig&, snort::SnortConfig*) { } OdpContext::~OdpContext() { } +void FlowHAState::add(uint8_t) { } + static AppIdConfig stub_config; static AppIdContext stub_ctxt(stub_config); static OdpContext stub_odp_ctxt(stub_config, nullptr); diff --git a/src/network_inspectors/appid/test/appid_session_api_test.cc b/src/network_inspectors/appid/test/appid_session_api_test.cc index 23708855b..9c86bae12 100644 --- a/src/network_inspectors/appid/test/appid_session_api_test.cc +++ b/src/network_inspectors/appid/test/appid_session_api_test.cc @@ -34,6 +34,7 @@ AppIdSession* mock_session = nullptr; AppIdSessionApi* appid_session_api = nullptr; static AppIdConfig config; static OdpContext odpctxt(config, nullptr); +static Flow flow; void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { } @@ -53,12 +54,12 @@ namespace snort void AppIdSession::set_ss_application_ids(AppId service_id, AppId client_id, AppId payload_id, AppId misc_id, AppId referred_id, AppidChangeBits& change_bits) { - api.set_ss_application_ids(service_id, client_id, payload_id, misc_id, referred_id, change_bits); + api.set_ss_application_ids(service_id, client_id, payload_id, misc_id, referred_id, change_bits, *flow); } void AppIdSession::set_application_ids_service(AppId service_id, AppidChangeBits& change_bits) { - api.set_application_ids_service(service_id, change_bits); + api.set_application_ids_service(service_id, change_bits, *flow); } TEST_GROUP(appid_session_api) @@ -69,6 +70,7 @@ TEST_GROUP(appid_session_api) SfIp ip; mock_session = new AppIdSession(IpProtocol::TCP, &ip, 1492, dummy_appid_inspector, odpctxt); + mock_session->flow = &flow; pkt_thread_odp_ctxt = &mock_session->get_odp_ctxt(); mock_session->set_ss_application_ids(APPID_UT_ID, APPID_UT_ID, APPID_UT_ID, APPID_UT_ID, APPID_UT_ID, change_bits); @@ -131,6 +133,7 @@ TEST(appid_session_api, get_app_id) { SfIp ip; AppIdSession asd(IpProtocol::TCP, &ip, 1492, dummy_appid_inspector, odpctxt); + asd.flow = &flow; AppidChangeBits change_bits; asd.set_application_ids_service(APP_ID_HTTP2, change_bits);