)
set ( UTIL_APPID_SOURCES
- util/common_util.h
- util/fw_avltree.cc
- util/fw_avltree.h
- util/ip_funcs.cc
- util/ip_funcs.h
- util/network_set.cc
- util/network_set.h
- util/output_file.cc
- util/output_file.h
- util/sfksearch.cc
- util/sfksearch.h
- util/sf_mlmp.cc
- util/sf_mlmp.h
- util/sf_multi_mpse.cc
- util/sf_multi_mpse.h
- util/sfutil.cc
- util/sfutil.h
+ appid_utils/common_util.h
+ appid_utils/fw_avltree.cc
+ appid_utils/fw_avltree.h
+ appid_utils/ip_funcs.cc
+ appid_utils/ip_funcs.h
+ appid_utils/network_set.cc
+ appid_utils/network_set.h
+ appid_utils/output_file.cc
+ appid_utils/output_file.h
+ appid_utils/sfksearch.cc
+ appid_utils/sfksearch.h
+ appid_utils/sf_mlmp.cc
+ appid_utils/sf_mlmp.h
+ appid_utils/sf_multi_mpse.cc
+ appid_utils/sf_multi_mpse.h
+ appid_utils/sfutil.cc
+ appid_utils/sfutil.h
)
set ( APPID_SOURCES
appid_api.h
appid_config.cc
appid_config.h
- appid_flow_data.cc
- appid_flow_data.h
+ appid_session.cc
+ appid_session.h
appid.h
appid_inspector.cc
appid_inspector.h
app_info_table.cc
app_info_table.h
application_ids.h
- dns_defs.h
flow_error.h
fw_appid.cc
fw_appid.h
service_plugins/service_util.h
util_file_list = \
-util/common_util.h \
-util/fw_avltree.cc \
-util/fw_avltree.h \
-util/ip_funcs.cc \
-util/ip_funcs.h \
-util/network_set.cc \
-util/network_set.h \
-util/output_file.cc \
-util/output_file.h \
-util/sfksearch.cc \
-util/sfksearch.h \
-util/sf_mlmp.cc \
-util/sf_mlmp.h \
-util/sf_multi_mpse.cc \
-util/sf_multi_mpse.h \
-util/sfutil.cc \
-util/sfutil.h
+appid_utils/common_util.h \
+appid_utils/fw_avltree.cc \
+appid_utils/fw_avltree.h \
+appid_utils/ip_funcs.cc \
+appid_utils/ip_funcs.h \
+appid_utils/network_set.cc \
+appid_utils/network_set.h \
+appid_utils/output_file.cc \
+appid_utils/output_file.h \
+appid_utils/sfksearch.cc \
+appid_utils/sfksearch.h \
+appid_utils/sf_mlmp.cc \
+appid_utils/sf_mlmp.h \
+appid_utils/sf_multi_mpse.cc \
+appid_utils/sf_multi_mpse.h \
+appid_utils/sfutil.cc \
+appid_utils/sfutil.h
file_list = \
app_forecast.cc \
appid_api.h \
appid_config.cc \
appid_config.h \
-appid_flow_data.cc \
-appid_flow_data.h \
+appid_session.cc \
+appid_session.h \
appid.h \
appid_inspector.cc \
appid_inspector.h \
app_info_table.cc \
app_info_table.h \
application_ids.h \
-dns_defs.h \
flow_error.h \
fw_appid.cc \
fw_appid.h \
}
AppId checkSessionForAFForecast(
- AppIdData* session, Packet* p, int dir, const AppIdConfig* pConfig, ApplicationId forecast)
+ AppIdSession* session, Packet* p, int dir, const AppIdConfig* pConfig, ApplicationId forecast)
{
AFActVal* check_act_val;
return APP_ID_UNKNOWN;
}
- session->payloadAppId = check_act_val->target;
+ session->payload_app_id = check_act_val->target;
return forecast;
}
#include "appid_config.h"
#include "protocols/packet.h"
-#include "appid_flow_data.h"
+#include "appid_session.h"
// indicator - the appId that indicates there may be subsequent flows to look for, from the same host
// forecast - the appId in the subsequent flow that we are looking for
};
void checkSessionForAFIndicator(Packet*, int, const AppIdConfig*, ApplicationId);
-AppId checkSessionForAFForecast(AppIdData*, Packet*, int, const AppIdConfig*, ApplicationId);
+AppId checkSessionForAFForecast(AppIdSession*, Packet*, int, const AppIdConfig*, ApplicationId);
#endif
#include "target_based/snort_protocols.h"
#include "utils/util.h"
-#define APP_MAPPING_FILE "appMapping.data"
-#define APP_CONFIG_FILE "appid.conf"
-#define USR_CONFIG_FILE "userappid.conf"
-
#define MAX_TABLE_LINE_LEN 1024
#define CONF_SEPARATORS "\t\n\r"
#define MIN_MAX_TP_FLOW_DEPTH 1
{
SFGHASH* appNameHash;
appNameHash = sfghash_new(65, 0, 0 /* alloc copies of lowercased keys */, nullptr);
- if (!appNameHash)
- {
- FatalError("AppNameHash: Failed to Initialize\n");
- }
return appNameHash;
}
return;
searchName = strdupToLower(appName);
- if (!searchName)
- return;
-
if (SFGHASH_OK == (errCode = sfghash_add(appNameHash, searchName, data)))
{
DebugFormat(DEBUG_INSPECTOR, "App name added for %s\n", appName);
return nullptr;
searchName = strdupToLower(appName);
- if (!searchName)
- return nullptr;
-
data = sfghash_find(appNameHash, searchName);
-
snort_free(searchName);
return data;
AppInfoTableEntry* appInfoEntryGet(AppId, const AppIdConfig*);
AppInfoTableEntry* appInfoEntryCreate(const char* appName, AppIdConfig*);
AppId appGetSnortIdFromAppId(AppId);
+AppId appGetAppFromServiceId(uint32_t appId, AppIdConfig* pConfig);
+AppId appGetAppFromClientId(uint32_t appId, AppIdConfig* pConfig);
+AppId appGetAppFromPayloadId(uint32_t appId, AppIdConfig* pConfig);
void AppIdDumpStats(int exit_flag);
void appInfoTableDump(AppIdConfig*);
void appInfoSetActive(AppId, bool active);
// FIXIT-M J this should go in a separate header
#define DHCP_OPTION55_LEN_MAX 255
-// FIXIT-M J this should go in a separate header
#define FINGERPRINT_UDP_FLAGS_XENIX 0x00000800
#define FINGERPRINT_UDP_FLAGS_NT 0x00001000
#define FINGERPRINT_UDP_FLAGS_MASK (FINGERPRINT_UDP_FLAGS_XENIX | FINGERPRINT_UDP_FLAGS_NT)
+using AppIdFreeFCN = void(*)(void*);
+
#endif
#define SSL_WHITELIST_PKT_LIMIT 20
-AppId getServiceAppId(AppIdData* appIdData)
+AppIdApi appid_api;
+
+const char* AppIdApi::get_application_name(int32_t app_id)
+{
+ return appGetAppName(app_id);
+}
+
+AppId AppIdApi::get_application_id(const char* appName)
{
- if (appIdData)
- return pickServiceAppId(appIdData);
+ return appGetAppId(appName);
+}
+
+AppId AppIdApi::get_service_app_id(AppIdSession* session)
+{
+ if (session)
+ return session->pick_service_app_id();
return APP_ID_NONE;
}
-AppId getOnlyServiceAppId(AppIdData* appIdData)
+AppId AppIdApi::get_port_service_app_id(AppIdSession* session)
{
- if (appIdData)
- return pickOnlyServiceAppId(appIdData);
+ if (session)
+ return session->portServiceAppId;
+ return APP_ID_NONE;
+}
+
+AppId AppIdApi::get_only_service_app_id(AppIdSession* session)
+{
+ if (session)
+ return session->pick_only_service_app_id();
return APP_ID_NONE;
}
-AppId getMiscAppId(AppIdData* appIdData)
+AppId AppIdApi::get_misc_app_id(AppIdSession* session)
{
- if (appIdData)
- return pickMiscAppId(appIdData);
+ if (session)
+ return session->pick_misc_app_id();
return APP_ID_NONE;
}
-AppId getClientAppId(AppIdData* appIdData)
+AppId AppIdApi::get_client_app_id(AppIdSession* session)
{
- if (appIdData)
- return pickClientAppId(appIdData);
+ if (session)
+ return session->pick_client_app_id();
return APP_ID_NONE;
}
-AppId getPayloadAppId(AppIdData* appIdData)
+AppId AppIdApi::get_payload_app_id(AppIdSession* session)
{
- if (appIdData)
- return pickPayloadId(appIdData);
+ if (session)
+ return session->pick_payload_app_id();
return APP_ID_NONE;
}
-AppId getReferredAppId(AppIdData* appIdData)
+AppId AppIdApi::get_referred_app_id(AppIdSession* session)
{
- if (appIdData)
- return pickReferredPayloadId(appIdData);
+ if (session)
+ return session->pick_referred_payload_app_id();
return APP_ID_NONE;
}
-AppId getFwServiceAppId(AppIdData* appIdData)
+AppId AppIdApi::get_fw_service_app_id(AppIdSession* session)
{
- if (appIdData)
- return fwPickServiceAppId(appIdData);
+ if (session)
+ return session->fw_pick_service_app_id();
return APP_ID_NONE;
}
-AppId getFwMiscAppId(AppIdData* appIdData)
+AppId AppIdApi::get_fw_misc_app_id(AppIdSession* session)
{
- if (appIdData)
- return fwPickMiscAppId(appIdData);
+ if (session)
+ return session->fw_pick_misc_app_id();
return APP_ID_NONE;
}
-AppId getFwClientAppId(AppIdData* appIdData)
+AppId AppIdApi::get_fw_client_app_id(AppIdSession* session)
{
- if (appIdData)
- return fwPickClientAppId(appIdData);
+ if (session)
+ return session->fw_pick_client_app_id();
return APP_ID_NONE;
}
-AppId getFwPayloadAppId(AppIdData* appIdData)
+AppId AppIdApi::get_fw_payload_app_id(AppIdSession* session)
{
- if (appIdData)
- return fwPickPayloadAppId(appIdData);
+ if (session)
+ return session->fw_pick_payload_app_id();
return APP_ID_NONE;
}
-AppId getFwReferredAppId(AppIdData* appIdData)
+AppId AppIdApi::get_fw_referred_app_id(AppIdSession* session)
{
- if (appIdData)
- return fwPickReferredPayloadAppId(appIdData);
+ if (session)
+ return session->fw_pick_referred_payload_app_id();
return APP_ID_NONE;
}
-bool isSessionSslDecrypted(AppIdData* appIdData)
+bool AppIdApi::is_ssl_session_decrypted(AppIdSession* session)
{
- if (appIdData)
- return isFwSessionSslDecrypted(appIdData);
+ if (session)
+ return session->is_ssl_session_decrypted();
return false;
}
-AppIdData* getAppIdData(void* lwssn)
+AppIdSession* AppIdApi::get_appid_data(Flow* flow)
{
- AppIdData* appIdData = (AppIdData*)(((Flow*)lwssn)->get_application_data(AppIdData::flow_id));
+ AppIdSession* session = (AppIdSession*) flow->get_application_data(AppIdSession::flow_id);
- return (appIdData && appIdData->common.fsf_type.flow_type == APPID_SESSION_TYPE_NORMAL) ?
- appIdData : nullptr;
+ return (session && session->common.fsf_type.flow_type == APPID_SESSION_TYPE_NORMAL) ?
+ session : nullptr;
}
-bool IsAppIdInspectingSession(AppIdData* appIdSession)
+bool AppIdApi::is_appid_inspecting_session(AppIdSession* appIdSession)
{
if (appIdSession && appIdSession->common.fsf_type.flow_type == APPID_SESSION_TYPE_NORMAL)
{
if (appIdSession->rnaServiceState != RNA_STATE_FINISHED ||
!TPIsAppIdDone(appIdSession->tpsession) ||
- getAppIdFlag(appIdSession, APPID_SESSION_HTTP_SESSION | APPID_SESSION_CONTINUE) ||
- (getAppIdFlag(appIdSession, APPID_SESSION_ENCRYPTED) &&
- (getAppIdFlag(appIdSession, APPID_SESSION_DECRYPTED) ||
- appIdSession->session_packet_count < SSL_WHITELIST_PKT_LIMIT)))
+ appIdSession->getAppIdFlag(APPID_SESSION_HTTP_SESSION | APPID_SESSION_CONTINUE) ||
+ (appIdSession->getAppIdFlag(APPID_SESSION_ENCRYPTED) &&
+ (appIdSession->getAppIdFlag(APPID_SESSION_DECRYPTED) ||
+ appIdSession->session_packet_count < SSL_WHITELIST_PKT_LIMIT)))
{
return true;
}
- if (appIdSession->rnaClientState != RNA_STATE_FINISHED &&
- (!getAppIdFlag(appIdSession, APPID_SESSION_CLIENT_DETECTED) ||
- (appIdSession->rnaServiceState != RNA_STATE_STATEFUL && getAppIdFlag(appIdSession,
- APPID_SESSION_CLIENT_GETS_SERVER_PACKETS))))
+ if (appIdSession->rna_client_state != RNA_STATE_FINISHED &&
+ (!appIdSession->getAppIdFlag(APPID_SESSION_CLIENT_DETECTED) ||
+ (appIdSession->rnaServiceState != RNA_STATE_STATEFUL
+ && appIdSession->getAppIdFlag(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS))))
{
return true;
}
- if (appIdSession->tpAppId == APP_ID_SSH && appIdSession->payloadAppId != APP_ID_SFTP &&
+ if (appIdSession->tp_app_id == APP_ID_SSH && appIdSession->payload_app_id != APP_ID_SFTP &&
appIdSession->session_packet_count < MAX_SFTP_PACKET_COUNT)
{
return true;
return false;
}
-char* getUserName(AppIdData* appIdData, AppId* service, bool* isLoginSuccessful)
+char* AppIdApi::get_user_name(AppIdSession* session, AppId* service, bool* isLoginSuccessful)
{
char* userName = nullptr;
- if (appIdData)
+ if (session)
{
- userName = appIdData->username;
- *service = appIdData->usernameService;
- *isLoginSuccessful = getAppIdFlag(appIdData, APPID_SESSION_LOGIN_SUCCEEDED) ? true : false;
- appIdData->username = nullptr; //transfer ownership to caller.
+ userName = session->username;
+ *service = session->username_service;
+ *isLoginSuccessful = session->getAppIdFlag(APPID_SESSION_LOGIN_SUCCEEDED) ? true : false;
+ session->username = nullptr; //transfer ownership to caller.
return userName;
}
return nullptr;
}
-bool isAppIdAvailable(AppIdData* appIdData)
+bool AppIdApi::is_appid_available(AppIdSession* session)
{
- if (appIdData)
+ if (session)
{
- if (getAppIdFlag(appIdData, APPID_SESSION_NO_TPI))
+ if (session->getAppIdFlag(APPID_SESSION_NO_TPI))
return true;
- return TPIsAppIdAvailable(appIdData->tpsession);
+ return TPIsAppIdAvailable(session->tpsession);
}
return false;
}
-char* getClientVersion(AppIdData* appIdData)
+char* AppIdApi::get_client_version(AppIdSession* session)
{
- return appIdData ? appIdData->clientVersion : nullptr;
+ return session ? session->client_version : nullptr;
}
-uint64_t getAppIdSessionAttribute(AppIdData* appIdData, uint64_t flags)
+uint64_t AppIdApi::get_appid_session_attribute(AppIdSession* session, uint64_t flags)
{
- return appIdData ? getAppIdFlag(appIdData, flags) : 0;
+ return session ? session->getAppIdFlag(flags) : 0;
}
-APPID_FLOW_TYPE getFlowType(AppIdData* appIdData)
+APPID_FLOW_TYPE AppIdApi::get_flow_type(AppIdSession* session)
{
- return appIdData ? appIdData->common.fsf_type.flow_type : APPID_FLOW_TYPE_IGNORE;
+ return session ? session->common.fsf_type.flow_type : APPID_FLOW_TYPE_IGNORE;
}
-void getServiceInfo(AppIdData* appIdData, char** serviceVendor, char** serviceVersion,
+void AppIdApi::get_service_info(AppIdSession* session, char** serviceVendor, char** serviceVersion,
RNAServiceSubtype** serviceSubtype)
{
- if (appIdData)
+ if (session)
{
- *serviceVendor = appIdData->serviceVendor;
- *serviceVersion = appIdData->serviceVersion;
- *serviceSubtype = appIdData->subtype;
+ *serviceVendor = session->serviceVendor;
+ *serviceVersion = session->serviceVersion;
+ *serviceSubtype = session->subtype;
}
else
{
}
}
-short getServicePort(AppIdData* appIdData)
+short AppIdApi::get_service_port(AppIdSession* session)
{
- if (appIdData)
- return appIdData->service_port;
+ if (session)
+ return session->service_port;
return 0;
}
-char* getHttpUserAgent(AppIdData* appIdData)
+char* AppIdApi::get_http_user_agent(AppIdSession* session)
{
- if (appIdData && appIdData->hsession)
- return appIdData->hsession->useragent;
+ if (session && session->hsession)
+ return session->hsession->useragent;
return nullptr;
}
-char* getHttpHost(AppIdData* appIdData)
+char* AppIdApi::get_http_host(AppIdSession* session)
{
- if (appIdData && appIdData->hsession)
- return appIdData->hsession->host;
+ if (session && session->hsession)
+ return session->hsession->host;
return nullptr;
}
-char* getHttpUrl(AppIdData* appIdData)
+char* AppIdApi::get_http_url(AppIdSession* session)
{
- if (appIdData && appIdData->hsession)
- return appIdData->hsession->url;
+ if (session && session->hsession)
+ return session->hsession->url;
return nullptr;
}
-char* getHttpReferer(AppIdData* appIdData)
+char* AppIdApi::get_http_referer(AppIdSession* session)
{
- if (appIdData && appIdData->hsession)
- return appIdData->hsession->referer;
+ if (session && session->hsession)
+ return session->hsession->referer;
return nullptr;
}
-char* getHttpNewUrl(AppIdData* appIdData)
+char* AppIdApi::get_http_new_url(AppIdSession* session)
{
- if (appIdData && appIdData->hsession)
- return appIdData->hsession->new_field[REQ_URI_FID];
+ if (session && session->hsession)
+ return session->hsession->new_field[REQ_URI_FID];
return nullptr;
}
-char* getHttpUri(AppIdData* appIdData)
+char* AppIdApi::get_http_uri(AppIdSession* session)
{
- if (appIdData && appIdData->hsession)
- return appIdData->hsession->uri;
+ if (session && session->hsession)
+ return session->hsession->uri;
return nullptr;
}
-char* getHttpResponseCode(AppIdData* appIdData)
+char* AppIdApi::get_http_response_code(AppIdSession* session)
{
- if (appIdData && appIdData->hsession)
- return appIdData->hsession->response_code;
+ if (session && session->hsession)
+ return session->hsession->response_code;
return nullptr;
}
-char* getHttpCookie(AppIdData* appIdData)
+char* AppIdApi::get_http_cookie(AppIdSession* session)
{
- if (appIdData && appIdData->hsession)
- return appIdData->hsession->cookie;
+ if (session && session->hsession)
+ return session->hsession->cookie;
return nullptr;
}
-char* getHttpNewCookie(AppIdData* appIdData)
+char* AppIdApi::get_http_new_cookie(AppIdSession* session)
{
- if (appIdData && appIdData->hsession)
- return appIdData->hsession->new_field[REQ_COOKIE_FID];
+ if (session && session->hsession)
+ return session->hsession->new_field[REQ_COOKIE_FID];
return nullptr;
}
-char* getHttpNewField(AppIdData* appIdData, HTTP_FIELD_ID fieldId)
+char* AppIdApi::get_http_new_field(AppIdSession* session, HTTP_FIELD_ID fieldId)
{
- if (appIdData && appIdData->hsession && fieldId >= 0 && fieldId <= HTTP_FIELD_MAX)
- return appIdData->hsession->new_field[fieldId];
+ if (session && session->hsession && fieldId >= 0 && fieldId <= HTTP_FIELD_MAX)
+ return session->hsession->new_field[fieldId];
return nullptr;
}
-void freeHttpNewField(AppIdData* appIdData, HTTP_FIELD_ID fieldId)
+void AppIdApi::free_http_new_field(AppIdSession* session, HTTP_FIELD_ID fieldId)
{
- if (appIdData && appIdData->hsession && fieldId >= 0 && fieldId <= HTTP_FIELD_MAX &&
- nullptr != appIdData->hsession->new_field[fieldId])
+ if (session && session->hsession && fieldId >= 0 && fieldId <= HTTP_FIELD_MAX &&
+ nullptr != session->hsession->new_field[fieldId])
{
- snort_free(appIdData->hsession->new_field[fieldId]);
- appIdData->hsession->new_field[fieldId] = nullptr;
+ snort_free(session->hsession->new_field[fieldId]);
+ session->hsession->new_field[fieldId] = nullptr;
}
}
-char* getHttpContentType(AppIdData* appIdData)
+char* AppIdApi::get_http_content_type(AppIdSession* session)
{
- if (appIdData && appIdData->hsession)
- return appIdData->hsession->content_type;
+ if (session && session->hsession)
+ return session->hsession->content_type;
return nullptr;
}
-char* getHttpLocation(AppIdData* appIdData)
+char* AppIdApi::get_http_location(AppIdSession* session)
{
- if (appIdData && appIdData->hsession)
- return appIdData->hsession->location;
+ if (session && session->hsession)
+ return session->hsession->location;
return nullptr;
}
-char* getHttpBody(AppIdData* appIdData)
+char* AppIdApi::get_http_body(AppIdSession* session)
{
- if (appIdData && appIdData->hsession)
- return appIdData->hsession->body;
+ if (session && session->hsession)
+ return session->hsession->body;
return nullptr;
}
-char* getHttpReqBody(AppIdData* appIdData)
+char* AppIdApi::get_http_request_body(AppIdSession* session)
{
- if (appIdData && appIdData->hsession)
- return appIdData->hsession->req_body;
+ if (session && session->hsession)
+ return session->hsession->req_body;
return nullptr;
}
-uint16_t getHttpUriOffset(AppIdData* appIdData)
+uint16_t AppIdApi::get_http_uri_offset(AppIdSession* session)
{
- if (appIdData && appIdData->hsession)
- return appIdData->hsession->uriOffset;
+ if (session && session->hsession)
+ return session->hsession->uriOffset;
return 0;
}
-uint16_t getHttpUriEndOffset(AppIdData* appIdData)
+uint16_t AppIdApi::get_http_uri_end_offset(AppIdSession* session)
{
- if (appIdData && appIdData->hsession)
- return appIdData->hsession->uriEndOffset;
+ if (session && session->hsession)
+ return session->hsession->uriEndOffset;
return 0;
}
-uint16_t getHttpCookieOffset(AppIdData* appIdData)
+uint16_t AppIdApi::get_http_cookie_offset(AppIdSession* session)
{
- if (appIdData && appIdData->hsession)
- return appIdData->hsession->cookieOffset;
+ if (session && session->hsession)
+ return session->hsession->cookieOffset;
return 0;
}
-uint16_t getHttpCookieEndOffset(AppIdData* appIdData)
+uint16_t AppIdApi::get_http_cookie_end_offset(AppIdSession* session)
{
- if (appIdData && appIdData->hsession)
- return appIdData->hsession->cookieEndOffset;
+ if (session && session->hsession)
+ return session->hsession->cookieEndOffset;
return 0;
}
-SEARCH_SUPPORT_TYPE getHttpSearch(AppIdData* appIdData)
+SEARCH_SUPPORT_TYPE AppIdApi::get_http_search(AppIdSession* session)
{
- if (appIdData)
- return (appIdData->search_support_type != SEARCH_SUPPORT_TYPE_UNKNOWN) ?
- appIdData->search_support_type : NOT_A_SEARCH_ENGINE;
+ if (session)
+ return (session->search_support_type != SEARCH_SUPPORT_TYPE_UNKNOWN) ?
+ session->search_support_type : NOT_A_SEARCH_ENGINE;
return NOT_A_SEARCH_ENGINE;
}
// FIXIT used to be sfaddr_t
-sfip_t* getHttpXffAddr(AppIdData* appIdData)
+sfip_t* AppIdApi::get_http_xff_addr(AppIdSession* session)
{
- if (appIdData && appIdData->hsession)
- return appIdData->hsession->xffAddr;
+ if (session && session->hsession)
+ return session->hsession->xffAddr;
return nullptr;
}
-char* getTlsHost(AppIdData* appIdData)
+char* AppIdApi::get_tls_host(AppIdSession* session)
{
- if (appIdData && appIdData->tsession)
- return appIdData->tsession->tls_host;
+ if (session && session->tsession)
+ return session->tsession->tls_host;
return nullptr;
}
-AppId getPorServiceAppId(AppIdData* appIdData)
-{
- if (appIdData)
- return appIdData->portServiceAppId;
- return APP_ID_NONE;
-}
-
// FIXIT used to be sfaddr_t
-sfip_t* getServiceIp(AppIdData* appIdData)
+sfip_t* AppIdApi::get_service_ip(AppIdSession* session)
{
- if (appIdData)
- return &appIdData->service_ip;
+ if (session)
+ return &session->service_ip;
return nullptr;
}
// FIXIT used to be sfaddr_t
-sfip_t* getInitiatorIp(AppIdData* appIdData)
+sfip_t* AppIdApi::get_initiator_ip(AppIdSession* session)
{
- return appIdData ? &appIdData->common.initiator_ip : nullptr;
+ return session ? &session->common.initiator_ip : nullptr;
}
-DhcpFPData* getDhcpFpData(AppIdData* appIdData)
+DhcpFPData* AppIdApi::get_dhcp_fp_data(AppIdSession* session)
{
- if (appIdData && getAppIdFlag(appIdData, APPID_SESSION_HAS_DHCP_FP))
+ if (session && session->getAppIdFlag(APPID_SESSION_HAS_DHCP_FP))
return static_cast<DhcpFPData*>(
- AppIdFlowdataRemove(appIdData, APPID_SESSION_DATA_DHCP_FP_DATA));
+ session->remove_flow_data(APPID_SESSION_DATA_DHCP_FP_DATA));
return nullptr;
}
-void freeDhcpFpData(AppIdData* appIdData, DhcpFPData* data)
+void AppIdApi::free_dhcp_fp_data(AppIdSession* session, DhcpFPData* data)
{
- if (appIdData)
+ if (session)
{
- clearAppIdFlag(appIdData, APPID_SESSION_HAS_DHCP_FP);
+ session->clearAppIdFlag(APPID_SESSION_HAS_DHCP_FP);
AppIdFreeDhcpData(data);
}
}
-DHCPInfo* getDhcpInfo(AppIdData* appIdData)
+DHCPInfo* AppIdApi::get_dhcp_info(AppIdSession* session)
{
- if (appIdData && getAppIdFlag(appIdData, APPID_SESSION_HAS_DHCP_INFO))
+ if (session && session->getAppIdFlag(APPID_SESSION_HAS_DHCP_INFO))
return static_cast<DHCPInfo*>(
- AppIdFlowdataRemove(appIdData, APPID_SESSION_DATA_DHCP_INFO));
+ session->remove_flow_data(APPID_SESSION_DATA_DHCP_INFO));
return nullptr;
}
-void freeDhcpInfo(AppIdData* appIdData, DHCPInfo* data)
+void AppIdApi::free_dhcp_info(AppIdSession* session, DHCPInfo* data)
{
- if (appIdData)
+ if (session)
{
- clearAppIdFlag(appIdData, APPID_SESSION_HAS_DHCP_INFO);
+ session->clearAppIdFlag(APPID_SESSION_HAS_DHCP_INFO);
AppIdFreeDhcpInfo(data);
}
}
-FpSMBData* getSmbFpData(AppIdData* appIdData)
+FpSMBData* AppIdApi::get_smb_fp_data(AppIdSession* session)
{
- if (appIdData && getAppIdFlag(appIdData, APPID_SESSION_HAS_SMB_INFO))
+ if (session && session->getAppIdFlag(APPID_SESSION_HAS_SMB_INFO))
return static_cast<FpSMBData*>(
- AppIdFlowdataRemove(appIdData, APPID_SESSION_DATA_SMB_DATA));
+ session->remove_flow_data(APPID_SESSION_DATA_SMB_DATA));
return nullptr;
}
-void freeSmbFpData(AppIdData* appIdData, FpSMBData* data)
+void AppIdApi::free_smb_fp_data(AppIdSession* session, FpSMBData* data)
{
- if (appIdData)
+ if (session)
{
- clearAppIdFlag(appIdData, APPID_SESSION_HAS_SMB_INFO);
+ session->clearAppIdFlag(APPID_SESSION_HAS_SMB_INFO);
AppIdFreeSMBData(data);
}
}
-char* getNetbiosName(AppIdData* appIdData)
+char* AppIdApi::get_netbios_name(AppIdSession* session)
{
- if (appIdData)
+ if (session)
{
- char* netbiosName = appIdData->netbios_name;
- appIdData->netbios_name = nullptr; //transfer ownership to caller.
+ char* netbiosName = session->netbios_name;
+ session->netbios_name = nullptr; //transfer ownership to caller.
return netbiosName;
}
return nullptr;
#define APPID_HA_FLAGS_SVC_DONE (1<<2)
#define APPID_HA_FLAGS_HTTP (1<<3)
-uint32_t produceHAState(void* lwssn, uint8_t* buf)
+uint32_t AppIdApi::produce_ha_state(void* lwssn, uint8_t* buf)
{
AppIdSessionHA* appHA = (AppIdSessionHA*)buf;
- AppIdData* appIdData = (AppIdData*)(((Flow*)lwssn)->get_application_data(AppIdData::flow_id));
+ AppIdSession* session = (AppIdSession*)(((Flow*)lwssn)->get_application_data(AppIdSession::flow_id));
// FIXIT - getFlowType should be a class member
- if (appIdData && getFlowType(appIdData) != APPID_FLOW_TYPE_NORMAL)
- appIdData = nullptr;
- if (appIdData)
+ if (session && get_flow_type(session) != APPID_FLOW_TYPE_NORMAL)
+ session = nullptr;
+ if (session)
{
appHA->flags = APPID_HA_FLAGS_APP;
- if (TPIsAppIdAvailable(appIdData->tpsession))
+ if (TPIsAppIdAvailable(session->tpsession))
appHA->flags |= APPID_HA_FLAGS_TP_DONE;
- if (getAppIdFlag(appIdData, APPID_SESSION_SERVICE_DETECTED))
+ if (session->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
appHA->flags |= APPID_HA_FLAGS_SVC_DONE;
- if (getAppIdFlag(appIdData, APPID_SESSION_HTTP_SESSION))
+ if (session->getAppIdFlag(APPID_SESSION_HTTP_SESSION))
appHA->flags |= APPID_HA_FLAGS_HTTP;
- appHA->appId[0] = appIdData->tpAppId;
- appHA->appId[1] = appIdData->serviceAppId;
- appHA->appId[2] = appIdData->ClientServiceAppId;
- appHA->appId[3] = appIdData->portServiceAppId;
- appHA->appId[4] = appIdData->payloadAppId;
- appHA->appId[5] = appIdData->tpPayloadAppId;
- appHA->appId[6] = appIdData->ClientAppId;
- appHA->appId[7] = appIdData->miscAppId;
+ appHA->appId[0] = session->tp_app_id;
+ appHA->appId[1] = session->serviceAppId;
+ appHA->appId[2] = session->client_service_app_id;
+ appHA->appId[3] = session->portServiceAppId;
+ appHA->appId[4] = session->payload_app_id;
+ appHA->appId[5] = session->tp_payload_app_id;
+ appHA->appId[6] = session->client_app_id;
+ appHA->appId[7] = session->misc_app_id;
}
else
{
}
// FIXIT last arg used to be sfaddr_t
-uint32_t consumeHAState(void* lwssn, const uint8_t* buf, uint8_t, IpProtocol proto,
+uint32_t AppIdApi::consume_ha_state(void* lwssn, const uint8_t* buf, uint8_t, IpProtocol proto,
sfip_t* ip)
{
AppIdSessionHA* appHA = (AppIdSessionHA*)buf;
if (appHA->flags & APPID_HA_FLAGS_APP)
{
- AppIdData* appIdData = (AppIdData*)(((Flow*)lwssn)->get_application_data(
- AppIdData::flow_id));
+ AppIdSession* session = (AppIdSession*)(((Flow*)lwssn)->get_application_data(
+ AppIdSession::flow_id));
- if (!appIdData)
+ if (!session)
{
- appIdData = appSharedDataAlloc(proto, ip);
- ((Flow*)lwssn)->set_application_data(appIdData);
- if (appIdData->serviceAppId == APP_ID_FTP_CONTROL)
+ session = new AppIdSession(proto, ip);
+ ((Flow*)lwssn)->set_application_data(session);
+ if (session->serviceAppId == APP_ID_FTP_CONTROL)
{
- setAppIdFlag(appIdData, APPID_SESSION_CLIENT_DETECTED |
+ session->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED |
APPID_SESSION_NOT_A_SERVICE | APPID_SESSION_SERVICE_DETECTED);
- if (!AddFTPServiceState(appIdData))
+ if (!AddFTPServiceState(session))
{
- setAppIdFlag(appIdData, APPID_SESSION_CONTINUE);
+ session->setAppIdFlag(APPID_SESSION_CONTINUE);
}
- appIdData->rnaServiceState = RNA_STATE_STATEFUL;
+ session->rnaServiceState = RNA_STATE_STATEFUL;
}
else
- appIdData->rnaServiceState = RNA_STATE_FINISHED;
- appIdData->rnaClientState = RNA_STATE_FINISHED;
+ session->rnaServiceState = RNA_STATE_FINISHED;
+ session->rna_client_state = RNA_STATE_FINISHED;
if (thirdparty_appid_module)
- thirdparty_appid_module->session_state_set(appIdData->tpsession, TP_STATE_HA);
+ thirdparty_appid_module->session_state_set(session->tpsession, TP_STATE_HA);
}
- if (appHA->flags & APPID_HA_FLAGS_TP_DONE && thirdparty_appid_module)
+ if ( ( appHA->flags & APPID_HA_FLAGS_TP_DONE ) && thirdparty_appid_module )
{
- thirdparty_appid_module->session_state_set(appIdData->tpsession, TP_STATE_TERMINATED);
- setAppIdFlag(appIdData, APPID_SESSION_NO_TPI);
+ thirdparty_appid_module->session_state_set(session->tpsession, TP_STATE_TERMINATED);
+ session->setAppIdFlag(APPID_SESSION_NO_TPI);
}
if (appHA->flags & APPID_HA_FLAGS_SVC_DONE)
- setAppIdFlag(appIdData, APPID_SESSION_SERVICE_DETECTED);
+ session->setAppIdFlag(APPID_SESSION_SERVICE_DETECTED);
if (appHA->flags & APPID_HA_FLAGS_HTTP)
- setAppIdFlag(appIdData, APPID_SESSION_HTTP_SESSION);
-
- appIdData->tpAppId = appHA->appId[0];
- appIdData->serviceAppId = appHA->appId[1];
- appIdData->ClientServiceAppId = appHA->appId[2];
- appIdData->portServiceAppId = appHA->appId[3];
- appIdData->payloadAppId = appHA->appId[4];
- appIdData->tpPayloadAppId = appHA->appId[5];
- appIdData->ClientAppId = appHA->appId[6];
- appIdData->miscAppId = appHA->appId[7];
+ session->setAppIdFlag(APPID_SESSION_HTTP_SESSION);
+
+ session->tp_app_id = appHA->appId[0];
+ session->serviceAppId = appHA->appId[1];
+ session->client_service_app_id = appHA->appId[2];
+ session->portServiceAppId = appHA->appId[3];
+ session->payload_app_id = appHA->appId[4];
+ session->tp_payload_app_id = appHA->appId[5];
+ session->client_app_id = appHA->appId[6];
+ session->misc_app_id = appHA->appId[7];
}
return sizeof(*appHA);
}
-char* getDNSQuery(AppIdData* appIdData, uint8_t* query_len)
+char* AppIdApi::get_dns_query(AppIdSession* session, uint8_t* query_len)
{
- if (appIdData && appIdData->dsession)
+ if (session && session->dsession)
{
if (query_len)
{
- if (appIdData->dsession->host)
- *query_len = appIdData->dsession->host_len;
+ if (session->dsession->host)
+ *query_len = session->dsession->host_len;
else
*query_len = 0;
}
- return appIdData->dsession->host;
+ return session->dsession->host;
}
if (query_len)
*query_len = 0;
return nullptr;
}
-uint16_t getDNSQueryoffset(AppIdData* appIdData)
+uint16_t AppIdApi::get_dns_query_offset(AppIdSession* session)
{
- if (appIdData && appIdData->dsession)
- return appIdData->dsession->host_offset;
+ if (session && session->dsession)
+ return session->dsession->host_offset;
return 0;
}
-uint16_t getDNSRecordType(AppIdData* appIdData)
+uint16_t AppIdApi::get_dns_record_type(AppIdSession* session)
{
- if (appIdData && appIdData->dsession)
- return appIdData->dsession->record_type;
+ if (session && session->dsession)
+ return session->dsession->record_type;
return 0;
}
-uint8_t getDNSResponseType(AppIdData* appIdData)
+uint8_t AppIdApi::get_dns_response_type(AppIdSession* session)
{
- if (appIdData && appIdData->dsession)
- return appIdData->dsession->response_type;
+ if (session && session->dsession)
+ return session->dsession->response_type;
return 0;
}
-uint32_t getDNSTTL(AppIdData* appIdData)
+uint32_t AppIdApi::get_dns_ttl(AppIdSession* session)
{
- if (appIdData && appIdData->dsession)
- return appIdData->dsession->ttl;
+ if (session && session->dsession)
+ return session->dsession->ttl;
return 0;
}
enum class IpProtocol : uint8_t;
+#define APP_MAPPING_FILE "appMapping.data"
+#define APP_CONFIG_FILE "appid.conf"
+#define USR_CONFIG_FILE "userappid.conf"
+
#define APPID_SESSION_RESPONDER_MONITORED (1ULL << 0)
#define APPID_SESSION_INITIATOR_MONITORED (1ULL << 1)
#define APPID_SESSION_SPECIAL_MONITORED (1ULL << 2)
APPID_SESSION_NO_TPI | \
APPID_SESSION_SERVICE_DETECTED | \
APPID_SESSION_PORT_SERVICE_DONE)
-
-class AppIdData;
+class AppIdSession;
enum APPID_FLOW_TYPE
{
struct sfip_t;
-class AppIdApi
+class SO_PUBLIC AppIdApi
{
- const char* getApplicationName(int32_t appId);
- AppId getApplicationId(const char* appName);
- AppId getServiceAppId(AppIdData*);
- AppId getPorServiceAppId(AppIdData*);
- AppId getOnlyServiceAppId(AppIdData*);
- AppId getMiscAppId(AppIdData*);
- AppId getClientAppId(AppIdData*);
- AppId getPayloadAppId(AppIdData*);
- AppId getReferredAppId(AppIdData*);
- AppId getFwServiceAppId(AppIdData*);
- AppId getFwMiscAppId(AppIdData*);
- AppId getFwClientAppId(AppIdData*);
- AppId getFwPayloadAppId(AppIdData*);
- AppId getFwReferredAppId(AppIdData*);
- bool isSessionSslDecrypted(AppIdData*);
- bool isAppIdInspectingSession(AppIdData*);
- bool isAppIdAvailable(AppIdData*);
- char* getUserName(AppIdData*, AppId* service, bool* isLoginSuccessful);
- char* getClientVersion(AppIdData*);
- uint64_t getAppIdSessionAttribute(AppIdData*, uint64_t flag);
- APPID_FLOW_TYPE getFlowType(AppIdData*);
- void getServiceInfo(AppIdData*, char **serviceVendor, char** serviceVersion, RNAServiceSubtype** subtype);
- short getServicePort(AppIdData*);
- sfip_t* getServiceIp(AppIdData*);
- sfip_t* getInitiatorIp(AppIdData*);
- char* getHttpUserAgent(AppIdData*);
- char* getHttpHost(AppIdData*);
- char* getHttpUrl(AppIdData*);
- char* getHttpReferer(AppIdData*);
- char* getHttpNewUrl(AppIdData*);
- char* getHttpUri(AppIdData*);
- char* getHttpResponseCode(AppIdData*);
- char* getHttpCookie(AppIdData*);
- char* getHttpNewCookie(AppIdData*);
- char* getHttpContentType(AppIdData*);
- char* getHttpLocation(AppIdData*);
- char* getHttpBody(AppIdData*);
- char* getHttpReqBody(AppIdData*);
- uint16_t getHttpUriOffset(AppIdData*);
- uint16_t getHttpUriEndOffset(AppIdData*);
- uint16_t getHttpCookieOffset(AppIdData*);
- uint16_t getHttpCookieEndOffset(AppIdData*);
- SEARCH_SUPPORT_TYPE getHttpSearch(AppIdData*);
- sfip_t* getHttpXffAddr(AppIdData*);
- char* getTlsHost(AppIdData*);
- DhcpFPData* getDhcpFpData(AppIdData*);
- void freeDhcpFpData(AppIdData*, DhcpFPData*);
- DHCPInfo* getDhcpInfo(AppIdData*);
- void freeDhcpInfo(AppIdData*, DHCPInfo*);
- FpSMBData* getSmbFpData(AppIdData*);
- void freeSmbFpData(AppIdData*, FpSMBData*);
- char* getNetbiosName(AppIdData*);
- uint32_t produceHAState(void* lwssn, uint8_t* buf);
- uint32_t consumeHAState(void* lwssn, const uint8_t* buf, uint8_t length, IpProtocol proto, sfip_t* ip);
- AppIdData* getAppIdData(void* lwssn);
- char* getDNSQuery(AppIdData*, uint8_t* query_len);
- uint16_t getDNSQueryoffset(AppIdData*);
- uint16_t getDNSRecordType(AppIdData*);
- uint8_t getDNSResponseType(AppIdData*);
- uint32_t getDNSTTL(AppIdData*);
- char* getHttpNewField(AppIdData*, HTTP_FIELD_ID);
- void freeHttpNewField(AppIdData*, HTTP_FIELD_ID);
+public:
+ SO_PRIVATE AppIdApi() {}
+ SO_PRIVATE ~AppIdApi() {}
+
+ const char* get_application_name(int32_t app_id);
+ AppId get_application_id(const char* appName);
+ AppId get_service_app_id(AppIdSession*);
+ AppId get_port_service_app_id(AppIdSession*);
+ AppId get_only_service_app_id(AppIdSession*);
+ AppId get_misc_app_id(AppIdSession*);
+ AppId get_client_app_id(AppIdSession*);
+ AppId get_payload_app_id(AppIdSession*);
+ AppId get_referred_app_id(AppIdSession*);
+ AppId get_fw_service_app_id(AppIdSession*);
+ AppId get_fw_misc_app_id(AppIdSession*);
+ AppId get_fw_client_app_id(AppIdSession*);
+ AppId get_fw_payload_app_id(AppIdSession*);
+ AppId get_fw_referred_app_id(AppIdSession*);
+ bool is_ssl_session_decrypted(AppIdSession*);
+ bool is_appid_inspecting_session(AppIdSession*);
+ bool is_appid_available(AppIdSession*);
+ char* get_user_name(AppIdSession*, AppId* service, bool* isLoginSuccessful);
+ char* get_client_version(AppIdSession*);
+ uint64_t get_appid_session_attribute(AppIdSession*, uint64_t flag);
+ APPID_FLOW_TYPE get_flow_type(AppIdSession*);
+ void get_service_info(AppIdSession*, char **serviceVendor, char** serviceVersion, RNAServiceSubtype** subtype);
+ short get_service_port(AppIdSession*);
+ sfip_t* get_service_ip(AppIdSession*);
+ sfip_t* get_initiator_ip(AppIdSession*);
+ char* get_http_user_agent(AppIdSession*);
+ char* get_http_host(AppIdSession*);
+ char* get_http_url(AppIdSession*);
+ char* get_http_referer(AppIdSession*);
+ char* get_http_new_url(AppIdSession*);
+ char* get_http_uri(AppIdSession*);
+ char* get_http_response_code(AppIdSession*);
+ char* get_http_cookie(AppIdSession*);
+ char* get_http_new_cookie(AppIdSession*);
+ char* get_http_content_type(AppIdSession*);
+ char* get_http_location(AppIdSession*);
+ char* get_http_body(AppIdSession*);
+ char* get_http_request_body(AppIdSession*);
+ uint16_t get_http_uri_offset(AppIdSession*);
+ uint16_t get_http_uri_end_offset(AppIdSession*);
+ uint16_t get_http_cookie_offset(AppIdSession*);
+ uint16_t get_http_cookie_end_offset(AppIdSession*);
+ SEARCH_SUPPORT_TYPE get_http_search(AppIdSession*);
+ sfip_t* get_http_xff_addr(AppIdSession*);
+ char* get_tls_host(AppIdSession*);
+ DhcpFPData* get_dhcp_fp_data(AppIdSession*);
+ void free_dhcp_fp_data(AppIdSession*, DhcpFPData*);
+ DHCPInfo* get_dhcp_info(AppIdSession*);
+ void free_dhcp_info(AppIdSession*, DHCPInfo*);
+ FpSMBData* get_smb_fp_data(AppIdSession*);
+ void free_smb_fp_data(AppIdSession*, FpSMBData*);
+ char* get_netbios_name(AppIdSession*);
+ uint32_t produce_ha_state(void* lwssn, uint8_t* buf);
+ uint32_t consume_ha_state(void* lwssn, const uint8_t* buf, uint8_t length, IpProtocol proto, sfip_t* ip);
+ AppIdSession* get_appid_data(Flow* flow);
+ char* get_dns_query(AppIdSession*, uint8_t* query_len);
+ uint16_t get_dns_query_offset(AppIdSession*);
+ uint16_t get_dns_record_type(AppIdSession*);
+ uint8_t get_dns_response_type(AppIdSession*);
+ uint32_t get_dns_ttl(AppIdSession*);
+ char* get_http_new_field(AppIdSession*, HTTP_FIELD_ID);
+ void free_http_new_field(AppIdSession*, HTTP_FIELD_ID);
};
+SO_PUBLIC extern AppIdApi appid_api;
+
#endif
#include "detector_plugins/detector_http.h"
#include "detector_plugins/detector_dns.h"
-#include "util/network_set.h"
-#include "util/ip_funcs.h"
-#include "util/common_util.h"
-#include "util/sfutil.h"
+#include "appid_utils/network_set.h"
+#include "appid_utils/ip_funcs.h"
+#include "appid_utils/common_util.h"
+#include "appid_utils/sfutil.h"
#include "lua_detector_api.h"
#include "lua_detector_module.h"
bool AppIdConfig::init_appid( )
{
- fwAppIdInit();
+ map_app_names_to_snort_ids();
if (config_state == RNA_FW_CONFIG_STATE_UNINIT)
{
{
if ( pConfig->tcp_port_exclusions_src[i] != nullptr )
{
- sflist_free_all(pConfig->tcp_port_exclusions_src[i], &free);
+ sflist_free_all(pConfig->tcp_port_exclusions_src[i], &snort_free);
pConfig->tcp_port_exclusions_src[i] = nullptr;
}
if ( pConfig->tcp_port_exclusions_dst[i] != nullptr )
{
- sflist_free_all(pConfig->tcp_port_exclusions_dst[i], &free);
+ sflist_free_all(pConfig->tcp_port_exclusions_dst[i], &snort_free);
pConfig->tcp_port_exclusions_dst[i] = nullptr;
}
if ( pConfig->udp_port_exclusions_src[i] != nullptr )
{
- sflist_free_all(pConfig->udp_port_exclusions_src[i], &free);
+ sflist_free_all(pConfig->udp_port_exclusions_src[i], &snort_free);
pConfig->udp_port_exclusions_src[i] = nullptr;
}
if ( pConfig->udp_port_exclusions_dst[i] != nullptr )
{
- sflist_free_all(pConfig->udp_port_exclusions_dst[i], &free);
+ sflist_free_all(pConfig->udp_port_exclusions_dst[i], &snort_free);
pConfig->udp_port_exclusions_dst[i] = nullptr;
}
}
+++ /dev/null
-//--------------------------------------------------------------------------
-// Copyright (C) 2014-2016 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_flow_data.cc author Sourcefire Inc.
-
-#include "appid_flow_data.h"
-#include "fw_appid.h"
-#include "appid_stats.h"
-#include "service_plugins/service_base.h"
-
-#include "log/messages.h"
-#include "stream/stream_api.h"
-#include "sfip/sf_ip.h"
-#include "utils/util.h"
-
-unsigned AppIdData::flow_id = 0;
-
-static AppIdFlowData* fd_free_list;
-
-AppIdData::~AppIdData()
-{
- appSharedDataDelete();
-}
-
-void AppIdData::appHttpFieldClear()
-{
- if (hsession == nullptr)
- return;
-
- if (hsession->referer)
- {
- snort_free(hsession->referer);
- hsession->referer = nullptr;
- }
- if (hsession->cookie)
- {
- snort_free(hsession->cookie);
- hsession->cookie = nullptr;
- }
- if (hsession->url)
- {
- snort_free(hsession->url);
- hsession->url = nullptr;
- }
- if (hsession->useragent)
- {
- snort_free(hsession->useragent);
- hsession->useragent = nullptr;
- }
- if (hsession->host)
- {
- snort_free(hsession->host);
- hsession->host = nullptr;
- }
- if (hsession->uri)
- {
- snort_free(hsession->uri);
- hsession->uri = nullptr;
- }
- if (hsession->content_type)
- {
- snort_free(hsession->content_type);
- hsession->content_type = nullptr;
- }
- if (hsession->location)
- {
- snort_free(hsession->location);
- hsession->location = nullptr;
- }
- if (hsession->body)
- {
- snort_free(hsession->body);
- hsession->body = nullptr;
- }
- if (hsession->req_body)
- {
- snort_free(hsession->req_body);
- hsession->req_body = nullptr;
- }
- if (hsession->xffAddr)
- {
- sfip_free(hsession->xffAddr);
- hsession->xffAddr = nullptr;
- }
-}
-
-void AppIdData::appHttpSessionDataFree()
-{
- int i;
-
- if (hsession == nullptr)
- return;
-
- appHttpFieldClear();
-
- for (i = 0; i < NUMBER_OF_PTYPES; i++)
- {
- if (nullptr != hsession->new_field[i])
- {
- snort_free(hsession->new_field[i]);
- hsession->new_field[i] = nullptr;
- }
- }
- if (hsession->fflow)
- {
- snort_free(hsession->fflow);
- hsession->fflow = nullptr;
- }
- if (hsession->via)
- {
- snort_free(hsession->via);
- hsession->via = nullptr;
- }
- if (hsession->content_type)
- {
- snort_free(hsession->content_type);
- hsession->content_type = nullptr;
- }
- if (hsession->response_code)
- {
- snort_free(hsession->response_code);
- hsession->response_code = nullptr;
- }
-
- snort_free(hsession);
- hsession = nullptr;
-}
-
-void AppIdData::appDNSSessionDataFree()
-{
- if (dsession )
- {
- if (dsession->host)
- {
- snort_free(dsession->host);
- dsession->host = nullptr;
- }
- snort_free(dsession);
- dsession = nullptr;
- }
-}
-
-void AppIdData::appTlsSessionDataFree()
-{
- if (tsession )
- {
- if (tsession->tls_host)
- snort_free(tsession->tls_host);
- if (tsession->tls_cname)
- snort_free(tsession->tls_cname);
- if (tsession->tls_orgUnit)
- snort_free(tsession->tls_orgUnit);
- snort_free(tsession);
- tsession = nullptr;
- }
-}
-
-void AppIdData::AppIdFlowdataFree()
-{
- AppIdFlowData* tmp_fd;
-
- while ((tmp_fd = flowData))
- {
- flowData = tmp_fd->next;
- if (tmp_fd->fd_data && tmp_fd->fd_free)
- tmp_fd->fd_free(tmp_fd->fd_data);
- tmp_fd->next = fd_free_list;
- fd_free_list = tmp_fd;
- }
-}
-
-void AppIdData::appSharedDataDelete()
-{
- RNAServiceSubtype* rna_service_subtype;
-
- /*check daq flag */
- appIdStatsUpdate(this);
-
- if (ssn)
- FailInProcessService(this, pAppidActiveConfig);
- AppIdFlowdataFree();
-
- if (thirdparty_appid_module)
- {
- thirdparty_appid_module->session_delete(tpsession, 0);
- tpsession = nullptr;
- }
-
- snort_free(clientVersion);
- snort_free(serviceVendor);
- snort_free(serviceVersion);
- snort_free(netbios_name);
- while ((rna_service_subtype = subtype))
- {
- subtype = rna_service_subtype->next;
- snort_free(*(void**)&rna_service_subtype->service);
- snort_free(*(void**)&rna_service_subtype->vendor);
- snort_free(*(void**)&rna_service_subtype->version);
- snort_free(rna_service_subtype);
- }
- if (candidate_service_list)
- {
- sflist_free(candidate_service_list);
- candidate_service_list = nullptr;
- }
-
- if (candidate_client_list)
- {
- sflist_free(candidate_client_list);
- candidate_client_list = nullptr;
- }
- snort_free(username);
- snort_free(netbiosDomain);
- snort_free(payloadVersion);
- appHttpSessionDataFree();
- appTlsSessionDataFree();
- appDNSSessionDataFree();
- tsession = nullptr;
-
- snort_free(firewallEarlyData);
- firewallEarlyData = nullptr;
-
- // should be freed by flow
- // appSharedDataFree(sharedData);
-}
-
-void AppIdFlowdataFini()
-{
- AppIdFlowData* tmp_fd;
-
- while ((tmp_fd = fd_free_list))
- {
- fd_free_list = fd_free_list->next;
- snort_free(tmp_fd);
- }
-}
-
-void* AppIdFlowdataGet(AppIdData* flowp, unsigned id)
-{
- AppIdFlowData* tmp_fd;
-
- for (tmp_fd = flowp->flowData; tmp_fd && tmp_fd->fd_id != id; tmp_fd = tmp_fd->next)
- ;
- return tmp_fd ? tmp_fd->fd_data : nullptr;
-}
-
-void* AppIdFlowdataRemove(AppIdData* flowp, unsigned id)
-{
- AppIdFlowData** pfd;
- AppIdFlowData* fd;
-
- for (pfd = &flowp->flowData; *pfd && (*pfd)->fd_id != id; pfd = &(*pfd)->next)
- ;
- if ((fd = *pfd))
- {
- *pfd = fd->next;
- fd->next = fd_free_list;
- fd_free_list = fd;
- return fd->fd_data;
- }
- return nullptr;
-}
-
-void AppIdFlowdataDelete(AppIdData* flowp, unsigned id)
-{
- AppIdFlowData** pfd;
- AppIdFlowData* fd;
-
- for (pfd = &flowp->flowData; *pfd && (*pfd)->fd_id != id; pfd = &(*pfd)->next)
- ;
- if ((fd = *pfd))
- {
- *pfd = fd->next;
- if (fd->fd_data && fd->fd_free)
- fd->fd_free(fd->fd_data);
- fd->next = fd_free_list;
- fd_free_list = fd;
- }
-}
-
-void AppIdFlowdataDeleteAllByMask(AppIdData* flowp, unsigned mask)
-{
- AppIdFlowData** pfd;
- AppIdFlowData* fd;
-
- pfd = &flowp->flowData;
- while (*pfd)
- {
- if ((*pfd)->fd_id & mask)
- {
- fd = *pfd;
- *pfd = fd->next;
- if (fd->fd_data && fd->fd_free)
- fd->fd_free(fd->fd_data);
- fd->next = fd_free_list;
- fd_free_list = fd;
- }
- else
- {
- pfd = &(*pfd)->next;
- }
- }
-}
-
-int AppIdFlowdataAdd(AppIdData* flowp, void* data, unsigned id, AppIdFreeFCN fcn)
-{
- AppIdFlowData* tmp_fd;
-
- if (fd_free_list)
- {
- tmp_fd = fd_free_list;
- fd_free_list = tmp_fd->next;
- }
- else
- tmp_fd = (AppIdFlowData*)snort_alloc(sizeof(AppIdFlowData));
-
- tmp_fd->fd_id = id;
- tmp_fd->fd_data = data;
- tmp_fd->fd_free = fcn;
- tmp_fd->next = flowp->flowData;
- flowp->flowData = tmp_fd;
- return 0;
-}
-
-int AppIdFlowdataAddId(AppIdData* flowp, uint16_t port, const RNAServiceElement* svc_element)
-{
- if (flowp->serviceData)
- return -1;
- flowp->serviceData = svc_element;
- flowp->service_port = port;
- return 0;
-}
-
-#ifdef RNA_DEBUG_EXPECTED_FLOWS
-static void flowAppSharedDataDelete(AppIdData* sharedData)
-{
- _dpd.errMsg("Deleting %p\n",sharedData);
- appSharedDataDelete(sharedData);
-}
-
-#endif
-
-AppIdData* AppIdEarlySessionCreate(
- AppIdData*, const Packet* /*ctrlPkt*/, const sfip_t* cliIp, uint16_t cliPort,
- const sfip_t* srvIp, uint16_t srvPort, IpProtocol proto, int16_t app_id, int /*flags*/)
-{
- char src_ip[INET6_ADDRSTRLEN];
- char dst_ip[INET6_ADDRSTRLEN];
- // FIXIT - not needed until crtlPkt expectedSession is supported
- //struct _ExpectNode** node;
- enum PktType protocol = ( enum PktType )proto;
-
- if (app_id_debug_session_flag)
- {
- sfip_ntop(cliIp, src_ip, sizeof(src_ip));
- sfip_ntop(srvIp, dst_ip, sizeof(dst_ip));
- }
-
- AppIdData* data = appSharedDataAlloc(proto, cliIp);
- data->common.policyId = appIdPolicyId;
-
- // FIXIT - expect session control packet support not ported to snort3 yet
- //node = (flags & APPID_EARLY_SESSION_FLAG_FW_RULE) ? &ctrlPkt->expectedSession : nullptr;
-
- // FIXIT - 2.9.x set_application_protocol_id_expected has several new parameters, need to look
- // into what is required to support those here.
- if (stream.set_application_protocol_id_expected(/*crtlPkt,*/ cliIp, cliPort, srvIp, srvPort,
- protocol, app_id, data) )
- {
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s failed to create a related flow for %s-%u -> %s-%u %u\n",
- app_id_debug_session,
- src_ip, (unsigned)cliPort, dst_ip, (unsigned)srvPort, (unsigned)proto);
- data->appSharedDataDelete();
- return nullptr;
- }
- else if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s created a related flow for %s-%u -> %s-%u %u\n",
- app_id_debug_session,
- src_ip, (unsigned)cliPort, dst_ip, (unsigned)srvPort, (unsigned)proto);
-
- return data;
-}
-
#endif
#include "profiler/profiler.h"
+#include "appid_session.h"
#include "fw_appid.h"
//-------------------------------------------------------------------------
bool AppIdInspector::configure(SnortConfig*)
{
active_config = new AppIdConfig( ( AppIdModuleConfig* )config);
+ if(config->debug)
+ show(nullptr);
return active_config->init_appid();
// FIXIT some of this stuff may be needed in some fashion...
Profile profile(appidPerfStats);
appid_stats.packets++;
- fwAppIdSearch(pkt);
+ AppIdSession::do_application_discovery(pkt);
}
//-------------------------------------------------------------------------
static void appid_inspector_init()
{
- AppIdData::init();
+ AppIdSession::init();
}
static Inspector* appid_inspector_ctor(Module* m)
const BaseApi* nin_appid = &appid_inspector_api.base;
#endif
+#ifdef REMOVED_WHILE_NOT_IN_USE
+// FIXIT-M: This is to be replace with snort3 inspection events
+void httpHeaderCallback(Packet* p, HttpParsedHeaders* const headers)
+{
+ AppIdSession* session;
+ int direction;
+ AppIdConfig* pConfig = pAppidActiveConfig;
+
+ if (thirdparty_appid_module)
+ return;
+ if (!p || !(session = appid_api.get_appid_data(p->flow)))
+ return;
+
+ direction = p->is_from_client() ? APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
+
+ if (!session->hsession)
+ session->hsession = (decltype(session->hsession))snort_calloc(sizeof(httpSession));
+
+ if (direction == APP_ID_FROM_INITIATOR)
+ {
+ if (headers->host.start)
+ {
+ snort_free(session->hsession->host);
+ session->hsession->host = snort_strndup((char*)headers->host.start, headers->host.len);
+ session->scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
+
+ if (headers->url.start)
+ {
+ snort_free(session->hsession->url);
+ session->hsession->url = (char*)snort_calloc(sizeof(HTTP_PREFIX) +
+ headers->host.len + headers->url.len);
+ strcpy(session->hsession->url, HTTP_PREFIX);
+ strncat(session->hsession->url, (char*)headers->host.start, headers->host.len);
+ strncat(session->hsession->url, (char*)headers->url.start, headers->url.len);
+ session->scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
+ }
+ }
+ if (headers->userAgent.start)
+ {
+ snort_free(session->hsession->useragent);
+ session->hsession->useragent = snort_strndup((char*)headers->userAgent.start,
+ headers->userAgent.len);
+ session->scan_flags |= SCAN_HTTP_USER_AGENT_FLAG;
+ }
+ if (headers->referer.start)
+ {
+ snort_free(session->hsession->referer);
+ session->hsession->referer = snort_strndup((char*)headers->referer.start,
+ headers->referer.len);
+ }
+ if (headers->via.start)
+ {
+ snort_free(session->hsession->via);
+ session->hsession->via = snort_strndup((char*)headers->via.start, headers->via.len);
+ session->scan_flags |= SCAN_HTTP_VIA_FLAG;
+ }
+ }
+ else
+ {
+ if (headers->via.start)
+ {
+ snort_free(session->hsession->via);
+ session->hsession->via = snort_strndup((char*)headers->via.start, headers->via.len);
+ session->scan_flags |= SCAN_HTTP_VIA_FLAG;
+ }
+ if (headers->contentType.start)
+ {
+ snort_free(session->hsession->content_type);
+ session->hsession->content_type = snort_strndup((char*)headers->contentType.start,
+ headers->contentType.len);
+ }
+ if (headers->responseCode.start)
+ {
+ long responseCodeNum;
+ responseCodeNum = strtoul((char*)headers->responseCode.start, nullptr, 10);
+ if (responseCodeNum > 0 && responseCodeNum < 700)
+ {
+ snort_free(session->hsession->response_code);
+ session->hsession->response_code = snort_strndup((char*)headers->responseCode.start,
+ headers->responseCode.len);
+ }
+ }
+ }
+
+ session->processHTTPPacket(p, direction, headers, pConfig);
+ session->setAppIdFlag(APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_HTTP_SESSION);
+ p->flow->set_application_ids(session->pick_service_app_id(), session->pick_client_app_id(),
+ session->pick_payload_app_id(), session->pick_misc_app_id());
+}
+#endif
+
+/**
+ * @returns 1 if some appid is found, 0 otherwise.
+ */
+//int sslAppGroupIdLookup(void* ssnptr, const char* serverName, const char* commonName,
+// AppId* serviceAppId, AppId* ClientAppId, AppId* payloadAppId)
+int sslAppGroupIdLookup(void*, const char*, const char*, AppId*, AppId*, AppId*)
+{
+ // FIXIT-M: detemine need and proper location for this code when support for ssl is implemented
+#ifdef REMOVED_WHILE_NOT_IN_USE
+ AppIdSession* session;
+ *serviceAppId = *ClientAppId = *payload_app_id = APP_ID_NONE;
+
+ if (commonName)
+ {
+ ssl_scan_cname((const uint8_t*)commonName, strlen(commonName), ClientAppId, payload_app_id,
+ &pAppidActiveConfig->serviceSslConfig);
+ }
+ if (serverName)
+ {
+ ssl_scan_hostname((const uint8_t*)serverName, strlen(serverName), ClientAppId,
+ payload_app_id, &pAppidActiveConfig->serviceSslConfig);
+ }
+
+ if (ssnptr && (session = appid_api.get_appid_data(ssnptr)))
+ {
+ *serviceAppId = pick_service_app_id(session);
+ if (*ClientAppId == APP_ID_NONE)
+ {
+ *ClientAppId = pick_client_app_id(session);
+ }
+ if (*payload_app_id == APP_ID_NONE)
+ {
+ *payload_app_id = pick_payload_app_id(session);
+ }
+ }
+ if (*serviceAppId != APP_ID_NONE ||
+ *ClientAppId != APP_ID_NONE ||
+ *payload_app_id != APP_ID_NONE)
+ {
+ return 1;
+ }
+#endif
+
+ return 0;
+}
+
+AppId getOpenAppId(Flow* flow)
+{
+ assert(flow);
+ AppIdSession* session = appid_api.get_appid_data(flow);
+ return session->payload_app_id;
+}
+
AppIdConfig* active_config = nullptr;
};
+void httpHeaderCallback(Packet*, HttpParsedHeaders* const);
+int sslAppGroupIdLookup(void*, const char*, const char*, AppId*, AppId*, AppId*);
+AppId getOpenAppId(Flow*);
+
#endif
// appid module
//-------------------------------------------------------------------------
+unsigned long app_id_ignored_packet_count = 0;
+
THREAD_LOCAL ProfileStats appidPerfStats;
// FIXIT-M: define and implement a flexible solution for maintaining protocol specific stats
const PegInfo appid_pegs[] =
{
- { "packets", "count of packets processed by appid" },
+ { "packets", "count of packets received by appid inspector" },
+ { "processed packets", "count of packets processed by appid inspector" },
+ { "ignored packets", "count of packets ignored by appid inspector" },
{ "battlefield_flows", "count of battle field flows discovered by appid" },
{ "bgp_flows", "count of bgp flows discovered by appid" },
{ "bit_clients", "count of bittorrent clients discovered by appid" },
struct AppIdStats
{
PegCount packets;
+ PegCount processed_packets;
+ PegCount ignored_packets;
PegCount battlefield_flows;
PegCount bgp_flows;
PegCount bit_clients;
--- /dev/null
+//--------------------------------------------------------------------------
+// Copyright (C) 2014-2016 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_flow_data.cc author Sourcefire Inc.
+
+#include "protocols/tcp.h"
+#include "profiler/profiler.h"
+#include "target_based/snort_protocols.h"
+
+#include "appid_session.h"
+#include "appid_module.h"
+#include "fw_appid.h"
+#include "appid_stats.h"
+#include "app_forecast.h"
+#include "host_port_app_cache.h"
+#include "lua_detector_module.h"
+#include "client_plugins/client_app_base.h"
+#include "detector_plugins/detector_http.h"
+#include "detector_plugins/detector_dns.h"
+#include "service_plugins/service_base.h"
+#include "service_plugins/service_ssl.h"
+#include "service_plugins/service_util.h"
+
+#include "log/messages.h"
+#include "stream/stream_api.h"
+#include "sfip/sf_ip.h"
+#include "utils/util.h"
+#include "appid_utils/ip_funcs.h"
+#include "time/packet_time.h"
+
+ProfileStats tpPerfStats;
+ProfileStats tpLibPerfStats;
+ProfileStats httpPerfStats;
+ProfileStats clientMatchPerfStats;
+ProfileStats serviceMatchPerfStats;
+
+unsigned AppIdSession::flow_id = 0;
+static AppIdFlowData* fd_free_list;
+
+static volatile int app_id_debug_flag;
+static FWDebugSessionConstraints app_id_debug_info;
+char app_id_debug_session[FW_DEBUG_SESSION_ID_SIZE];
+bool app_id_debug_session_flag;
+
+// FIXIT - should appid_flow_data_id be global to all threads?
+static THREAD_LOCAL uint32_t appid_flow_data_id = 0;
+
+static int16_t snortId_for_ftp;
+static int16_t snortId_for_ftp_data;
+static int16_t snortId_for_imap;
+static int16_t snortId_for_pop3;
+static int16_t snortId_for_smtp;
+static int16_t snortId_for_http2;
+
+void map_app_names_to_snort_ids()
+{
+ /* init globals for snortId compares */
+ snortId_for_ftp = FindProtocolReference("ftp");
+ snortId_for_ftp_data = FindProtocolReference("ftp-data");
+ snortId_for_imap = FindProtocolReference("imap");
+ snortId_for_pop3 = FindProtocolReference("pop3");
+ snortId_for_smtp = FindProtocolReference("smtp");
+ snortId_for_http2 = FindProtocolReference("http2");
+}
+
+static inline bool fwAppIdDebugCheck(Flow* flow, AppIdSession* session, volatile int debug_flag,
+ FWDebugSessionConstraints* info, char* debug_session, int direction)
+{
+ if (debug_flag)
+ {
+ assert(flow);
+ const FlowKey* key = flow->key;
+
+ if (((info->protocol == PktType::NONE) || info->protocol == key->pkt_type) &&
+ (((!info->sport || info->sport == key->port_l) &&
+ (!info->sip_flag || memcmp(&info->sip, key->ip_l, sizeof(info->sip)) == 0) &&
+ (!info->dport || info->dport == key->port_h) &&
+ (!info->dip_flag || memcmp(&info->dip, key->ip_h, sizeof(info->dip)) == 0)) ||
+ ((!info->sport || info->sport == key->port_h) &&
+ (!info->sip_flag || memcmp(&info->sip, key->ip_h, sizeof(info->sip)) == 0) &&
+ (!info->dport || info->dport == key->port_l) &&
+ (!info->dip_flag || memcmp(&info->dip, key->ip_l, sizeof(info->dip)) == 0))))
+ {
+ int af;
+ sfip_t sip;
+ sfip_t dip;
+ unsigned offset;
+ uint16_t sport;
+ uint16_t dport;
+ char sipstr[INET6_ADDRSTRLEN];
+ char dipstr[INET6_ADDRSTRLEN];
+
+ if (session && session->common.fsf_type.flow_type != APPID_SESSION_TYPE_IGNORE)
+ {
+ if (session->common.initiator_port)
+ {
+ if (session->common.initiator_port == key->port_l)
+ {
+ sfip_set_raw(&sip, key->ip_l, AF_INET);
+ sfip_set_raw(&dip, key->ip_l, AF_INET);
+ sport = key->port_l;
+ dport = key->port_h;
+ }
+ else
+ {
+ sfip_set_raw(&sip, key->ip_l, AF_INET);
+ sfip_set_raw(&dip, key->ip_l, AF_INET);
+ sport = key->port_h;
+ dport = key->port_l;
+ }
+ }
+ else
+ {
+ // FIXIT-L: the key_ip var was added to be able to call sfip_fast_eq6, need to
+ // verify this works... not tested as yet...
+ sfip_t key_ip;
+ memcpy(key_ip.ip32, key->ip_l, sizeof(key_ip.ip32));
+ if (sfip_fast_eq6(&session->common.initiator_ip, &key_ip) == 0)
+ {
+ sfip_set_raw(&sip, key->ip_l, AF_INET);
+ sfip_set_raw(&dip, key->ip_h, AF_INET);
+ sport = key->port_l;
+ dport = key->port_h;
+ }
+ else
+ {
+ sfip_set_raw(&sip, key->ip_l, AF_INET);
+ sfip_set_raw(&dip, key->ip_h, AF_INET);
+ sport = key->port_h;
+ dport = key->port_l;
+ }
+ }
+ }
+ else
+ {
+ sfip_set_raw(&sip, key->ip_l, AF_INET);
+ sfip_set_raw(&dip, key->ip_h, AF_INET);
+ sport = key->port_l;
+ dport = key->port_h;
+ }
+ sipstr[0] = 0;
+ if ( sip.ip32[0] || sip.ip32[1] || sip.ip16[4] ||
+ (sip.ip16[5] && sip.ip16[5] != 0xffff) )
+ {
+ af = AF_INET6;
+ offset = 0;
+ }
+ else
+ {
+ af = AF_INET;
+ offset = 12;
+ }
+
+ inet_ntop(af, &sip.ip8[offset], sipstr, sizeof(sipstr));
+ dipstr[0] = 0;
+ if ( dip.ip32[0] || dip.ip32[1] || dip.ip16[4] ||
+ (dip.ip16[5] && dip.ip16[5] != 0xFFFF) )
+ {
+ af = AF_INET6;
+ offset = 0;
+ }
+ else
+ {
+ af = AF_INET;
+ offset = 12;
+ }
+
+ inet_ntop(af, &dip.ip8[offset], dipstr, sizeof(dipstr));
+#ifdef HAVE_DAQ_ADDRESS_SPACE_ID
+ snprintf(debug_session, FW_DEBUG_SESSION_ID_SIZE, "%s-%u -> %s-%u %u%s AS %u I %u",
+ sipstr, (unsigned)sport, dipstr, (unsigned)dport, (unsigned)key->pkt_type,
+ (direction == APP_ID_FROM_INITIATOR) ? "" : " R",
+ (unsigned)key->addressSpaceId, get_instance_id());
+#else
+ snprintf(debug_session, FW_DEBUG_SESSION_ID_SIZE, "%s-%u -> %s-%u %u%s I %u",
+ sipstr, (unsigned)sport, dipstr, (unsigned)dport, (unsigned)key->pkt_type,
+ (direction == APP_ID_FROM_INITIATOR) ? "" : " R", get_instance_id());
+#endif
+ return true;
+ }
+ }
+ return false;
+}
+
+static inline void appIdDebugParse(const char* desc, const uint8_t* data, uint32_t length,
+ volatile int* debug_flag, FWDebugSessionConstraints* info)
+{
+ *debug_flag = 0;
+ memset(info, 0, sizeof(*info));
+ do
+ {
+ if (length >= sizeof(info->protocol))
+ {
+ info->protocol = static_cast<PktType>(*data);
+ length -= sizeof(info->protocol);
+ data += sizeof(info->protocol);
+ }
+ else
+ break;
+
+ if (length >= sizeof(info->sip))
+ {
+ memcpy(&info->sip, data, sizeof(info->sip));
+ if (info->sip.u6_addr32[1] || info->sip.u6_addr32[2] || info->sip.u6_addr32[3])
+ info->sip_flag = 1;
+ else if (info->sip.u6_addr32[0])
+ {
+ info->sip.u6_addr32[3] = info->sip.u6_addr32[0];
+ info->sip.u6_addr32[0] = 0;
+ info->sip.u6_addr16[5] = 0xFFFF;
+ info->sip_flag = 1;
+ }
+ length -= sizeof(info->sip);
+ data += sizeof(info->sip);
+ }
+ else
+ break;
+
+ if (length >= sizeof(info->sport))
+ {
+ memcpy(&info->sport, data, sizeof(info->sport));
+ length -= sizeof(info->sport);
+ data += sizeof(info->sport);
+ }
+ else
+ break;
+
+ if (length >= sizeof(info->dip))
+ {
+ memcpy(&info->dip, data, sizeof(info->dip));
+ if (info->dip.u6_addr32[1] || info->dip.u6_addr32[2] || info->dip.u6_addr32[3])
+ info->dip_flag = 1;
+ else if (info->dip.u6_addr32[0])
+ {
+ info->dip.u6_addr32[3] = info->dip.u6_addr32[0];
+ info->dip.u6_addr32[0] = 0;
+ info->dip.u6_addr16[5] = 0xFFFF;
+ info->dip_flag = 1;
+ }
+ length -= sizeof(info->dip);
+ data += sizeof(info->dip);
+ }
+ else
+ break;
+
+ if (length >= sizeof(info->dport))
+ memcpy(&info->dport, data, sizeof(info->dport));
+ else
+ break;
+ }
+ while (0);
+
+ if (info->protocol != PktType::NONE || info->sip_flag || info->sport || info->dip_flag ||
+ info->dport)
+ {
+ int saf;
+ int daf;
+ char sipstr[INET6_ADDRSTRLEN];
+ char dipstr[INET6_ADDRSTRLEN];
+
+ if (!info->sip.u6_addr32[0] && !info->sip.u6_addr32[0] && !info->sip.u6_addr16[4] &&
+ info->sip.u6_addr16[5] == 0xFFFF)
+ {
+ saf = AF_INET;
+ }
+ else
+ saf = AF_INET6;
+ if (!info->dip.u6_addr32[0] && !info->dip.u6_addr32[0] && !info->dip.u6_addr16[4] &&
+ info->dip.u6_addr16[5] == 0xFFFF)
+ {
+ daf = AF_INET;
+ }
+ else
+ daf = AF_INET6;
+ if (!info->sip_flag)
+ saf = daf;
+ if (!info->dip_flag)
+ daf = saf;
+ sipstr[0] = 0;
+ inet_ntop(saf, saf == AF_INET ? &info->sip.u6_addr32[3] : info->sip.u6_addr32, sipstr,
+ sizeof(sipstr));
+ dipstr[0] = 0;
+ inet_ntop(daf, daf == AF_INET ? &info->dip.u6_addr32[3] : info->dip.u6_addr32, dipstr,
+ sizeof(dipstr));
+ LogMessage("Debugging %s with %s-%u and %s-%u %u\n", desc,
+ sipstr, (unsigned)info->sport,
+ dipstr, (unsigned)info->dport,
+ (unsigned)info->protocol);
+ *debug_flag = 1;
+ }
+ else
+ LogMessage("Debugging %s disabled\n", desc);
+}
+
+int AppIdDebug(uint16_t, const uint8_t* const data, uint32_t length, void**, char*, int)
+{
+ appIdDebugParse("appId", data, length, &app_id_debug_flag, &app_id_debug_info);
+ return 0;
+}
+
+// FIXIT-M: this function does work that probably should be in http inspector, appid should leverage that if possible
+static inline void getOffsetsFromRebuilt(Packet* pkt, httpSession* hsession)
+{
+// size of "GET /\r\n\r\n"
+#define MIN_HTTP_REQ_HEADER_SIZE 9
+ const uint8_t cookieStr[] = "Cookie: ";
+ unsigned cookieStrLen = sizeof(cookieStr)-1;
+ const uint8_t crlf[] = "\r\n";
+ unsigned crlfLen = sizeof(crlf)-1;
+ const uint8_t crlfcrlf[] = "\r\n\r\n";
+ unsigned crlfcrlfLen = sizeof(crlfcrlf)-1;
+ const uint8_t* p;
+ uint8_t* headerEnd;
+ uint16_t headerSize;
+
+ if (!pkt || !pkt->data || pkt->dsize < MIN_HTTP_REQ_HEADER_SIZE)
+ return;
+
+ p = pkt->data;
+
+ if (!(headerEnd = (uint8_t*)service_strstr(p, pkt->dsize, crlfcrlf, crlfcrlfLen)))
+ return;
+
+ headerEnd += crlfcrlfLen;
+
+ headerSize = headerEnd - p;
+
+ //uri offset is the index of the first char after the first space in the data
+ if (!(p = (uint8_t*)memchr(pkt->data, ' ', headerSize)))
+ return;
+ hsession->uriOffset = ++p - pkt->data;
+ headerSize = headerEnd - p;
+
+ //uri end offset is the index of the first CRLF sequence after uri offset
+ if (!(p = (uint8_t*)service_strstr(p, headerSize, crlf, crlfLen)))
+ {
+ // clear uri offset if we can't find an end offset
+ hsession->uriOffset = 0;
+ return;
+ }
+ hsession->uriEndOffset = p - pkt->data;
+ headerSize = headerEnd - p;
+
+ //cookie offset is the index of the first char after the cookie header, "Cookie: "
+ if (!(p = (uint8_t*)service_strstr(p, headerSize, cookieStr, cookieStrLen)))
+ return;
+ hsession->cookieOffset = p + cookieStrLen - pkt->data;
+ headerSize = headerEnd - p;
+
+ //cookie end offset is the index of the first CRLF sequence after cookie offset
+ if (!(p = (uint8_t*)service_strstr(p, headerSize, crlf, crlfLen)))
+ {
+ // clear cookie offset if we can't find a cookie end offset
+ hsession->cookieOffset = 0;
+ return;
+ }
+ hsession->cookieEndOffset = p - pkt->data;
+}
+
+void AppIdSession::clear_app_id_data()
+{
+ payload_app_id = APP_ID_UNKNOWN;
+ serviceAppId = APP_ID_UNKNOWN;
+ tp_payload_app_id = APP_ID_UNKNOWN;
+ tp_app_id = APP_ID_UNKNOWN;
+ if (payload_version)
+ {
+ snort_free(payload_version);
+ payload_version = nullptr;
+ }
+ if (serviceVendor)
+ {
+ snort_free(serviceVendor);
+ serviceVendor = nullptr;
+ }
+ if (serviceVersion)
+ {
+ snort_free(serviceVersion);
+ serviceVersion = nullptr;
+ }
+
+ if (tsession)
+ free_tls_session_data();
+
+ if (hsession)
+ free_http_session_data();
+
+ if (dsession)
+ free_dns_session_data();
+
+ if (thirdparty_appid_module)
+ thirdparty_appid_module->session_delete(tpsession, 1);
+}
+
+AppIdSession* AppIdSession::allocate_session(const Packet* p, IpProtocol proto, int direction)
+{
+ const sfip_t* ip;
+
+ ip = (direction == APP_ID_FROM_INITIATOR)
+ ? p->ptrs.ip_api.get_src() : p->ptrs.ip_api.get_dst();
+ AppIdSession* data = new AppIdSession(proto, ip);
+
+ if ( ( proto == IpProtocol::TCP || proto == IpProtocol::UDP ) && ( p->ptrs.sp != p->ptrs.dp ) )
+ data->common.initiator_port =
+ (direction == APP_ID_FROM_INITIATOR) ? p->ptrs.sp : p->ptrs.dp;
+ data->flow = p->flow;
+ data->stats.firstPktsecond = p->pkth->ts.tv_sec;
+
+ p->flow->set_application_data(data);
+ return data;
+}
+
+AppIdSession::AppIdSession(IpProtocol proto, const sfip_t* ip) : FlowData(flow_id)
+{
+ service_ip.clear();
+ id = ++appid_flow_data_id;
+ common.fsf_type.flow_type = APPID_SESSION_TYPE_NORMAL;
+ protocol = proto;
+ common.initiator_ip = *ip;
+
+ if (thirdparty_appid_module)
+ if (!(tpsession = thirdparty_appid_module->session_create()))
+ ErrorMessage("Could not allocate third party session data");
+}
+
+AppIdSession::~AppIdSession()
+{
+ delete_shared_data();
+}
+
+AppIdSession* AppIdSession::create_future_session(const Packet* /*ctrlPkt*/, const sfip_t* cliIp, uint16_t cliPort,
+ const sfip_t* srvIp, uint16_t srvPort, IpProtocol proto, int16_t app_id, int /*flags*/)
+{
+ char src_ip[INET6_ADDRSTRLEN];
+ char dst_ip[INET6_ADDRSTRLEN];
+ // FIXIT - not needed until crtlPkt expectedSession is supported
+ //struct _ExpectNode** node;
+ enum PktType protocol = ( enum PktType ) proto;
+
+ if (app_id_debug_session_flag)
+ {
+ sfip_ntop(cliIp, src_ip, sizeof(src_ip));
+ sfip_ntop(srvIp, dst_ip, sizeof(dst_ip));
+ }
+
+ AppIdSession* session = new AppIdSession(proto, cliIp);
+ session->common.policyId = appIdPolicyId;
+
+ // FIXIT - expect session control packet support not ported to snort3 yet
+ //node = (flags & APPID_EARLY_SESSION_FLAG_FW_RULE) ? &ctrlPkt->expectedSession : nullptr;
+
+ // FIXIT - 2.9.x set_application_protocol_id_expected has several new parameters, need to look
+ // into what is required to support those here.
+ if (stream.set_application_protocol_id_expected(/*crtlPkt,*/ cliIp, cliPort, srvIp, srvPort,
+ protocol, app_id, session) )
+ {
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s failed to create a related flow for %s-%u -> %s-%u %u\n",
+ app_id_debug_session, src_ip, (unsigned)cliPort, dst_ip,
+ (unsigned)srvPort, (unsigned)proto);
+ // FIXIT-M: this deletes data on just allocated session, probably isn't any, should this
+ // be delete of data in parent session?
+ session->delete_shared_data();
+ delete session;
+ return nullptr;
+ }
+ else if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s created a related flow for %s-%u -> %s-%u %u\n",
+ app_id_debug_session, src_ip, (unsigned)cliPort, dst_ip,
+ (unsigned)srvPort, (unsigned)proto);
+
+ return session;
+}
+
+void AppIdSession::reinit_shared_data()
+{
+ misc_app_id = APP_ID_NONE;
+
+ //data
+ if (isSslServiceAppId(tp_app_id))
+ {
+ payload_app_id = referred_payload_app_id = tp_payload_app_id = APP_ID_NONE;
+ clearAppIdFlag(APPID_SESSION_CONTINUE);
+ if (payload_version)
+ {
+ snort_free(payload_version);
+ payload_version = nullptr;
+ }
+ if (hsession && hsession->url)
+ {
+ snort_free(hsession->url);
+ hsession->url = nullptr;
+ }
+ }
+
+ //service
+ if (!getAppIdFlag(APPID_SESSION_STICKY_SERVICE))
+ {
+ clearAppIdFlag(APPID_SESSION_STICKY_SERVICE);
+
+ tp_app_id = serviceAppId = portServiceAppId = APP_ID_NONE;
+ if (serviceVendor)
+ {
+ snort_free(serviceVendor);
+ serviceVendor = nullptr;
+ }
+ if (serviceVersion)
+ {
+ snort_free(serviceVersion);
+ serviceVersion = nullptr;
+ }
+
+ service_ip.clear();
+ service_port = 0;
+ rnaServiceState = RNA_STATE_NONE;
+ serviceData = nullptr;
+ free_flow_data_by_mask(APPID_SESSION_DATA_SERVICE_MODSTATE_BIT);
+ }
+
+ //client
+ client_app_id = client_service_app_id = APP_ID_NONE;
+ if (client_version)
+ {
+ snort_free(client_version);
+ client_version = nullptr;
+ }
+ rna_client_state = RNA_STATE_NONE;
+ free_flow_data_by_mask(APPID_SESSION_DATA_CLIENT_MODSTATE_BIT);
+
+ //3rd party cleaning
+ if (thirdparty_appid_module)
+ thirdparty_appid_module->session_delete(tpsession, 1);
+ init_tpPackets = 0;
+ resp_tpPackets = 0;
+
+ scan_flags &= ~SCAN_HTTP_HOST_URL_FLAG;
+ clearAppIdFlag(APPID_SESSION_SERVICE_DETECTED |APPID_SESSION_CLIENT_DETECTED |
+ APPID_SESSION_SSL_SESSION|APPID_SESSION_HTTP_SESSION | APPID_SESSION_APP_REINSPECT);
+}
+
+int AppIdSession::exec_client_detectors(Packet* p, int direction, AppIdConfig* pConfig)
+{
+ int ret = CLIENT_APP_INPROCESS;
+
+ if (rna_client_data != nullptr)
+ {
+ ret = rna_client_data->validate(p->data, p->dsize, direction,
+ this, p, rna_client_data->userData, pConfig);
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s %s client detector returned %d\n", app_id_debug_session,
+ rna_client_data->name ? rna_client_data->name : "UNKNOWN", ret);
+ }
+ else if ( (candidate_client_list != nullptr)
+ && (sflist_count(candidate_client_list) > 0) )
+ {
+ SF_LNODE* node;
+ RNAClientAppModule* client;
+
+ ret = CLIENT_APP_INPROCESS;
+ (void)sflist_first(candidate_client_list, &node);
+ while (node != nullptr)
+ {
+ int result;
+ SF_LNODE* node_tmp;
+
+ client = (RNAClientAppModule*)node->ndata;
+ result = client->validate(p->data, p->dsize, direction,
+ this, p, client->userData, pConfig);
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s %s client detector returned %d\n", app_id_debug_session,
+ client->name ? client->name : "UNKNOWN", result);
+
+ node_tmp = node;
+ sflist_next(&node);
+ if (result == CLIENT_APP_SUCCESS)
+ {
+ ret = CLIENT_APP_SUCCESS;
+ rna_client_data = client;
+ sflist_free(candidate_client_list);
+ candidate_client_list = nullptr;
+ break; /* done */
+ }
+ else if (result != CLIENT_APP_INPROCESS) /* fail */
+ {
+ sflist_remove_node(candidate_client_list, node_tmp);
+ }
+ }
+ }
+
+ return ret;
+}
+
+bool AppIdSession::is_packet_ignored(Packet* p)
+{
+ if(!p->flow)
+ {
+ appid_stats.ignored_packets++;
+ return true;
+ }
+ AppIdSession* session = appid_api.get_appid_data(p->flow);
+
+// FIXIT-M - Need to convert this _dpd stream api call to the correct snort++ method
+#ifdef REMOVED_WHILE_NOT_IN_USE
+ bool is_http2 = _dpd.streamAPI->is_session_http2(p->flow);
+#else
+ bool is_http2 = false;
+#endif
+ if (is_http2)
+ {
+ if (session)
+ session->is_http2 = true;
+ if ( !p->is_rebuilt() )
+ {
+ // For HTTP/2, we only want to look at the ones that are rebuilt from
+ // Stream / HTTP Inspect as HTTP/1 packets.
+ appid_stats.ignored_packets++;
+ return true;
+ }
+ }
+ else // not HTTP/2
+ {
+ if ( p->is_rebuilt() && !p->flow->is_proxied() )
+ {
+ if (session && session->hsession && session->hsession->get_offsets_from_rebuilt)
+ {
+ getOffsetsFromRebuilt(p, session->hsession);
+ if (app_id_debug_session_flag)
+ LogMessage(
+ "AppIdDbg %s offsets from rebuilt packet: uri: %u-%u cookie: %u-%u\n",
+ app_id_debug_session, session->hsession->uriOffset,
+ session->hsession->uriEndOffset, session->hsession->cookieOffset,
+ session->hsession->cookieEndOffset);
+ }
+ appid_stats.ignored_packets++;
+ return true;
+ }
+ }
+
+ return false;
+}
+#ifdef REMOVED_WHILE_NOT_IN_USE
+static int ptype_scan_counts[NUMBER_OF_PTYPES];
+
+void AppIdSession::ProcessThirdPartyResults(Packet* p, int confidence,
+ AppId* proto_list, ThirdPartyAppIDAttributeData* attribute_data)
+{
+ int size;
+ AppId serviceAppId = 0;
+ AppId client_app_id = 0;
+ AppId payload_app_id = 0;
+ AppId referred_payload_app_id = 0;
+ AppIdConfig* pConfig = pAppidActiveConfig;
+
+ if (ThirdPartyAppIDFoundProto(APP_ID_EXCHANGE, proto_list))
+ {
+ if (!payload_app_id)
+ payload_app_id = APP_ID_EXCHANGE;
+ }
+
+ if (ThirdPartyAppIDFoundProto(APP_ID_HTTP, proto_list))
+ {
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s flow is HTTP\n", app_id_debug_session);
+ setAppIdFlag(APPID_SESSION_HTTP_SESSION);
+ }
+ if (ThirdPartyAppIDFoundProto(APP_ID_SPDY, proto_list))
+ {
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s flow is SPDY\n", app_id_debug_session);
+
+ setAppIdFlag(APPID_SESSION_HTTP_SESSION | APPID_SESSION_SPDY_SESSION);
+ }
+
+ if (getAppIdFlag(APPID_SESSION_HTTP_SESSION))
+ {
+ if (!hsession)
+ {
+ hsession = (httpSession*)snort_calloc(sizeof(httpSession));
+ memset(ptype_scan_counts, 0, 7 * sizeof(ptype_scan_counts[0]));
+ }
+
+ if (getAppIdFlag(APPID_SESSION_SPDY_SESSION))
+ {
+ if (attribute_data->spdyRequesHost)
+ {
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s SPDY host is %s\n", app_id_debug_session,
+ attribute_data->spdyRequesHost);
+ if (hsession->host)
+ {
+ snort_free(hsession->host);
+ hsession->chp_finished = 0;
+ }
+ hsession->host = snort_strdup(attribute_data->spdyRequesHost);
+ scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
+ }
+ if (attribute_data->spdyRequestPath)
+ {
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s SPDY URI is %s\n", app_id_debug_session,
+ attribute_data->spdyRequestPath);
+ if (hsession->uri)
+ {
+ snort_free(hsession->uri);
+ hsession->chp_finished = 0;
+ }
+ hsession->uri = snort_strdup(attribute_data->spdyRequestPath);
+ }
+ if (attribute_data->spdyRequestScheme &&
+ attribute_data->spdyRequesHost &&
+ attribute_data->spdyRequestPath)
+ {
+ static const char httpsScheme[] = "https";
+ static const char httpScheme[] = "http";
+ const char* scheme;
+
+ if (hsession->url)
+ {
+ snort_free(hsession->url);
+ hsession->chp_finished = 0;
+ }
+ if (getAppIdFlag(APPID_SESSION_DECRYPTED)
+ && memcmp(attribute_data->spdyRequestScheme, httpScheme, sizeof(httpScheme)-
+ 1) == 0)
+ {
+ scheme = httpsScheme;
+ }
+ else
+ {
+ scheme = attribute_data->spdyRequestScheme;
+ }
+
+ size = strlen(scheme) +
+ strlen(attribute_data->spdyRequesHost) +
+ strlen(attribute_data->spdyRequestPath) +
+ sizeof("://"); // see sprintf() format
+ hsession->url = (char*)snort_calloc(size);
+ sprintf(hsession->url, "%s://%s%s",
+ scheme, attribute_data->spdyRequesHost, attribute_data->spdyRequestPath);
+ scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
+ }
+ if (attribute_data->spdyRequestScheme)
+ {
+ snort_free(attribute_data->spdyRequestScheme);
+ attribute_data->spdyRequestScheme = nullptr;
+ }
+ if (attribute_data->spdyRequesHost)
+ {
+ snort_free(attribute_data->spdyRequesHost);
+ attribute_data->spdyRequesHost = nullptr;
+ }
+ if (attribute_data->spdyRequestPath)
+ {
+ snort_free(attribute_data->spdyRequestPath);
+ attribute_data->spdyRequestPath = nullptr;
+ }
+ }
+ else
+ {
+ if (attribute_data->httpRequesHost)
+ {
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s HTTP host is %s\n", app_id_debug_session,
+ attribute_data->httpRequesHost);
+ if (hsession->host)
+ {
+ snort_free(hsession->host);
+ if (!getAppIdFlag(APPID_SESSION_APP_REINSPECT))
+ hsession->chp_finished = 0;
+ }
+ hsession->host = attribute_data->httpRequesHost;
+ attribute_data->httpRequesHost = nullptr;
+ scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
+ }
+ if (attribute_data->httpRequesUrl)
+ {
+ static const char httpScheme[] = "http://";
+
+ if (hsession->url)
+ {
+ snort_free(hsession->url);
+ if (!getAppIdFlag(APPID_SESSION_APP_REINSPECT))
+ hsession->chp_finished = 0;
+ }
+
+ //change http to https if session was decrypted.
+ if (getAppIdFlag(APPID_SESSION_DECRYPTED)
+ &&
+ memcmp(attribute_data->httpRequesUrl, httpScheme, sizeof(httpScheme)-1) == 0)
+ {
+ hsession->url = (char*)snort_calloc(strlen(attribute_data->httpRequesUrl) + 2);
+
+ if (hsession->url)
+ sprintf(hsession->url, "https://%s",
+ attribute_data->httpRequesUrl + sizeof(httpScheme)-1);
+
+ snort_free(attribute_data->httpRequesUrl);
+ attribute_data->httpRequesUrl = nullptr;
+ }
+ else
+ {
+ hsession->url = attribute_data->httpRequesUrl;
+ attribute_data->httpRequesUrl = nullptr;
+ }
+
+ scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
+ }
+ if (attribute_data->httpRequestUri)
+ {
+ if (hsession->uri)
+ {
+ snort_free(hsession->uri);
+ if (!getAppIdFlag(APPID_SESSION_APP_REINSPECT))
+ hsession->chp_finished = 0;
+ }
+ hsession->uri = attribute_data->httpRequestUri;
+ hsession->uriOffset = attribute_data->httpRequestUriOffset;
+ hsession->uriEndOffset = attribute_data->httpRequestUriEndOffset;
+ attribute_data->httpRequestUri = nullptr;
+ attribute_data->httpRequestUriOffset = 0;
+ attribute_data->httpRequestUriEndOffset = 0;
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s uri (%u-%u) is %s\n", app_id_debug_session,
+ hsession->uriOffset, hsession->uriEndOffset,
+ hsession->uri);
+ }
+ }
+ if (attribute_data->httpRequestVia)
+ {
+ if (hsession->via)
+ {
+ snort_free(hsession->via);
+ if (!getAppIdFlag(APPID_SESSION_APP_REINSPECT))
+ hsession->chp_finished = 0;
+ }
+ hsession->via = attribute_data->httpRequestVia;
+ attribute_data->httpRequestVia = nullptr;
+ scan_flags |= SCAN_HTTP_VIA_FLAG;
+ }
+ else if (attribute_data->httpResponseVia)
+ {
+ if (hsession->via)
+ {
+ snort_free(hsession->via);
+ if (!getAppIdFlag(APPID_SESSION_APP_REINSPECT))
+ hsession->chp_finished = 0;
+ }
+ hsession->via = attribute_data->httpResponseVia;
+ attribute_data->httpResponseVia = nullptr;
+ scan_flags |= SCAN_HTTP_VIA_FLAG;
+ }
+ if (attribute_data->httpRequestUserAgent)
+ {
+ if (hsession->useragent)
+ {
+ snort_free(hsession->useragent);
+ if (!getAppIdFlag(APPID_SESSION_APP_REINSPECT))
+ hsession->chp_finished = 0;
+ }
+ hsession->useragent = attribute_data->httpRequestUserAgent;
+ attribute_data->httpRequestUserAgent = nullptr;
+ 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 (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s HTTP response version is %s\n", app_id_debug_session,
+ attribute_data->httpResponseVersion);
+ if (strncmp(attribute_data->httpResponseVersion, "HTTP/2", 6) == 0)
+ {
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s 3rd party detected and parsed HTTP/2\n",
+ app_id_debug_session);
+ is_http2 = true;
+ }
+ snort_free(attribute_data->httpResponseVersion);
+ attribute_data->httpResponseVersion = nullptr;
+ }
+ if (attribute_data->httpResponseCode)
+ {
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s HTTP response code is %s\n", app_id_debug_session,
+ attribute_data->httpResponseCode);
+ if (hsession->response_code)
+ {
+ snort_free(hsession->response_code);
+ if (!getAppIdFlag(APPID_SESSION_APP_REINSPECT))
+ hsession->chp_finished = 0;
+ }
+ hsession->response_code = 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 (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s HTTP response upgrade is %s\n", app_id_debug_session,
+ attribute_data->httpResponseUpgrade);
+ if (pAppidActiveConfig->mod_config->http2_detection_enabled)
+ if (hsession->response_code && (strncmp(
+ hsession->response_code, "101", 3) == 0))
+ if (strncmp(attribute_data->httpResponseUpgrade, "h2c", 3) == 0)
+ {
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s Got an upgrade to HTTP/2\n",
+ app_id_debug_session);
+ is_http2 = true;
+ }
+ snort_free(attribute_data->httpResponseUpgrade);
+ attribute_data->httpResponseUpgrade = nullptr;
+ }
+ if (!pAppidActiveConfig->mod_config->referred_appId_disabled &&
+ attribute_data->httpRequestReferer)
+ {
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s referrer is %s\n", app_id_debug_session,
+ attribute_data->httpRequestReferer);
+ if (hsession->referer)
+ {
+ snort_free(hsession->referer);
+ if (!getAppIdFlag(APPID_SESSION_APP_REINSPECT))
+ hsession->chp_finished = 0;
+ }
+ hsession->referer = attribute_data->httpRequestReferer;
+ attribute_data->httpRequestReferer = nullptr;
+ }
+ if (attribute_data->httpRequestCookie)
+ {
+ if (hsession->cookie)
+ {
+ snort_free(hsession->cookie);
+ if (!getAppIdFlag(APPID_SESSION_APP_REINSPECT))
+ hsession->chp_finished = 0;
+ }
+ hsession->cookie = attribute_data->httpRequestCookie;
+ hsession->cookieOffset = attribute_data->httpRequestCookieOffset;
+ hsession->cookieEndOffset = attribute_data->httpRequestCookieEndOffset;
+ attribute_data->httpRequestCookie = nullptr;
+ attribute_data->httpRequestCookieOffset = 0;
+ attribute_data->httpRequestCookieEndOffset = 0;
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s cookie (%u-%u) is %s\n", app_id_debug_session,
+ hsession->cookieOffset, hsession->cookieEndOffset,
+ hsession->cookie);
+ }
+ if (attribute_data->httpResponseContent)
+ {
+ if (hsession->content_type)
+ {
+ snort_free(hsession->content_type);
+ if (!getAppIdFlag(APPID_SESSION_APP_REINSPECT))
+ hsession->chp_finished = 0;
+ }
+ hsession->content_type = attribute_data->httpResponseContent;
+ attribute_data->httpResponseContent = nullptr;
+ scan_flags |= SCAN_HTTP_CONTENT_TYPE_FLAG;
+ }
+ if (ptype_scan_counts[LOCATION_PT] && attribute_data->httpResponseLocation)
+ {
+ if (hsession->location)
+ {
+ snort_free(hsession->location);
+ if (!getAppIdFlag(APPID_SESSION_APP_REINSPECT))
+ hsession->chp_finished = 0;
+ }
+ hsession->location = attribute_data->httpResponseLocation;
+ attribute_data->httpResponseLocation = nullptr;
+ }
+ if (attribute_data->httpRequestBody)
+ {
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s got a request body %s\n", app_id_debug_session,
+ attribute_data->httpRequestBody);
+ if (hsession->req_body)
+ {
+ snort_free(hsession->req_body);
+ if (!getAppIdFlag(APPID_SESSION_APP_REINSPECT))
+ hsession->chp_finished = 0;
+ }
+ hsession->req_body = attribute_data->httpRequestBody;
+ attribute_data->httpRequestBody = nullptr;
+ }
+ if (ptype_scan_counts[BODY_PT] && attribute_data->httpResponseBody)
+ {
+ if (hsession->body)
+ {
+ snort_free(hsession->body);
+ if (!getAppIdFlag(APPID_SESSION_APP_REINSPECT))
+ hsession->chp_finished = 0;
+ }
+ hsession->body = attribute_data->httpResponseBody;
+ attribute_data->httpResponseBody = nullptr;
+ }
+ if (attribute_data->numXffFields)
+ {
+ pickHttpXffAddress(p, attribute_data);
+ }
+ if (!hsession->chp_finished || hsession->chp_hold_flow)
+ {
+ setAppIdFlag(APPID_SESSION_CHP_INSPECTING);
+ if (thirdparty_appid_module)
+ thirdparty_appid_module->session_attr_set(tpsession,
+ TP_ATTR_CONTINUE_MONITORING);
+ }
+ if (attribute_data->httpResponseServer)
+ {
+ if (hsession->server)
+ snort_free(hsession->server);
+ hsession->server = attribute_data->httpResponseServer;
+ attribute_data->httpResponseServer = nullptr;
+ scan_flags |= SCAN_HTTP_VENDOR_FLAG;
+ }
+ if (attribute_data->httpRequestXWorkingWith)
+ {
+ if (hsession->x_working_with)
+ snort_free(hsession->x_working_with);
+ hsession->x_working_with = attribute_data->httpRequestXWorkingWith;
+ attribute_data->httpRequestXWorkingWith = nullptr;
+ scan_flags |= SCAN_HTTP_XWORKINGWITH_FLAG;
+ }
+ }
+ else if (ThirdPartyAppIDFoundProto(APP_ID_RTMP, proto_list) ||
+ ThirdPartyAppIDFoundProto(APP_ID_RTSP, proto_list))
+ {
+ if (!hsession)
+ hsession = (httpSession*)snort_calloc(sizeof(httpSession));
+
+ if (!hsession->url)
+ {
+ if (attribute_data->httpRequesUrl)
+ {
+ hsession->url = attribute_data->httpRequesUrl;
+ attribute_data->httpRequesUrl = nullptr;
+ scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
+ }
+ }
+
+ if (!pAppidActiveConfig->mod_config->referred_appId_disabled &&
+ !hsession->referer)
+ {
+ if (attribute_data->httpRequestReferer)
+ {
+ hsession->referer = attribute_data->httpRequestReferer;
+ attribute_data->httpRequestReferer = nullptr;
+ }
+ }
+
+ if (hsession->url || (confidence == 100 &&
+ session_packet_count > pAppidActiveConfig->mod_config->rtmp_max_packets))
+ {
+ if (hsession->url)
+ {
+ if (((getAppIdFromUrl(nullptr, hsession->url, nullptr,
+ hsession->referer, &client_app_id, &serviceAppId,
+ &payload_app_id, &referred_payload_app_id, 1, &pConfig->detectorHttpConfig)) ||
+ (getAppIdFromUrl(nullptr, hsession->url, nullptr,
+ hsession->referer, &client_app_id, &serviceAppId,
+ &payload_app_id, &referred_payload_app_id, 0, &pConfig->detectorHttpConfig))) == 1)
+ {
+ // do not overwrite a previously-set client or service
+ if (client_app_id <= APP_ID_NONE)
+ set_client_app_id_data(client_app_id, nullptr);
+ if (serviceAppId <= APP_ID_NONE)
+ set_service_appid_data(serviceAppId, nullptr, nullptr);
+
+ // DO overwrite a previously-set data
+ set_payload_app_id_data((ApplicationId)payload_app_id, nullptr);
+ set_referred_payload_app_id_data(referred_payload_app_id);
+ }
+ }
+
+ if (thirdparty_appid_module)
+ {
+ thirdparty_appid_module->disable_flags(tpsession,
+ TP_SESSION_FLAG_ATTRIBUTE | TP_SESSION_FLAG_TUNNELING |
+ TP_SESSION_FLAG_FUTUREFLOW);
+ thirdparty_appid_module->session_delete(tpsession, 1);
+ }
+ tpsession = nullptr;
+ clearAppIdFlag(APPID_SESSION_APP_REINSPECT);
+ }
+ }
+ else if (ThirdPartyAppIDFoundProto(APP_ID_SSL, proto_list))
+ {
+ AppId tmpAppId = APP_ID_NONE;
+
+ if (thirdparty_appid_module && tpsession)
+ tmpAppId = thirdparty_appid_module->session_appid_get(tpsession);
+
+ setAppIdFlag(APPID_SESSION_SSL_SESSION);
+
+ if (!tsession)
+ tsession = (tlsSession*)snort_calloc(sizeof(tlsSession));
+
+ if (!client_app_id)
+ set_client_app_id_data(APP_ID_SSL_CLIENT, nullptr);
+
+ if (attribute_data->tlsHost)
+ {
+ if (tsession->tls_host)
+ snort_free(tsession->tls_host);
+ tsession->tls_host = attribute_data->tlsHost;
+ attribute_data->tlsHost = nullptr;
+ if (testSSLAppIdForReinspect(tmpAppId))
+ scan_flags |= SCAN_SSL_HOST_FLAG;
+ }
+ if (testSSLAppIdForReinspect(tmpAppId))
+ {
+ if (attribute_data->tlsCname)
+ {
+ if (tsession->tls_cname)
+ snort_free(tsession->tls_cname);
+ tsession->tls_cname = attribute_data->tlsCname;
+ attribute_data->tlsCname = nullptr;
+ }
+ if (attribute_data->tlsOrgUnit)
+ {
+ if (tsession->tls_orgUnit)
+ snort_free(tsession->tls_orgUnit);
+ tsession->tls_orgUnit = attribute_data->tlsOrgUnit;
+ attribute_data->tlsOrgUnit = nullptr;
+ }
+ }
+ }
+ else if (ThirdPartyAppIDFoundProto(APP_ID_FTP_CONTROL, proto_list))
+ {
+ if (!pAppidActiveConfig->mod_config->ftp_userid_disabled && attribute_data->ftpCommandUser)
+ {
+ if (username)
+ snort_free(username);
+ username = attribute_data->ftpCommandUser;
+ attribute_data->ftpCommandUser = nullptr;
+ username_service = APP_ID_FTP_CONTROL;
+ setAppIdFlag(APPID_SESSION_LOGIN_SUCCEEDED);
+ }
+ }
+}
+
+void AppIdSession::checkTerminateTpModule(uint16_t tpPktCount)
+{
+ if ((tpPktCount >= pAppidActiveConfig->mod_config->max_tp_flow_depth) ||
+ (getAppIdFlag(APPID_SESSION_HTTP_SESSION | APPID_SESSION_APP_REINSPECT) ==
+ (APPID_SESSION_HTTP_SESSION | APPID_SESSION_APP_REINSPECT) &&
+ hsession && hsession->uri && (!hsession->chp_candidate || hsession->chp_finished)))
+ {
+ if (tp_app_id == APP_ID_NONE)
+ tp_app_id = APP_ID_UNKNOWN;
+ if (payload_app_id == APP_ID_NONE)
+ payload_app_id = APP_ID_UNKNOWN;
+ if (thirdparty_appid_module)
+ thirdparty_appid_module->session_delete(tpsession, 1);
+ }
+}
+
+bool AppIdSession::do_third_party_discovery(IpProtocol protocol, const sfip_t* ip,
+ Packet* p, int& direction)
+{
+ ThirdPartyAppIDAttributeData* tp_attribute_data;
+ AppId* tp_proto_list;
+ int tp_confidence;
+ bool isTpAppidDiscoveryDone = false;
+ AppIdConfig* pConfig = pAppidActiveConfig;
+
+ /*** Start of third-party processing. ***/
+ if (thirdparty_appid_module && !getAppIdFlag(APPID_SESSION_NO_TPI)
+ && (!TPIsAppIdDone(tpsession)
+ || getAppIdFlag(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 (getAppIdFlag(APPID_SESSION_APP_REINSPECT_SSL))
+ clearAppIdFlag(APPID_SESSION_APP_REINSPECT_SSL);
+
+ if (p->dsize || pAppidActiveConfig->mod_config->tp_allow_probes)
+ {
+ if (protocol != IpProtocol::TCP || !p->dsize || (p->packet_flags & PKT_STREAM_ORDER_OK)
+ || pAppidActiveConfig->mod_config->tp_allow_probes)
+ {
+ {
+ Profile tpLibPerfStats_profile_context(tpLibPerfStats);
+ if (!tpsession)
+ {
+ if (!(tpsession = thirdparty_appid_module->session_create()))
+ FatalError("Could not allocate tpsession data");
+ }; // debug output of packet content
+ thirdparty_appid_module->session_process(tpsession, p, direction, &tp_app_id, &tp_confidence,
+ &tp_proto_list, &tp_attribute_data);
+ }
+ isTpAppidDiscoveryDone = true;
+ if (thirdparty_appid_module->session_state_get(tpsession) == TP_STATE_CLASSIFIED)
+ clearAppIdFlag(APPID_SESSION_APP_REINSPECT);
+
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s 3rd party returned %d\n", app_id_debug_session, tp_app_id);
+
+ if (appInfoEntryFlagGet(tp_app_id, APPINFO_FLAG_IGNORE, pConfig))
+ {
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s 3rd party ignored\n", app_id_debug_session);
+
+ if (getAppIdFlag(APPID_SESSION_HTTP_SESSION))
+ tp_app_id = APP_ID_HTTP;
+ else
+ tp_app_id = APP_ID_NONE;
+ }
+ // For now, third party can detect HTTP/2 (w/o metadata) for
+ // some cases. Treat it like HTTP w/ is_http2 flag set.
+ if ((tp_app_id == APP_ID_HTTP2) && (tp_confidence == 100))
+ {
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s 3rd party saw HTTP/2\n", app_id_debug_session);
+
+ tp_app_id = APP_ID_HTTP;
+ is_http2 = true;
+ }
+ // if the third-party appId must be treated as a client, do it now
+ if (appInfoEntryFlagGet(tp_app_id, APPINFO_FLAG_TP_CLIENT, pAppidActiveConfig))
+ client_app_id = tp_app_id;
+
+ ProcessThirdPartyResults(p, tp_confidence, tp_proto_list, tp_attribute_data);
+ }
+ else
+ {
+ tp_app_id = APP_ID_NONE;
+ if (app_id_debug_session_flag && !getAppIdFlag(APPID_SESSION_TPI_OOO_LOGGED))
+ {
+ setAppIdFlag(APPID_SESSION_TPI_OOO_LOGGED);
+ LogMessage("AppIdDbg %s 3rd party packet out-of-order\n", app_id_debug_session);
+ }
+ }
+ if (thirdparty_appid_module->session_state_get(tpsession) == TP_STATE_MONITORING)
+ {
+ thirdparty_appid_module->disable_flags(tpsession,
+ TP_SESSION_FLAG_ATTRIBUTE | TP_SESSION_FLAG_TUNNELING | TP_SESSION_FLAG_FUTUREFLOW);
+ }
+ if (tp_app_id == APP_ID_SSL && (stream.get_application_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.
+ tp_app_id = APP_ID_NONE;
+ }
+ if (tp_app_id > APP_ID_NONE
+ && (!getAppIdFlag(APPID_SESSION_APP_REINSPECT) || payload_app_id > APP_ID_NONE))
+ {
+ AppId snorAppId;
+ // if the packet is HTTP, then search for via pattern
+ if (getAppIdFlag(APPID_SESSION_HTTP_SESSION) && hsession)
+ {
+ snorAppId = APP_ID_HTTP;
+ //data should never be APP_ID_HTTP
+ if (tp_app_id != APP_ID_HTTP)
+ tp_payload_app_id = tp_app_id;
+
+ tp_app_id = APP_ID_HTTP;
+ processHTTPPacket(p, direction, nullptr, pAppidActiveConfig);
+ if (TPIsAppIdAvailable(tpsession) && tp_app_id == APP_ID_HTTP
+ && !getAppIdFlag(APPID_SESSION_APP_REINSPECT))
+ {
+ rna_client_state = RNA_STATE_FINISHED;
+ setAppIdFlag(APPID_SESSION_CLIENT_DETECTED | APPID_SESSION_SERVICE_DETECTED);
+ rnaServiceState = RNA_STATE_FINISHED;
+ clearAppIdFlag(APPID_SESSION_CONTINUE);
+ if (direction == APP_ID_FROM_INITIATOR)
+ {
+ ip = p->ptrs.ip_api.get_dst();
+ service_ip = *ip;
+ service_port = p->ptrs.dp;
+ }
+ else
+ {
+ ip = p->ptrs.ip_api.get_src();
+ service_ip = *ip;
+ service_port = p->ptrs.sp;
+ }
+ }
+ }
+ else if (getAppIdFlag(APPID_SESSION_SSL_SESSION) && tsession)
+ {
+ examine_ssl_metadata(p, pConfig);
+ uint16_t serverPort;
+ AppId porAppId;
+ serverPort = (direction == APP_ID_FROM_INITIATOR) ? p->ptrs.dp : p->ptrs.sp;
+ porAppId = serverPort;
+ if (tp_app_id == APP_ID_SSL)
+ {
+ tp_app_id = porAppId;
+ //SSL policy needs to determine IMAPS/POP3S etc before appId sees first
+ // server packet
+ portServiceAppId = porAppId;
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s SSL is service %d, portServiceAppId %d\n", app_id_debug_session,
+ tp_app_id, portServiceAppId);
+ }
+ else
+ {
+ tp_payload_app_id = tp_app_id;
+ tp_app_id = porAppId;
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s SSL is %d\n", app_id_debug_session, tp_app_id);
+ }
+ snorAppId = APP_ID_SSL;
+ }
+ else
+ {
+ //for non-http protocols, tp id is treated like serviceId
+ snorAppId = tp_app_id;
+ }
+
+ sync_with_snort_id(snorAppId, p, pConfig);
+ }
+ else
+ {
+ if (protocol != IpProtocol::TCP || !p->dsize
+ || (p->packet_flags & (PKT_STREAM_ORDER_OK | PKT_STREAM_ORDER_BAD)))
+ {
+ if (direction == APP_ID_FROM_INITIATOR)
+ {
+ init_tpPackets++;
+ checkTerminateTpModule(init_tpPackets);
+ }
+ else
+ {
+ resp_tpPackets++;
+ checkTerminateTpModule(resp_tpPackets);
+ }
+ }
+ }
+ }
+ }
+
+ return isTpAppidDiscoveryDone;
+}
+#endif
+
+bool AppIdSession::do_service_discovery(IpProtocol protocol, int direction, AppId ClientAppId,
+ AppId payloadAppId, Packet* p)
+{
+ AppInfoTableEntry* entry;
+ bool isTpAppidDiscoveryDone = false;
+ AppIdConfig* pConfig = pAppidActiveConfig;
+
+ if (rnaServiceState != RNA_STATE_FINISHED)
+ {
+ Profile serviceMatchPerfStats_profile_context(serviceMatchPerfStats);
+ uint32_t prevRnaServiceState;
+ prevRnaServiceState = rnaServiceState;
+ //decision to directly call validator or go through elaborate service_state tracking
+ //is made once at the beginning of sesssion.
+ if (rnaServiceState == RNA_STATE_NONE && p->dsize)
+ {
+ if (p->flow->get_session_flags() & SSNFLAG_MIDSTREAM)
+ {
+ // Unless it could be ftp control
+ if (protocol == IpProtocol::TCP && (p->ptrs.sp == 21 || p->ptrs.dp == 21)
+ && !(p->ptrs.tcph->is_fin() || p->ptrs.tcph->is_rst()))
+ {
+ setAppIdFlag(APPID_SESSION_CLIENT_DETECTED | APPID_SESSION_NOT_A_SERVICE
+ | APPID_SESSION_SERVICE_DETECTED);
+ if (!AddFTPServiceState(this))
+ {
+ setAppIdFlag(APPID_SESSION_CONTINUE);
+ if (p->ptrs.dp != 21)
+ setAppIdFlag(APPID_SESSION_RESPONDER_SEEN);
+ }
+ rnaServiceState = RNA_STATE_STATEFUL;
+ }
+ else
+ {
+ setAppIdFlag(APPID_SESSION_MID | APPID_SESSION_SERVICE_DETECTED);
+ rnaServiceState = RNA_STATE_FINISHED;
+ }
+ }
+ else if (TPIsAppIdAvailable(tpsession))
+ {
+ if (tp_app_id > APP_ID_NONE)
+ {
+ //tp has positively identified appId, Dig deeper only if sourcefire
+ // detector identifies additional information or flow is UDP reveresed.
+ if ((entry = appInfoEntryGet(tp_app_id, pConfig)) && entry->svrValidator
+ && ((entry->flags & APPINFO_FLAG_SERVICE_ADDITIONAL)
+ || ((entry->flags & APPINFO_FLAG_SERVICE_UDP_REVERSED)
+ && protocol == IpProtocol::UDP
+ && getAppIdFlag(
+ APPID_SESSION_INITIATOR_MONITORED
+ | APPID_SESSION_RESPONDER_MONITORED))))
+ {
+ free_flow_data_by_mask(APPID_SESSION_DATA_SERVICE_MODSTATE_BIT);
+ serviceData = entry->svrValidator;
+ rnaServiceState = RNA_STATE_STATEFUL;
+ }
+ else
+ stop_rna_service_inspection(p, direction);
+ }
+ else
+ rnaServiceState = RNA_STATE_STATEFUL;
+ }
+ else
+ rnaServiceState = RNA_STATE_STATEFUL;
+ }
+ //stop rna inspection as soon as tp has classified a valid AppId later in the session
+ if (rnaServiceState == RNA_STATE_STATEFUL&&
+ prevRnaServiceState == RNA_STATE_STATEFUL &&
+ !getAppIdFlag(APPID_SESSION_NO_TPI) &&
+ TPIsAppIdAvailable(tpsession) &&
+ tp_app_id > APP_ID_NONE && tp_app_id < SF_APPID_MAX)
+ {
+ entry = appInfoEntryGet(tp_app_id, pConfig);
+ if (entry && entry->svrValidator && !(entry->flags & APPINFO_FLAG_SERVICE_ADDITIONAL))
+ {
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s Stop service detection\n", app_id_debug_session);
+ stop_rna_service_inspection(p, direction);
+ }
+ }
+ if (rnaServiceState == RNA_STATE_STATEFUL)
+ {
+ AppIdDiscoverService(p, direction, this, pConfig);
+ isTpAppidDiscoveryDone = true;
+ //to stop executing validator after service has been detected by RNA.
+ if (getAppIdFlag(APPID_SESSION_SERVICE_DETECTED |
+ APPID_SESSION_CONTINUE) == APPID_SESSION_SERVICE_DETECTED)
+ rnaServiceState = RNA_STATE_FINISHED;
+
+ if (serviceAppId == APP_ID_DNS && pAppidActiveConfig->mod_config->dns_host_reporting
+ && dsession && dsession->host)
+ {
+ size_t size = dsession->host_len;
+ dns_host_scan_hostname((const u_int8_t*) (dsession->host), size, &ClientAppId, &payloadAppId,
+ &pConfig->serviceDnsConfig);
+ set_client_app_id_data(ClientAppId, nullptr);
+ }
+ else if (serviceAppId == APP_ID_RTMP)
+ examine_rtmp_metadata();
+ else if (getAppIdFlag(APPID_SESSION_SSL_SESSION) && tsession)
+ examine_ssl_metadata(p, pConfig);
+
+ if (tp_app_id <= APP_ID_NONE && getAppIdFlag(APPID_SESSION_SERVICE_DETECTED |
+ APPID_SESSION_NOT_A_SERVICE | APPID_SESSION_IGNORE_HOST) ==
+ APPID_SESSION_SERVICE_DETECTED)
+ {
+ sync_with_snort_id(serviceAppId, p, pConfig);
+ }
+ }
+ }
+ return isTpAppidDiscoveryDone;
+}
+
+bool AppIdSession::do_client_discovery(int direction, Packet* p)
+{
+ bool isTpAppidDiscoveryDone = false;
+ AppInfoTableEntry* entry;
+ AppIdConfig* pConfig = pAppidActiveConfig;
+
+ if (rna_client_state != RNA_STATE_FINISHED)
+ {
+ Profile clientMatchPerfStats_profile_context(clientMatchPerfStats);
+ uint32_t prevRnaClientState = rna_client_state;
+ bool was_http2 = is_http2;
+ bool was_service = getAppIdFlag(APPID_SESSION_SERVICE_DETECTED) ? true : false;
+ //decision to directly call validator or go through elaborate service_state tracking
+ //is made once at the beginning of sesssion.
+ if (rna_client_state == RNA_STATE_NONE && p->dsize && direction == APP_ID_FROM_INITIATOR)
+ {
+ if (p->flow->get_session_flags() & SSNFLAG_MIDSTREAM)
+ rna_client_state = RNA_STATE_FINISHED;
+ else if (TPIsAppIdAvailable(tpsession) && ( tp_app_id > APP_ID_NONE )
+ && ( tp_app_id < SF_APPID_MAX ) )
+ {
+ entry = appInfoEntryGet(tp_app_id, pConfig);
+ if ( entry && entry->clntValidator
+ && ( ( entry->flags & APPINFO_FLAG_CLIENT_ADDITIONAL )
+ || ( ( entry->flags & APPINFO_FLAG_CLIENT_USER)
+ && getAppIdFlag(APPID_SESSION_DISCOVER_USER) ) ) )
+ {
+ //tp has positively identified appId, Dig deeper only if sourcefire
+ // detector identifies additional information
+ rna_client_data = entry->clntValidator;
+ rna_client_state = RNA_STATE_DIRECT;
+ }
+ else
+ {
+ setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
+ rna_client_state = RNA_STATE_FINISHED;
+ }
+ }
+ else if (getAppIdFlag(APPID_SESSION_HTTP_SESSION))
+ rna_client_state = RNA_STATE_FINISHED;
+ else
+ rna_client_state = RNA_STATE_STATEFUL;
+ }
+ //stop rna inspection as soon as tp has classified a valid AppId later in the session
+ if ((rna_client_state == RNA_STATE_STATEFUL || rna_client_state == RNA_STATE_DIRECT)
+ && rna_client_state == prevRnaClientState && !getAppIdFlag(APPID_SESSION_NO_TPI)
+ && TPIsAppIdAvailable(tpsession) && tp_app_id > APP_ID_NONE && tp_app_id < SF_APPID_MAX)
+ {
+ entry = appInfoEntryGet(tp_app_id, pConfig);
+ if (!(entry && entry->clntValidator && entry->clntValidator == rna_client_data
+ && (entry->flags & (APPINFO_FLAG_CLIENT_ADDITIONAL | APPINFO_FLAG_CLIENT_USER))))
+ {
+ rna_client_state = RNA_STATE_FINISHED;
+ setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
+ }
+ }
+ if (rna_client_state == RNA_STATE_DIRECT)
+ {
+ int ret = CLIENT_APP_INPROCESS;
+ if (direction == APP_ID_FROM_INITIATOR)
+ {
+ /* get out if we've already tried to validate a client app */
+ if (!getAppIdFlag(APPID_SESSION_CLIENT_DETECTED))
+ {
+ ret = exec_client_detectors(p, direction, pConfig);
+ }
+ }
+ else if (rnaServiceState != RNA_STATE_STATEFUL
+ && getAppIdFlag(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS))
+ {
+ ret = exec_client_detectors(p, direction, pConfig);
+ }
+
+ switch (ret)
+ {
+ case CLIENT_APP_INPROCESS:
+ break;
+ default:
+ rna_client_state = RNA_STATE_FINISHED;
+ break;
+ }
+ }
+ else if (rna_client_state == RNA_STATE_STATEFUL)
+ {
+ AppIdDiscoverClientApp(p, direction, this, pConfig);
+ isTpAppidDiscoveryDone = true;
+ if (candidate_client_list != nullptr)
+ {
+ if (sflist_count(candidate_client_list) > 0)
+ {
+ int ret = 0;
+ if (direction == APP_ID_FROM_INITIATOR)
+ {
+ /* get out if we've already tried to validate a client app */
+ if (!getAppIdFlag(APPID_SESSION_CLIENT_DETECTED))
+ ret = exec_client_detectors(p, direction, pConfig);
+ }
+ else if (rnaServiceState != RNA_STATE_STATEFUL
+ && getAppIdFlag(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS))
+ ret = exec_client_detectors(p, direction, pConfig);
+
+ if (ret < 0)
+ setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
+ }
+ else
+ setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
+ }
+ }
+
+ if (app_id_debug_session_flag)
+ if (!was_http2 && is_http2)
+ LogMessage("AppIdDbg %s Got a preface for HTTP/2\n", app_id_debug_session);
+
+ if (!was_service && getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
+ sync_with_snort_id(serviceAppId, p, pConfig);
+ }
+
+ return isTpAppidDiscoveryDone;
+}
+
+void AppIdSession::do_application_discovery(Packet* p)
+{
+ IpProtocol protocol;
+ AppId serviceAppId = 0;
+ AppId ClientAppId = 0;
+ AppId payloadAppId = 0;
+ bool isTpAppidDiscoveryDone = false;
+ uint64_t flow_flags;
+ int direction;
+ const sfip_t* ip;
+ uint16_t port;
+ AppIdConfig* pConfig = pAppidActiveConfig;
+
+ if( is_packet_ignored(p) )
+ return;
+
+ AppIdSession* session = (AppIdSession*) p->flow->get_application_data(AppIdSession::flow_id);
+ if (session)
+ {
+ if (session->common.fsf_type.flow_type == APPID_SESSION_TYPE_IGNORE)
+ return;
+
+ if (session->common.fsf_type.flow_type == APPID_SESSION_TYPE_NORMAL)
+ {
+ protocol = session->protocol;
+ session->flow = p->flow;
+ }
+ else if (p->is_tcp())
+ protocol = IpProtocol::TCP;
+ else
+ protocol = IpProtocol::UDP;
+
+ ip = p->ptrs.ip_api.get_src();
+ if (session->common.initiator_port)
+ direction = (session->common.initiator_port == p->ptrs.sp) ? APP_ID_FROM_INITIATOR :
+ APP_ID_FROM_RESPONDER;
+ else
+ direction = (sfip_fast_equals_raw(ip, &session->common.initiator_ip)) ?
+ APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
+ }
+ else
+ {
+ if (p->is_tcp())
+ protocol = IpProtocol::TCP;
+ else if (p->is_udp())
+ protocol = IpProtocol::UDP;
+ else if ( p->is_ip4() || p->is_ip6() )
+ protocol = p->get_ip_proto_next();
+ else
+ return;
+
+ // FIXIT - L Refactor to use direction symbols defined by snort proper
+ direction = p->is_from_client() ? APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
+ }
+
+ app_id_debug_session_flag = fwAppIdDebugCheck(p->flow, session, app_id_debug_flag,
+ &app_id_debug_info, app_id_debug_session, direction);
+
+ flow_flags = AppIdSession::is_session_monitored(p, direction, session);
+ if (!(flow_flags & (APPID_SESSION_DISCOVER_APP | APPID_SESSION_SPECIAL_MONITORED)))
+ {
+ if (!session)
+ {
+ if ((flow_flags & APPID_SESSION_BIDIRECTIONAL_CHECKED) ==
+ APPID_SESSION_BIDIRECTIONAL_CHECKED)
+ {
+ // FIXIT-M: This _dpd call needs to be convert to correct snort++ call
+ // static THREAD_LOCAL APPID_SESSION_STRUCT_FLAG ignore_fsf {
+ // APPID_SESSION_TYPE_IGNORE };
+
+ // _dpd.sessionAPI->set_application_data(p->flow, PP_APP_ID, &ignore_fsf,
+ // nullptr);
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s not monitored\n", app_id_debug_session);
+ }
+ else
+ {
+ ip = (direction == APP_ID_FROM_INITIATOR) ?
+ p->ptrs.ip_api.get_src() : p->ptrs.ip_api.get_dst();
+ AppIdSession* tmp_session = new AppIdSession(protocol, ip);
+
+ tmp_session->common.fsf_type.flow_type = APPID_SESSION_TYPE_TMP;
+ tmp_session->common.flags = flow_flags;
+ tmp_session->common.initiator_ip = *ip;
+ if ( ( protocol == IpProtocol::TCP || protocol == IpProtocol::UDP ) &&
+ p->ptrs.sp != p->ptrs.dp )
+ {
+ tmp_session->common.initiator_port =
+ (direction == APP_ID_FROM_INITIATOR) ? p->ptrs.sp : p->ptrs.dp;
+ }
+ else
+ tmp_session->common.initiator_port = 0;
+ tmp_session->common.policyId = appIdPolicyId;
+ p->flow->set_application_data(tmp_session);
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s unknown monitoring\n", app_id_debug_session);
+ }
+ }
+ else
+ {
+ session->common.flags = flow_flags;
+ if ((flow_flags & APPID_SESSION_BIDIRECTIONAL_CHECKED) ==
+ APPID_SESSION_BIDIRECTIONAL_CHECKED)
+ session->common.fsf_type.flow_type = APPID_SESSION_TYPE_IGNORE;
+ session->common.policyId = appIdPolicyId;
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s not monitored\n", app_id_debug_session);
+ }
+ return;
+ }
+
+ if (!session || session->common.fsf_type.flow_type == APPID_SESSION_TYPE_TMP)
+ {
+ /* This call will free the existing temporary session, if there is one */
+ session = AppIdSession::allocate_session(p, protocol, direction);
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s new session\n", app_id_debug_session);
+ }
+
+ appid_stats.processed_packets++;
+ session->session_packet_count++;
+
+ if (direction == APP_ID_FROM_INITIATOR)
+ session->stats.initiatorBytes += p->pkth->pktlen;
+ else
+ session->stats.responderBytes += p->pkth->pktlen;
+
+ session->common.flags = flow_flags;
+ session->common.policyId = appIdPolicyId;
+ session->common.policyId = appIdPolicyId;
+
+ if (session->getAppIdFlag(APPID_SESSION_IGNORE_FLOW))
+ {
+ if (app_id_debug_session_flag && !session->getAppIdFlag(APPID_SESSION_IGNORE_FLOW_LOGGED))
+ {
+ session->setAppIdFlag(APPID_SESSION_IGNORE_FLOW_LOGGED);
+ LogMessage("AppIdDbg %s Ignoring connection with service %d\n",
+ app_id_debug_session, session->serviceAppId);
+ }
+ return;
+ }
+
+ if (p->packet_flags & PKT_STREAM_ORDER_BAD)
+ session->setAppIdFlag(APPID_SESSION_OOO);
+
+ else if ( p->is_tcp() && p->ptrs.tcph )
+ {
+ const auto* tcph = p->ptrs.tcph;
+ if ( tcph->is_rst() && session->previous_tcp_flags == TH_SYN )
+ {
+ AppIdServiceIDState* id_state;
+
+ session->setAppIdFlag(APPID_SESSION_SYN_RST);
+ if (sfip_is_set(&session->service_ip))
+ {
+ ip = &session->service_ip;
+ port = session->service_port;
+ }
+ else
+ {
+ ip = p->ptrs.ip_api.get_src();
+ port = p->ptrs.sp;
+ }
+
+ id_state = AppIdGetServiceIDState(ip, IpProtocol::TCP, port,
+ AppIdServiceDetectionLevel(
+ session));
+
+ if (id_state)
+ {
+ if (!id_state->reset_time)
+ id_state->reset_time = packet_time();
+ else if ((packet_time() - id_state->reset_time) >= 60)
+ {
+ // FIXIT-H ip's on the packet are const
+ // AppIdRemoveServiceIDState(ip, IpProtocol::TCP, port,
+ // AppIdServiceDetectionLevel(session));
+ session->setAppIdFlag(APPID_SESSION_SERVICE_DELETED);
+ }
+ }
+ }
+
+ session->previous_tcp_flags = p->ptrs.tcph->th_flags;
+ }
+
+ /*HostPort based AppId. */
+ if (!(session->scan_flags & SCAN_HOST_PORT_FLAG))
+ {
+ HostPortVal* hv;
+
+ session->scan_flags |= SCAN_HOST_PORT_FLAG;
+ if (direction == APP_ID_FROM_INITIATOR)
+ {
+ ip = p->ptrs.ip_api.get_dst();
+ port = p->ptrs.dp;
+ }
+ else
+ {
+ ip = p->ptrs.ip_api.get_src();
+ port = p->ptrs.sp;
+ }
+
+ if ((hv = hostPortAppCacheFind(ip, port, protocol, pConfig)))
+ {
+ switch (hv->type)
+ {
+ case 1:
+ session->client_app_id = hv->appId;
+ session->rna_client_state = RNA_STATE_FINISHED;
+ break;
+ case 2:
+ session->payload_app_id = hv->appId;
+ break;
+ default:
+ session->serviceAppId = hv->appId;
+ session->sync_with_snort_id(hv->appId, p, pConfig);
+ session->rnaServiceState = RNA_STATE_FINISHED;
+ session->rna_client_state = RNA_STATE_FINISHED;
+ session->setAppIdFlag(APPID_SESSION_SERVICE_DETECTED);
+ if (thirdparty_appid_module)
+ thirdparty_appid_module->session_delete(session->tpsession, 1);
+ session->tpsession = nullptr;
+ }
+ }
+ }
+
+ session->check_app_detection_restart();
+
+ //restart inspection by 3rd party
+ if (!session->getAppIdFlag(APPID_SESSION_NO_TPI))
+ {
+ if (TPIsAppIdDone(session->tpsession) && session->getAppIdFlag(
+ APPID_SESSION_HTTP_SESSION) && p->dsize)
+ {
+ if (session->tp_reinspect_by_initiator)
+ {
+ session->clearAppIdFlag(APPID_SESSION_APP_REINSPECT);
+ if (direction == APP_ID_FROM_RESPONDER)
+ session->tp_reinspect_by_initiator = 0; //toggle at OK response
+ }
+ else if (direction == APP_ID_FROM_INITIATOR)
+ {
+ session->tp_reinspect_by_initiator = 1; //once per request
+ session->setAppIdFlag(APPID_SESSION_APP_REINSPECT);
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s 3rd party allow reinspect http\n",
+ app_id_debug_session);
+ session->clear_http_field();
+ }
+ }
+ }
+
+ if (session->tp_app_id == APP_ID_SSH && session->payload_app_id != APP_ID_SFTP &&
+ session->session_packet_count >= MIN_SFTP_PACKET_COUNT && session->session_packet_count <
+ MAX_SFTP_PACKET_COUNT)
+ {
+ if ( p->ptrs.ip_api.tos() == 8 )
+ {
+ session->payload_app_id = APP_ID_SFTP;
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s data is SFTP\n", app_id_debug_session);
+ }
+ }
+
+ Profile tpPerfStats_profile_context(tpPerfStats);
+
+#ifdef REMOVED_WHILE_NOT_IN_USE
+ // do third party detector processing
+ isTpAppidDiscoveryDone = session->do_third_party_discovery(protocol, ip, p, direction);
+#endif
+
+ if (direction == APP_ID_FROM_RESPONDER && !session->getAppIdFlag(
+ APPID_SESSION_PORT_SERVICE_DONE|APPID_SESSION_SYN_RST))
+ {
+ session->setAppIdFlag(APPID_SESSION_PORT_SERVICE_DONE);
+ session->portServiceAppId = getPortServiceId(protocol, p->ptrs.sp, pConfig);
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s port service %d\n", app_id_debug_session,
+ session->portServiceAppId);
+ }
+
+ /* Length-based detectors. */
+ /* Only check if:
+ * - Port service didn't find anything (and we haven't yet either).
+ * - We haven't hit the max packets allowed for detector sequence matches.
+ * - Packet has data (we'll ignore 0-sized packets in sequencing). */
+ if ( (session->portServiceAppId <= APP_ID_NONE)
+ && (session->length_sequence.sequence_cnt < LENGTH_SEQUENCE_CNT_MAX)
+ && (p->dsize > 0))
+ {
+ uint8_t index = session->length_sequence.sequence_cnt;
+ session->length_sequence.proto = protocol;
+ session->length_sequence.sequence_cnt++;
+ session->length_sequence.sequence[index].direction = direction;
+ session->length_sequence.sequence[index].length = p->dsize;
+ session->portServiceAppId = lengthAppCacheFind(&session->length_sequence, pConfig);
+ if (session->portServiceAppId > APP_ID_NONE)
+ session->setAppIdFlag(APPID_SESSION_PORT_SERVICE_DONE);
+ }
+
+ /* exceptions for rexec and any other service detector that needs to see SYN and SYN/ACK */
+ if (session->getAppIdFlag(APPID_SESSION_REXEC_STDERR))
+ {
+ AppIdDiscoverService(p, direction, session, pConfig);
+ if (session->serviceAppId == APP_ID_DNS &&
+ pAppidActiveConfig->mod_config->dns_host_reporting &&
+ session->dsession && session->dsession->host )
+ {
+ size_t size = session->dsession->host_len;
+ dns_host_scan_hostname((const u_int8_t*)session->dsession->host, size, &ClientAppId,
+ &payloadAppId, &pConfig->serviceDnsConfig);
+ session->set_client_app_id_data(ClientAppId, nullptr);
+ }
+ else if (session->serviceAppId == APP_ID_RTMP)
+ session->examine_rtmp_metadata();
+ else if (session->getAppIdFlag(APPID_SESSION_SSL_SESSION) && session->tsession)
+ session->examine_ssl_metadata(p, pConfig);
+ }
+ else if (protocol != IpProtocol::TCP || !p->dsize || (p->packet_flags & PKT_STREAM_ORDER_OK))
+ {
+ isTpAppidDiscoveryDone = session->do_service_discovery(protocol, direction, ClientAppId,
+ payloadAppId, p);
+ isTpAppidDiscoveryDone = session->do_client_discovery(direction, p);
+ session->setAppIdFlag(APPID_SESSION_ADDITIONAL_PACKET);
+ }
+ else
+ {
+ if (app_id_debug_session_flag && p->dsize &&
+ !session->getAppIdFlag(APPID_SESSION_OOO_LOGGED))
+ {
+ session->setAppIdFlag(APPID_SESSION_OOO_LOGGED);
+ LogMessage("AppIdDbg %s packet out-of-order\n", app_id_debug_session);
+ }
+ }
+
+ serviceAppId = session->pick_service_app_id();
+ payloadAppId = session->pick_payload_app_id();
+
+ if (serviceAppId > APP_ID_NONE)
+ {
+ if (session->getAppIdFlag(APPID_SESSION_DECRYPTED))
+ {
+ if (session->misc_app_id == APP_ID_NONE)
+ session->update_encrypted_app_id(serviceAppId);
+ }
+// FIXIT-M: Need to determine what api to use for this _dpd function
+#if 1
+ UNUSED(isTpAppidDiscoveryDone);
+#else
+ else if (isTpAppidDiscoveryDone && isSslServiceAppId(serviceAppId) &&
+ _dpd.isSSLPolicyEnabled(nullptr))
+ session->setAppIdFlag(APPID_SESSION_CONTINUE);
+#endif
+ }
+
+ p->flow->set_application_ids(serviceAppId, session->pick_client_app_id(), payloadAppId, session->pick_misc_app_id());
+
+ /* Set the field that the Firewall queries to see if we have a search engine. */
+ if (session->search_support_type == SEARCH_SUPPORT_TYPE_UNKNOWN && payloadAppId > APP_ID_NONE)
+ {
+ uint flags = appInfoEntryFlagGet(payloadAppId, APPINFO_FLAG_SEARCH_ENGINE |
+ APPINFO_FLAG_SUPPORTED_SEARCH, pConfig);
+ session->search_support_type =
+ (flags & APPINFO_FLAG_SEARCH_ENGINE) ?
+ ((flags & APPINFO_FLAG_SUPPORTED_SEARCH) ? SUPPORTED_SEARCH_ENGINE :
+ UNSUPPORTED_SEARCH_ENGINE )
+ : NOT_A_SEARCH_ENGINE;
+ if (app_id_debug_session_flag)
+ {
+ const char* typeString;
+ switch ( session->search_support_type )
+ {
+ case NOT_A_SEARCH_ENGINE: typeString = "NOT_A_SEARCH_ENGINE"; break;
+ case SUPPORTED_SEARCH_ENGINE: typeString = "SUPPORTED_SEARCH_ENGINE"; break;
+ case UNSUPPORTED_SEARCH_ENGINE: typeString = "UNSUPPORTED_SEARCH_ENGINE"; break;
+ default: typeString = "unknown"; break;
+ }
+
+ LogMessage("AppIdDbg %s appId: %u (safe)search_support_type=%s\n",
+ app_id_debug_session, payloadAppId, typeString);
+ }
+ }
+
+ if ( serviceAppId != APP_ID_NONE )
+ {
+ if ( payloadAppId != APP_ID_NONE && payloadAppId != session->pastIndicator)
+ {
+ session->pastIndicator = payloadAppId;
+ checkSessionForAFIndicator(p, direction, pConfig, (ApplicationId)payloadAppId);
+ }
+
+ if (session->payload_app_id == APP_ID_NONE && session->pastForecast != serviceAppId &&
+ session->pastForecast != APP_ID_UNKNOWN)
+ {
+ session->pastForecast = checkSessionForAFForecast(session, p, direction, pConfig,
+ (ApplicationId)serviceAppId);
+ }
+ }
+}
+
+static inline int PENetworkMatch(const sfip_t* pktAddr, const PortExclusion* pe)
+{
+ const uint32_t* pkt = pktAddr->ip32;
+ const uint32_t* nm = pe->netmask.u6_addr32;
+ const uint32_t* peIP = pe->ip.u6_addr32;
+ return (((pkt[0] & nm[0]) == peIP[0])
+ && ((pkt[1] & nm[1]) == peIP[1])
+ && ((pkt[2] & nm[2]) == peIP[2])
+ && ((pkt[3] & nm[3]) == peIP[3]));
+}
+
+static inline int checkPortExclusion(const Packet* pkt, int reversed)
+{
+ SF_LIST** src_port_exclusions;
+ SF_LIST** dst_port_exclusions;
+ SF_LIST* pe_list;
+ PortExclusion* pe;
+ const sfip_t* s_ip;
+ uint16_t port;
+ AppIdConfig* pConfig = pAppidActiveConfig;
+
+ if ( pkt->is_tcp() )
+ {
+ src_port_exclusions = pConfig->tcp_port_exclusions_src;
+ dst_port_exclusions = pConfig->tcp_port_exclusions_dst;
+ }
+ else if ( pkt->is_udp() )
+ {
+ src_port_exclusions = pConfig->udp_port_exclusions_src;
+ dst_port_exclusions = pConfig->udp_port_exclusions_dst;
+ }
+ else
+ return 0;
+
+ /* check the source port */
+ port = reversed ? pkt->ptrs.dp : pkt->ptrs.sp;
+ if ( port && (pe_list=src_port_exclusions[port]) != nullptr )
+ {
+ s_ip = reversed ? pkt->ptrs.ip_api.get_dst() : pkt->ptrs.ip_api.get_src();
+
+ SF_LNODE* node;
+
+ /* walk through the list of port exclusions for this port */
+ for ( pe = (PortExclusion*)sflist_first(pe_list, &node);
+ pe;
+ pe = (PortExclusion*)sflist_next(&node) )
+ {
+ if ( PENetworkMatch(s_ip, pe))
+ return 1;
+ }
+ }
+
+ /* check the dest port */
+ port = reversed ? pkt->ptrs.sp : pkt->ptrs.dp;
+ if ( port && (pe_list=dst_port_exclusions[port]) != nullptr )
+ {
+ s_ip = reversed ? pkt->ptrs.ip_api.get_src() : pkt->ptrs.ip_api.get_dst();
+
+ SF_LNODE* node;
+ /* walk through the list of port exclusions for this port */
+ for ( pe = (PortExclusion*)sflist_first(pe_list, &node);
+ pe;
+ pe = (PortExclusion*)sflist_next(&node) )
+ {
+ if ( PENetworkMatch(s_ip, pe))
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static inline unsigned isIPMonitored(const Packet* p, int dst)
+{
+ const sfip_t* sf_ip;
+ NetworkSet* net_list;
+ unsigned flags;
+ int32_t zone;
+ NSIPv6Addr ip6;
+ AppIdConfig* pConfig = pAppidActiveConfig;
+
+ if (!dst)
+ {
+ zone = p->pkth->ingress_group;
+ sf_ip = p->ptrs.ip_api.get_src();
+ }
+ else
+ {
+ zone = (p->pkth->egress_index == DAQ_PKTHDR_UNKNOWN) ? p->pkth->ingress_group
+ :
+ p->pkth->egress_group;
+ if (zone == DAQ_PKTHDR_FLOOD)
+ return 0;
+ sf_ip = p->ptrs.ip_api.get_dst();
+ }
+
+ if (zone >= 0 && zone < MAX_ZONES && pConfig->net_list_by_zone[zone])
+ net_list = pConfig->net_list_by_zone[zone];
+ else
+ net_list = pConfig->net_list;
+
+ if ( sf_ip->is_ip4() )
+ {
+ if (sf_ip->ip32[0] == 0xFFFFFFFF)
+ return IPFUNCS_CHECKED;
+ NetworkSet_ContainsEx(net_list, ntohl(sf_ip->ip32[0]), &flags);
+ }
+ else
+ {
+ memcpy(&ip6, sf_ip->ip32, sizeof(ip6));
+ NSIPv6AddrNtoH(&ip6);
+ NetworkSet_Contains6Ex(net_list, &ip6, &flags);
+ }
+
+ return flags | IPFUNCS_CHECKED;
+}
+
+static inline bool isSpecialSessionMonitored(const Packet* p)
+{
+ if ( p->is_ip4() )
+ {
+ if (p->is_udp() && ((p->ptrs.sp == 68 && p->ptrs.dp == 67)
+ || (p->ptrs.sp == 67 && p->ptrs.dp == 68)))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool AppIdSession::is_ssl_decryption_enabled()
+{
+ if (getAppIdFlag(APPID_SESSION_DECRYPTED))
+ return 1;
+// FIXIT-M J bad bad bad
+// #ifdef UNIT_TEST
+// if (session_packet_count >= 12)
+// return 1;
+// return 0;
+// #else
+ return flow->is_proxied();
+// #endif
+}
+
+
+uint64_t AppIdSession::is_session_monitored(const Packet* p, int dir, AppIdSession* session)
+{
+ uint64_t flags;
+ uint64_t flow_flags = APPID_SESSION_DISCOVER_APP;
+
+ flow_flags |= (dir == APP_ID_FROM_INITIATOR) ?
+ APPID_SESSION_INITIATOR_SEEN : APPID_SESSION_RESPONDER_SEEN;
+ if (session)
+ {
+ flow_flags |= session->common.flags;
+ if (session->common.policyId != appIdPolicyId)
+ {
+ if (checkPortExclusion(p, dir == APP_ID_FROM_RESPONDER))
+ {
+ flow_flags |= APPID_SESSION_INITIATOR_SEEN | APPID_SESSION_RESPONDER_SEEN |
+ APPID_SESSION_INITIATOR_CHECKED | APPID_SESSION_RESPONDER_CHECKED;
+ flow_flags &= ~(APPID_SESSION_INITIATOR_MONITORED |
+ APPID_SESSION_RESPONDER_MONITORED);
+ return flow_flags;
+ }
+ if (dir == APP_ID_FROM_INITIATOR)
+ {
+ if (session->getAppIdFlag(APPID_SESSION_INITIATOR_CHECKED))
+ {
+ flags = isIPMonitored(p, 0);
+ if (flags & IPFUNCS_HOSTS_IP)
+ flow_flags |= APPID_SESSION_INITIATOR_MONITORED;
+ else
+ flow_flags &= ~APPID_SESSION_INITIATOR_MONITORED;
+ }
+
+ if (session->getAppIdFlag(APPID_SESSION_RESPONDER_CHECKED))
+ {
+ flags = isIPMonitored(p, 1);
+ if (flags & IPFUNCS_HOSTS_IP)
+ flow_flags |= APPID_SESSION_RESPONDER_MONITORED;
+ else
+ flow_flags &= ~APPID_SESSION_RESPONDER_MONITORED;
+ }
+ }
+ else
+ {
+ if (session->getAppIdFlag(APPID_SESSION_RESPONDER_CHECKED))
+ {
+ flags = isIPMonitored(p, 0);
+ if (flags & IPFUNCS_HOSTS_IP)
+ flow_flags |= APPID_SESSION_RESPONDER_MONITORED;
+ else
+ flow_flags &= ~APPID_SESSION_RESPONDER_MONITORED;
+ }
+
+ if (session->getAppIdFlag(APPID_SESSION_INITIATOR_CHECKED))
+ {
+ flags = isIPMonitored(p, 1);
+ if (flags & IPFUNCS_HOSTS_IP)
+ flow_flags |= APPID_SESSION_INITIATOR_MONITORED;
+ else
+ flow_flags &= ~APPID_SESSION_INITIATOR_MONITORED;
+ }
+ }
+ }
+
+ if (session->getAppIdFlag(APPID_SESSION_BIDIRECTIONAL_CHECKED) ==
+ APPID_SESSION_BIDIRECTIONAL_CHECKED)
+ return flow_flags;
+
+ if (dir == APP_ID_FROM_INITIATOR)
+ {
+ if (!session->getAppIdFlag(APPID_SESSION_INITIATOR_CHECKED))
+ {
+ flags = isIPMonitored(p, 0);
+ flow_flags |= APPID_SESSION_INITIATOR_CHECKED;
+ if (flags & IPFUNCS_HOSTS_IP)
+ flow_flags |= APPID_SESSION_INITIATOR_MONITORED;
+ if (flags & IPFUNCS_USER_IP)
+ flow_flags |= APPID_SESSION_DISCOVER_USER;
+ if (flags & IPFUNCS_APPLICATION)
+ flow_flags |= APPID_SESSION_DISCOVER_APP;
+
+ if (isSpecialSessionMonitored(p))
+ {
+ flow_flags |= APPID_SESSION_SPECIAL_MONITORED;
+ }
+ }
+ if (!(flow_flags & APPID_SESSION_DISCOVER_APP)
+ && !session->getAppIdFlag(APPID_SESSION_RESPONDER_CHECKED))
+ {
+ flags = isIPMonitored(p, 1);
+ if (flags & IPFUNCS_CHECKED)
+ flow_flags |= APPID_SESSION_RESPONDER_CHECKED;
+ if (flags & IPFUNCS_HOSTS_IP)
+ flow_flags |= APPID_SESSION_RESPONDER_MONITORED;
+ if (flags & IPFUNCS_APPLICATION)
+ flow_flags |= APPID_SESSION_DISCOVER_APP;
+ if (isSpecialSessionMonitored(p))
+ {
+ flow_flags |= APPID_SESSION_SPECIAL_MONITORED;
+ }
+ }
+ }
+ else
+ {
+ if (!session->getAppIdFlag(APPID_SESSION_RESPONDER_CHECKED))
+ {
+ flags = isIPMonitored(p, 0);
+ flow_flags |= APPID_SESSION_RESPONDER_CHECKED;
+ if (flags & IPFUNCS_HOSTS_IP)
+ flow_flags |= APPID_SESSION_RESPONDER_MONITORED;
+ if (flags & IPFUNCS_APPLICATION)
+ flow_flags |= APPID_SESSION_DISCOVER_APP;
+ if (isSpecialSessionMonitored(p))
+ {
+ flow_flags |= APPID_SESSION_SPECIAL_MONITORED;
+ }
+ }
+ if (!(flow_flags & APPID_SESSION_DISCOVER_APP)
+ && !session->getAppIdFlag(APPID_SESSION_INITIATOR_CHECKED))
+ {
+ flags = isIPMonitored(p, 1);
+ if (flags & IPFUNCS_CHECKED)
+ flow_flags |= APPID_SESSION_INITIATOR_CHECKED;
+ if (flags & IPFUNCS_HOSTS_IP)
+ flow_flags |= APPID_SESSION_INITIATOR_MONITORED;
+ if (flags & IPFUNCS_USER_IP)
+ flow_flags |= APPID_SESSION_DISCOVER_USER;
+ if (flags & IPFUNCS_APPLICATION)
+ flow_flags |= APPID_SESSION_DISCOVER_APP;
+ if (isSpecialSessionMonitored(p))
+ {
+ flow_flags |= APPID_SESSION_SPECIAL_MONITORED;
+ }
+ }
+ }
+ }
+ else if (checkPortExclusion(p, 0))
+ {
+ flow_flags |= APPID_SESSION_INITIATOR_SEEN | APPID_SESSION_RESPONDER_SEEN |
+ APPID_SESSION_INITIATOR_CHECKED | APPID_SESSION_RESPONDER_CHECKED;
+ }
+ else if (dir == APP_ID_FROM_INITIATOR)
+ {
+ flags = isIPMonitored(p, 0);
+ flow_flags |= APPID_SESSION_INITIATOR_CHECKED;
+ if (flags & IPFUNCS_HOSTS_IP)
+ flow_flags |= APPID_SESSION_INITIATOR_MONITORED;
+ if (flags & IPFUNCS_USER_IP)
+ flow_flags |= APPID_SESSION_DISCOVER_USER;
+ if (flags & IPFUNCS_APPLICATION)
+ flow_flags |= APPID_SESSION_DISCOVER_APP;
+ if (!(flow_flags & APPID_SESSION_DISCOVER_APP))
+ {
+ flags = isIPMonitored(p, 1);
+ if (flags & IPFUNCS_CHECKED)
+ flow_flags |= APPID_SESSION_RESPONDER_CHECKED;
+ if (flags & IPFUNCS_HOSTS_IP)
+ flow_flags |= APPID_SESSION_RESPONDER_MONITORED;
+ if (flags & IPFUNCS_APPLICATION)
+ flow_flags |= APPID_SESSION_DISCOVER_APP;
+ }
+ if (isSpecialSessionMonitored(p))
+ {
+ flow_flags |= APPID_SESSION_SPECIAL_MONITORED;
+ }
+ }
+ else
+ {
+ flags = isIPMonitored(p, 0);
+ flow_flags |= APPID_SESSION_RESPONDER_CHECKED;
+ if (flags & IPFUNCS_HOSTS_IP)
+ flow_flags |= APPID_SESSION_RESPONDER_MONITORED;
+ if (flags & IPFUNCS_APPLICATION)
+ flow_flags |= APPID_SESSION_DISCOVER_APP;
+ if (!(flow_flags & APPID_SESSION_DISCOVER_APP))
+ {
+ flags = isIPMonitored(p, 1);
+ if (flags & IPFUNCS_CHECKED)
+ flow_flags |= APPID_SESSION_INITIATOR_CHECKED;
+ if (flags & IPFUNCS_HOSTS_IP)
+ flow_flags |= APPID_SESSION_INITIATOR_MONITORED;
+ if (flags & IPFUNCS_USER_IP)
+ flow_flags |= APPID_SESSION_DISCOVER_USER;
+ if (flags & IPFUNCS_APPLICATION)
+ flow_flags |= APPID_SESSION_DISCOVER_APP;
+ }
+
+ if (isSpecialSessionMonitored(p))
+ {
+ flow_flags |= APPID_SESSION_SPECIAL_MONITORED;
+ }
+ }
+
+ return flow_flags;
+}
+
+void AppIdSession::check_app_detection_restart()
+{
+ if (getAppIdFlag(APPID_SESSION_DECRYPTED))
+ return;
+
+ if (!is_ssl_decryption_enabled())
+ return;
+
+ AppId serviceAppId = pick_service_app_id();
+ bool isSsl = isSslServiceAppId(serviceAppId);
+
+ // A session could either:
+ // 1. Start of as SSL - captured with isSsl flag, OR
+ // 2. It could start of as a non-SSL session and later change to SSL. For example, FTP->FTPS.
+ // In this case APPID_SESSION_ENCRYPTED flag is set by the protocol state machine.
+ if (getAppIdFlag(APPID_SESSION_ENCRYPTED) || isSsl)
+ {
+ setAppIdFlag(APPID_SESSION_DECRYPTED);
+ encrypted.serviceAppId = serviceAppId;
+ encrypted.payloadAppId = pick_payload_app_id();
+ encrypted.ClientAppId = pick_client_app_id();
+ encrypted.miscAppId = pick_misc_app_id();
+ encrypted.referredAppId = pick_referred_payload_app_id();
+ reinit_shared_data();
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s SSL decryption is available, restarting app Detection\n",
+ app_id_debug_session);
+
+ // APPID_SESSION_ENCRYPTED is set upon receiving a command which upgrades the session to
+ // SSL. Next packet after the command will have encrypted traffic. In the case of a
+ // session which starts as SSL, current packet itself is encrypted. Set the special flag
+ // APPID_SESSION_APP_REINSPECT_SSL which allows reinspection of this pcaket.
+ if (isSsl)
+ setAppIdFlag(APPID_SESSION_APP_REINSPECT_SSL);
+ }
+}
+
+void AppIdSession::update_encrypted_app_id(AppId serviceAppId)
+{
+ switch (serviceAppId)
+ {
+ case APP_ID_HTTP:
+ if (misc_app_id == APP_ID_NSIIOPS || misc_app_id == APP_ID_DDM_SSL
+ || misc_app_id == APP_ID_MSFT_GC_SSL || misc_app_id ==
+ APP_ID_SF_APPLIANCE_MGMT)
+ {
+ break;
+ }
+ misc_app_id = APP_ID_HTTPS;
+ break;
+ case APP_ID_SMTP:
+ misc_app_id = APP_ID_SMTPS;
+ break;
+ case APP_ID_NNTP:
+ misc_app_id = APP_ID_NNTPS;
+ break;
+ case APP_ID_IMAP:
+ misc_app_id = APP_ID_IMAPS;
+ break;
+ case APP_ID_SHELL:
+ misc_app_id = APP_ID_SSHELL;
+ break;
+ case APP_ID_LDAP:
+ misc_app_id = APP_ID_LDAPS;
+ break;
+ case APP_ID_FTP_DATA:
+ misc_app_id = APP_ID_FTPSDATA;
+ break;
+ case APP_ID_FTP:
+ misc_app_id = APP_ID_FTPS;
+ break;
+ case APP_ID_TELNET:
+ misc_app_id = APP_ID_TELNET;
+ break;
+ case APP_ID_IRC:
+ misc_app_id = APP_ID_IRCS;
+ break;
+ case APP_ID_POP3:
+ misc_app_id = APP_ID_POP3S;
+ break;
+ default:
+ break;
+ }
+}
+
+void AppIdSession::set_client_app_id_data(AppId clientAppId, char** version)
+{
+ AppIdConfig* pConfig = pAppidActiveConfig;
+ if (clientAppId <= APP_ID_NONE || clientAppId == APP_ID_HTTP)
+ return;
+
+ if (client_app_id != clientAppId)
+ {
+ unsigned prev_priority = appInfoEntryPriorityGet(client_app_id, pConfig);
+ unsigned curr_priority = appInfoEntryPriorityGet(clientAppId, pConfig);
+
+ if (pAppidActiveConfig->mod_config->instance_id)
+ checkSandboxDetection(clientAppId);
+
+ if ((client_app_id) && (prev_priority > curr_priority ))
+ return;
+ client_app_id = clientAppId;
+
+ if (client_version)
+ snort_free(client_version);
+
+ if (version && *version)
+ {
+ client_version = *version;
+ *version = nullptr;
+ }
+ else
+ client_version = nullptr;
+ }
+ else if (version && *version)
+ {
+ if (client_version)
+ snort_free(client_version);
+ client_version = *version;
+ *version = nullptr;
+ }
+}
+
+void AppIdSession::sync_with_snort_id(AppId newAppId, Packet* p, AppIdConfig* pConfig)
+{
+ AppInfoTableEntry* entry;
+ int16_t tempSnortId = snort_id;
+
+ if (tempSnortId == UNSYNCED_SNORT_ID)
+ {
+ tempSnortId = snort_id = p->flow->ssn_state.application_protocol;
+ }
+
+ if (tempSnortId == snortId_for_ftp || tempSnortId == snortId_for_ftp_data ||
+ tempSnortId == snortId_for_imap || tempSnortId == snortId_for_pop3 ||
+ tempSnortId == snortId_for_smtp || tempSnortId == snortId_for_http2)
+ {
+ return; // These preprocessors, in snort proper, already know and expect these to remain
+ // unchanged.
+ }
+ if ((entry = appInfoEntryGet(newAppId, pConfig)) && (tempSnortId = entry->snortId))
+ {
+ // Snort has a separate protocol ID for HTTP/2. We don't. So, when we
+ // talk to them about it, we have to play by their rules.
+ if ((newAppId == APP_ID_HTTP) && (is_http2))
+ tempSnortId = snortId_for_http2;
+
+ if (tempSnortId != snort_id)
+ {
+ if (app_id_debug_session_flag)
+ if (tempSnortId == snortId_for_http2)
+ LogMessage("AppIdDbg %s Telling Snort that it's HTTP/2\n",
+ app_id_debug_session);
+
+ p->flow->ssn_state.application_protocol = tempSnortId;
+ snort_id = tempSnortId;
+ }
+ }
+}
+
+void AppIdSession::examine_ssl_metadata(Packet* p, AppIdConfig* pConfig)
+{
+ size_t size;
+ int ret;
+ AppId clientAppId = 0;
+ AppId payload_app_id = 0;
+
+ if ((scan_flags & SCAN_SSL_HOST_FLAG) && tsession->tls_host)
+ {
+ size = strlen(tsession->tls_host);
+ if ((ret = ssl_scan_hostname((const u_int8_t*)tsession->tls_host, size,
+ &clientAppId, &payload_app_id, &pConfig->serviceSslConfig)))
+ {
+ set_client_app_id_data(clientAppId, nullptr);
+ set_payload_app_id_data((ApplicationId)payload_app_id, nullptr);
+ setSSLSquelch(p, ret, (ret == 1 ? payload_app_id : clientAppId));
+ }
+ scan_flags &= ~SCAN_SSL_HOST_FLAG;
+ }
+ if (tsession->tls_cname)
+ {
+ size = strlen(tsession->tls_cname);
+ if ((ret = ssl_scan_cname((const u_int8_t*)tsession->tls_cname, size,
+ &clientAppId, &payload_app_id, &pConfig->serviceSslConfig)))
+ {
+ set_client_app_id_data(clientAppId, nullptr);
+ set_payload_app_id_data((ApplicationId)payload_app_id, nullptr);
+ setSSLSquelch(p, ret, (ret == 1 ? payload_app_id : clientAppId));
+ }
+ snort_free(tsession->tls_cname);
+ tsession->tls_cname = nullptr;
+ }
+ if (tsession->tls_orgUnit)
+ {
+ size = strlen(tsession->tls_orgUnit);
+ if ((ret = ssl_scan_cname((const u_int8_t*)tsession->tls_orgUnit, size,
+ &clientAppId, &payload_app_id, &pConfig->serviceSslConfig)))
+ {
+ set_client_app_id_data(clientAppId, nullptr);
+ set_payload_app_id_data((ApplicationId)payload_app_id, nullptr);
+ setSSLSquelch(p, ret, (ret == 1 ? payload_app_id : clientAppId));
+ }
+ snort_free(tsession->tls_orgUnit);
+ tsession->tls_orgUnit = nullptr;
+ }
+}
+
+void AppIdSession::examine_rtmp_metadata()
+{
+ AppId serviceAppId = 0;
+ AppId ClientAppId = 0;
+ AppId payloadAppId = 0;
+ AppId referredPayloadAppId = 0;
+ char* version = nullptr;
+ AppIdConfig* pConfig = pAppidActiveConfig;
+
+ if (!hsession)
+ hsession = (httpSession*)snort_calloc(sizeof(httpSession));
+
+ if (hsession->url)
+ {
+ if (((getAppIdFromUrl(nullptr, hsession->url, &version,
+ hsession->referer, &ClientAppId, &serviceAppId,
+ &payloadAppId, &referredPayloadAppId, 1, &pConfig->detectorHttpConfig)) ||
+ (getAppIdFromUrl(nullptr, hsession->url, &version,
+ hsession->referer, &ClientAppId, &serviceAppId,
+ &payloadAppId, &referredPayloadAppId, 0, &pConfig->detectorHttpConfig))) == 1)
+ {
+ /* do not overwrite a previously-set client or service */
+ if (ClientAppId <= APP_ID_NONE)
+ set_client_app_id_data(ClientAppId, nullptr);
+ if (serviceAppId <= APP_ID_NONE)
+ set_service_appid_data(serviceAppId, nullptr, nullptr);
+
+ /* DO overwrite a previously-set data */
+ set_payload_app_id_data((ApplicationId)payloadAppId, nullptr);
+ set_referred_payload_app_id_data(referredPayloadAppId);
+ }
+ }
+}
+
+void AppIdSession::set_referred_payload_app_id_data(AppId id)
+{
+ if (id <= APP_ID_NONE)
+ return;
+
+ if (referred_payload_app_id != id)
+ {
+ if (pAppidActiveConfig->mod_config->instance_id)
+ checkSandboxDetection(id);
+
+ referred_payload_app_id = id;
+ }
+}
+
+void AppIdSession::set_payload_app_id_data(ApplicationId id, char** version)
+{
+ AppIdConfig* pConfig = pAppidActiveConfig;
+
+ if (id <= APP_ID_NONE)
+ return;
+
+ if (payload_app_id != id)
+ {
+ unsigned prev_priority = appInfoEntryPriorityGet(payload_app_id, pConfig);
+ unsigned curr_priority = appInfoEntryPriorityGet(id, pConfig);
+
+ if (pAppidActiveConfig->mod_config->instance_id)
+ checkSandboxDetection(id);
+
+ if ((payload_app_id ) && (prev_priority > curr_priority ))
+ return;
+
+ payload_app_id = id;
+
+ if (payload_version)
+ snort_free(payload_version);
+
+ if (version && *version)
+ {
+ payload_version = *version;
+ *version = nullptr;
+ }
+ else
+ payload_version = nullptr;
+ }
+ else if (version && *version)
+ {
+ if (payload_version)
+ snort_free(payload_version);
+ payload_version = *version;
+ *version = nullptr;
+ }
+}
+
+void AppIdSession::set_service_appid_data(AppId id, char* vendor, char** version)
+{
+ if (id <= APP_ID_NONE)
+ return;
+
+ //in drambuie, 3rd party is in INIT state after processing first GET requuest.
+ if (id == APP_ID_HTTP)
+ {
+ if (client_service_app_id == APP_ID_NONE)
+ {
+ client_service_app_id = id;
+ }
+ return;
+ }
+
+ if (serviceAppId != id)
+ {
+ serviceAppId = id;
+
+ if (pAppidActiveConfig->mod_config->instance_id)
+ checkSandboxDetection(id);
+
+ /* Clear out previous values of vendor & version */
+ if (serviceVendor)
+ {
+ snort_free(serviceVendor);
+ serviceVendor = nullptr;
+ }
+ if (serviceVersion)
+ {
+ snort_free(serviceVersion);
+ serviceVersion = nullptr;
+ }
+
+ if (vendor)
+ serviceVendor = vendor;
+
+ if (version && *version)
+ {
+ serviceVersion = *version;
+ *version = nullptr;
+ }
+ }
+ else
+ {
+ if (vendor || version)
+ {
+ /* Clear previous values */
+ if (serviceVendor)
+ snort_free(serviceVendor);
+ if (serviceVersion)
+ snort_free(serviceVersion);
+
+ /* set vendor */
+ if (vendor)
+ serviceVendor = vendor;
+ else
+ serviceVendor = nullptr;
+
+ /* set version */
+ if (version && *version)
+ {
+ serviceVersion = *version;
+ *version = nullptr;
+ }
+ else
+ serviceVersion = nullptr;
+ }
+ }
+}
+
+void AppIdSession::clear_http_field()
+{
+ if (hsession == nullptr)
+ return;
+
+ if (hsession->referer)
+ {
+ snort_free(hsession->referer);
+ hsession->referer = nullptr;
+ }
+ if (hsession->cookie)
+ {
+ snort_free(hsession->cookie);
+ hsession->cookie = nullptr;
+ }
+ if (hsession->url)
+ {
+ snort_free(hsession->url);
+ hsession->url = nullptr;
+ }
+ if (hsession->useragent)
+ {
+ snort_free(hsession->useragent);
+ hsession->useragent = nullptr;
+ }
+ if (hsession->host)
+ {
+ snort_free(hsession->host);
+ hsession->host = nullptr;
+ }
+ if (hsession->uri)
+ {
+ snort_free(hsession->uri);
+ hsession->uri = nullptr;
+ }
+ if (hsession->content_type)
+ {
+ snort_free(hsession->content_type);
+ hsession->content_type = nullptr;
+ }
+ if (hsession->location)
+ {
+ snort_free(hsession->location);
+ hsession->location = nullptr;
+ }
+ if (hsession->body)
+ {
+ snort_free(hsession->body);
+ hsession->body = nullptr;
+ }
+ if (hsession->req_body)
+ {
+ snort_free(hsession->req_body);
+ hsession->req_body = nullptr;
+ }
+ if (hsession->xffAddr)
+ {
+ sfip_free(hsession->xffAddr);
+ hsession->xffAddr = nullptr;
+ }
+}
+
+void AppIdSession::free_http_session_data()
+{
+ int i;
+
+ if (hsession == nullptr)
+ return;
+
+ clear_http_field();
+
+ for (i = 0; i < NUMBER_OF_PTYPES; i++)
+ {
+ if (nullptr != hsession->new_field[i])
+ {
+ snort_free(hsession->new_field[i]);
+ hsession->new_field[i] = nullptr;
+ }
+ }
+ if (hsession->fflow)
+ {
+ snort_free(hsession->fflow);
+ hsession->fflow = nullptr;
+ }
+ if (hsession->via)
+ {
+ snort_free(hsession->via);
+ hsession->via = nullptr;
+ }
+ if (hsession->content_type)
+ {
+ snort_free(hsession->content_type);
+ hsession->content_type = nullptr;
+ }
+ if (hsession->response_code)
+ {
+ snort_free(hsession->response_code);
+ hsession->response_code = nullptr;
+ }
+
+ snort_free(hsession);
+ hsession = nullptr;
+}
+
+void AppIdSession::free_dns_session_data()
+{
+ if (dsession )
+ {
+ if (dsession->host)
+ {
+ snort_free(dsession->host);
+ dsession->host = nullptr;
+ }
+ snort_free(dsession);
+ dsession = nullptr;
+ }
+}
+
+void AppIdSession::free_tls_session_data()
+{
+ if (tsession )
+ {
+ if (tsession->tls_host)
+ snort_free(tsession->tls_host);
+ if (tsession->tls_cname)
+ snort_free(tsession->tls_cname);
+ if (tsession->tls_orgUnit)
+ snort_free(tsession->tls_orgUnit);
+ snort_free(tsession);
+ tsession = nullptr;
+ }
+}
+
+void AppIdSession::free_flow_data()
+{
+ AppIdFlowData* tmp_fd;
+
+ while ((tmp_fd = flowData))
+ {
+ flowData = tmp_fd->next;
+ if (tmp_fd->fd_data && tmp_fd->fd_free)
+ tmp_fd->fd_free(tmp_fd->fd_data);
+ tmp_fd->next = fd_free_list;
+ fd_free_list = tmp_fd;
+ }
+}
+
+void AppIdSession::delete_shared_data()
+{
+ RNAServiceSubtype* rna_service_subtype;
+
+ /*check daq flag */
+ appIdStatsUpdate(this);
+
+ if (flow)
+ FailInProcessService(this, pAppidActiveConfig);
+ free_flow_data();
+
+ if (thirdparty_appid_module)
+ {
+ thirdparty_appid_module->session_delete(tpsession, 0);
+ tpsession = nullptr;
+ }
+
+ snort_free(client_version);
+ snort_free(serviceVendor);
+ snort_free(serviceVersion);
+ snort_free(netbios_name);
+ while ((rna_service_subtype = subtype))
+ {
+ subtype = rna_service_subtype->next;
+ snort_free(*(void**)&rna_service_subtype->service);
+ snort_free(*(void**)&rna_service_subtype->vendor);
+ snort_free(*(void**)&rna_service_subtype->version);
+ snort_free(rna_service_subtype);
+ }
+ if (candidate_service_list)
+ {
+ sflist_free(candidate_service_list);
+ candidate_service_list = nullptr;
+ }
+
+ if (candidate_client_list)
+ {
+ sflist_free(candidate_client_list);
+ candidate_client_list = nullptr;
+ }
+ snort_free(username);
+ snort_free(netbios_domain);
+ snort_free(payload_version);
+ free_http_session_data();
+ free_tls_session_data();
+ free_dns_session_data();
+ tsession = nullptr;
+
+ snort_free(firewallEarlyData);
+ firewallEarlyData = nullptr;
+
+ // should be freed by flow
+ // appSharedDataFree(sharedData);
+}
+
+void AppIdSession::release_free_list_flow_data()
+{
+ AppIdFlowData* tmp_fd;
+
+ while ((tmp_fd = fd_free_list))
+ {
+ fd_free_list = fd_free_list->next;
+ snort_free(tmp_fd);
+ }
+}
+
+void* AppIdSession::get_flow_data(unsigned id)
+{
+ AppIdFlowData* tmp_fd;
+
+ for (tmp_fd = flowData; tmp_fd && tmp_fd->fd_id != id; tmp_fd = tmp_fd->next)
+ ;
+ return tmp_fd ? tmp_fd->fd_data : nullptr;
+}
+
+void* AppIdSession::remove_flow_data(unsigned id)
+{
+ AppIdFlowData** pfd;
+ AppIdFlowData* fd;
+
+ for (pfd = &flowData; *pfd && (*pfd)->fd_id != id; pfd = &(*pfd)->next)
+ ;
+ if ((fd = *pfd))
+ {
+ *pfd = fd->next;
+ fd->next = fd_free_list;
+ fd_free_list = fd;
+ return fd->fd_data;
+ }
+ return nullptr;
+}
+
+void AppIdSession::free_flow_data_by_id(unsigned id)
+{
+ AppIdFlowData** pfd;
+ AppIdFlowData* fd;
+
+ for (pfd = &flowData; *pfd && (*pfd)->fd_id != id; pfd = &(*pfd)->next)
+ ;
+ if ((fd = *pfd))
+ {
+ *pfd = fd->next;
+ if (fd->fd_data && fd->fd_free)
+ fd->fd_free(fd->fd_data);
+ fd->next = fd_free_list;
+ fd_free_list = fd;
+ }
+}
+
+void AppIdSession::free_flow_data_by_mask(unsigned mask)
+{
+ AppIdFlowData** pfd;
+ AppIdFlowData* fd;
+
+ pfd = &flowData;
+ while (*pfd)
+ {
+ if ((*pfd)->fd_id & mask)
+ {
+ fd = *pfd;
+ *pfd = fd->next;
+ if (fd->fd_data && fd->fd_free)
+ fd->fd_free(fd->fd_data);
+ fd->next = fd_free_list;
+ fd_free_list = fd;
+ }
+ else
+ {
+ pfd = &(*pfd)->next;
+ }
+ }
+}
+
+int AppIdSession::add_flow_data(void* data, unsigned id, AppIdFreeFCN fcn)
+{
+ AppIdFlowData* tmp_fd;
+
+ if (fd_free_list)
+ {
+ tmp_fd = fd_free_list;
+ fd_free_list = tmp_fd->next;
+ }
+ else
+ tmp_fd = (AppIdFlowData*)snort_alloc(sizeof(AppIdFlowData));
+
+ tmp_fd->fd_id = id;
+ tmp_fd->fd_data = data;
+ tmp_fd->fd_free = fcn;
+ tmp_fd->next = flowData;
+ flowData = tmp_fd;
+ return 0;
+}
+
+int AppIdSession::add_flow_data_id(uint16_t port, const RNAServiceElement* svc_element)
+{
+ if (serviceData)
+ return -1;
+ serviceData = svc_element;
+ service_port = port;
+ return 0;
+}
+
+void AppIdSession::stop_rna_service_inspection(Packet* p, int direction)
+{
+ if (direction == APP_ID_FROM_INITIATOR)
+ {
+ service_ip = *p->ptrs.ip_api.get_dst();
+ service_port = p->ptrs.dp;
+ }
+ else
+ {
+ service_ip = *p->ptrs.ip_api.get_src();
+ service_port = p->ptrs.sp;
+ }
+
+ rnaServiceState = RNA_STATE_FINISHED;
+ setAppIdFlag(APPID_SESSION_SERVICE_DETECTED);
+ clearAppIdFlag(APPID_SESSION_CONTINUE);
+}
+
+AppId AppIdSession::is_appid_detection_done()
+{
+ return getAppIdFlag(APPID_SESSION_SERVICE_DETECTED);
+}
+
+AppId AppIdSession::pick_service_app_id()
+{
+ AppId rval;
+
+ if ( common.fsf_type.flow_type != APPID_SESSION_TYPE_NORMAL )
+ return APP_ID_NONE;
+
+ if (getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
+ {
+ bool deferred = appInfoEntryFlagGet(serviceAppId, APPINFO_FLAG_DEFER, pAppidActiveConfig)
+ || appInfoEntryFlagGet(tp_app_id, APPINFO_FLAG_DEFER, pAppidActiveConfig);
+
+ if (serviceAppId > APP_ID_NONE && !deferred)
+ return serviceAppId;
+ if (TPIsAppIdAvailable(tpsession))
+ {
+ if (tp_app_id > APP_ID_NONE)
+ return tp_app_id;
+ else if (deferred)
+ return serviceAppId;
+ else
+ rval = APP_ID_UNKNOWN_UI;
+ }
+ else
+ rval = tp_app_id;
+ }
+ else if (tp_app_id > APP_ID_NONE)
+ return tp_app_id;
+ else
+ rval = APP_ID_NONE;
+
+ if (client_service_app_id > APP_ID_NONE)
+ return client_service_app_id;
+
+ if (portServiceAppId > APP_ID_NONE)
+ return portServiceAppId;
+
+ return rval;
+}
+
+AppId AppIdSession::pick_only_service_app_id()
+{
+ if ( common.fsf_type.flow_type != APPID_SESSION_TYPE_NORMAL )
+ return APP_ID_NONE;
+
+ bool deferred = appInfoEntryFlagGet(serviceAppId, APPINFO_FLAG_DEFER, pAppidActiveConfig)
+ || appInfoEntryFlagGet(tp_app_id, APPINFO_FLAG_DEFER, pAppidActiveConfig);
+
+ if (serviceAppId > APP_ID_NONE && !deferred)
+ return serviceAppId;
+
+ if (TPIsAppIdAvailable(tpsession) && tp_app_id > APP_ID_NONE)
+ return tp_app_id;
+ else if (deferred)
+ return serviceAppId;
+
+ if (serviceAppId < APP_ID_NONE)
+ return APP_ID_UNKNOWN_UI;
+
+ return APP_ID_NONE;
+}
+
+AppId AppIdSession::pick_misc_app_id()
+{
+ if ( common.fsf_type.flow_type != APPID_SESSION_TYPE_NORMAL )
+ return APP_ID_NONE;
+ if (misc_app_id > APP_ID_NONE)
+ return misc_app_id;
+ return APP_ID_NONE;
+}
+
+AppId AppIdSession::pick_client_app_id()
+{
+ if ( common.fsf_type.flow_type != APPID_SESSION_TYPE_NORMAL )
+ return APP_ID_NONE;
+ if (client_app_id > APP_ID_NONE)
+ return client_app_id;
+ return APP_ID_NONE;
+}
+
+AppId AppIdSession::pick_payload_app_id()
+{
+ if ( common.fsf_type.flow_type != APPID_SESSION_TYPE_NORMAL )
+ return APP_ID_NONE;
+
+ // if we have a deferred payload, just use it.
+ // we are not worried about the APP_ID_UNKNOWN case here
+ if (appInfoEntryFlagGet(tp_payload_app_id, APPINFO_FLAG_DEFER_PAYLOAD, pAppidActiveConfig))
+ return tp_payload_app_id;
+ else if (payload_app_id > APP_ID_NONE)
+ return payload_app_id;
+ else if (tp_payload_app_id > APP_ID_NONE)
+ return tp_payload_app_id;
+
+ return APP_ID_NONE;
+}
+
+AppId AppIdSession::pick_referred_payload_app_id()
+{
+ if ( common.fsf_type.flow_type != APPID_SESSION_TYPE_NORMAL )
+ return APP_ID_NONE;
+ if (referred_payload_app_id > APP_ID_NONE)
+ return referred_payload_app_id;
+ return APP_ID_NONE;
+}
+
+AppId AppIdSession::fw_pick_service_app_id()
+{
+ AppId appId;
+ appId = pick_service_app_id();
+ if (appId == APP_ID_NONE)
+ appId = encrypted.serviceAppId;
+ return appId;
+}
+
+AppId AppIdSession::fw_pick_misc_app_id()
+{
+ AppId appId;
+ appId = pick_misc_app_id();
+ if (appId == APP_ID_NONE)
+ appId = encrypted.miscAppId;
+ return appId;
+}
+
+AppId AppIdSession::fw_pick_client_app_id()
+{
+ AppId appId;
+ appId = pick_client_app_id();
+ return appId;
+}
+
+AppId AppIdSession::fw_pick_payload_app_id()
+{
+ AppId appId;
+ appId = pick_payload_app_id();
+ if (appId == APP_ID_NONE)
+ appId = encrypted.payloadAppId;
+ return appId;
+}
+
+AppId AppIdSession::fw_pick_referred_payload_app_id()
+{
+ AppId appId;
+ appId = pick_referred_payload_app_id();
+ if (appId == APP_ID_NONE)
+ appId = encrypted.referredAppId;
+ return appId;
+}
+
+bool AppIdSession::is_ssl_session_decrypted()
+{
+ return getAppIdFlag(APPID_SESSION_DECRYPTED);
+}
+
+#ifdef REMOVED_WHILE_NOT_IN_USE
+
+static const char* httpFieldName[ NUMBER_OF_PTYPES ] = // for use in debug messages
+{
+ "useragent",
+ "host",
+ "referer",
+ "uri",
+ "cookie",
+ "req_body",
+ "content_type",
+ "location",
+ "body",
+};
+
+int AppIdSession::initial_CHP_sweep(char** chp_buffers, MatchedCHPAction** ppmatches,
+ const DetectorHttpConfig* pHttpConfig)
+{
+ CHPApp* cah = nullptr;
+ int longest = 0;
+ int size, i;
+ int scanKeyFoundSomething=0;
+ CHPMatchTally* pTally = nullptr; // scanKeyCHP allocates a pointer, but we free it when ready
+
+ for (i = 0; i <= MAX_KEY_PATTERN; i++)
+ {
+ ppmatches[i] = nullptr;
+ if (chp_buffers[i] && (size = strlen(chp_buffers[i])) &&
+ scanKeyCHP((PatternType)i, chp_buffers[i], size, &pTally, &ppmatches[i], pHttpConfig))
+ scanKeyFoundSomething=1;
+ }
+ if (!scanKeyFoundSomething)
+ return 0;
+
+ for (i = 0; i < pTally->in_use_elements; i++)
+ {
+ // Only those items which have had their key_pattern_countdown field reduced to zero are a
+ // full match
+ if (pTally->item[i].key_pattern_countdown)
+ continue;
+ if (longest < pTally->item[i].key_pattern_length_sum)
+ {
+ // We've found a new longest pattern set
+ longest = pTally->item[i].key_pattern_length_sum;
+ cah = pTally->item[i].chpapp;
+ }
+ }
+ // either we have a candidate or we don't so we can free the tally structure either way.
+ free(pTally);
+
+ if (cah == nullptr)
+ {
+ // We were planning to pass along the content of ppmatches to the second phase and let
+ // them be freed inside scanCHP, but we have no candidate so we free here
+ for (i = 0; i <= MAX_KEY_PATTERN; i++)
+ {
+ if (ppmatches[i])
+ {
+ FreeMatchedCHPActions(ppmatches[i]);
+ ppmatches[i] = nullptr;
+ }
+ }
+ return 0;
+ }
+
+ /***************************************************************
+ candidate has been chosen and it is pointed to by cah
+ we will preserve any match sets until the calls to scanCHP()
+ ***************************************************************/
+ for (i = 0; i < NUMBER_OF_PTYPES; i++)
+ {
+ ptype_scan_counts[i] = cah->ptype_scan_counts[i];
+ hsession->ptype_req_counts[i] = cah->ptype_req_counts[i] +
+ cah->ptype_rewrite_insert_used[i];
+ if (i > 3 && !cah->ptype_scan_counts[i]
+ && !getAppIdFlag(APPID_SESSION_SPDY_SESSION))
+ {
+ clearAppIdFlag(APPID_SESSION_CHP_INSPECTING);
+ if (thirdparty_appid_module)
+ thirdparty_appid_module->session_attr_clear(tpsession,
+ TP_ATTR_CONTINUE_MONITORING);
+ }
+ }
+ hsession->chp_candidate = cah->appIdInstance;
+ hsession->app_type_flags = cah->app_type_flags;
+ hsession->num_matches = cah->num_matches;
+ hsession->num_scans = cah->num_scans;
+
+ if (thirdparty_appid_module)
+ {
+ if ((ptype_scan_counts[CONTENT_TYPE_PT]))
+ thirdparty_appid_module->session_attr_set(tpsession, TP_ATTR_COPY_RESPONSE_CONTENT);
+ else
+ thirdparty_appid_module->session_attr_clear(tpsession, TP_ATTR_COPY_RESPONSE_CONTENT);
+
+ if ((ptype_scan_counts[LOCATION_PT]))
+ thirdparty_appid_module->session_attr_set(tpsession, TP_ATTR_COPY_RESPONSE_LOCATION);
+ else
+ thirdparty_appid_module->session_attr_clear(tpsession, TP_ATTR_COPY_RESPONSE_LOCATION);
+
+ if ((ptype_scan_counts[BODY_PT]))
+ thirdparty_appid_module->session_attr_set(tpsession, TP_ATTR_COPY_RESPONSE_BODY);
+ else
+ thirdparty_appid_module->session_attr_clear(tpsession, TP_ATTR_COPY_RESPONSE_BODY);
+ }
+
+ return 1;
+}
+
+void AppIdSession::processCHP(char** version, Packet* p, const AppIdConfig* pConfig)
+{
+ int i, size;
+ int found_in_buffer = 0;
+ char* user = nullptr;
+ AppId chp_final;
+ AppId ret = 0;
+ httpSession* http_session = hsession;
+
+ char* chp_buffers[NUMBER_OF_PTYPES] =
+ {
+ http_session->useragent,
+ http_session->host,
+ http_session->referer,
+ http_session->uri,
+ http_session->cookie,
+ http_session->req_body,
+ http_session->content_type,
+ http_session->location,
+ http_session->body,
+ };
+
+ char* chp_rewritten[NUMBER_OF_PTYPES] =
+ {
+ nullptr,nullptr,nullptr,
+ nullptr,nullptr,nullptr,
+ nullptr,nullptr,nullptr
+ };
+
+ MatchedCHPAction* chp_matches[NUMBER_OF_PTYPES] =
+ {
+ nullptr,nullptr,nullptr,
+ nullptr,nullptr,nullptr,
+ nullptr,nullptr,nullptr
+ };
+
+ if (http_session->chp_hold_flow)
+ http_session->chp_finished = 0;
+
+ if (!http_session->chp_candidate)
+ {
+ // remove artifacts from previous matches before we start again.
+ for (i = 0; i < NUMBER_OF_PTYPES; i++)
+ {
+ if (http_session->new_field[i])
+ {
+ snort_free(http_session->new_field[i]);
+ http_session->new_field[i] = nullptr;
+ }
+ }
+
+ if (!initial_CHP_sweep(chp_buffers, chp_matches, &pConfig->detectorHttpConfig))
+ http_session->chp_finished = 1; // this is a failure case.
+ }
+ if (!http_session->chp_finished && http_session->chp_candidate)
+ {
+ for (i = 0; i < NUMBER_OF_PTYPES; i++)
+ {
+ if (ptype_scan_counts[i] && chp_buffers[i] && (size = strlen(chp_buffers[i])) > 0)
+ {
+ found_in_buffer = 0;
+ ret = scanCHP((PatternType)i, chp_buffers[i], size, chp_matches[i], version,
+ &user, &chp_rewritten[i], &found_in_buffer,
+ http_session, p, &pConfig->detectorHttpConfig);
+ chp_matches[i] = nullptr; // freed by scanCHP()
+ http_session->total_found += found_in_buffer;
+ http_session->num_scans--;
+ ptype_scan_counts[i] = 0;
+ // Give up if scanCHP returns nothing, OR
+ // (if we did not match the right numbher of patterns in this field AND EITHER
+ // (there is no match quota [all must match]) OR
+ // (the total number of matches is less than our match quota))
+ if (!ret ||
+ (found_in_buffer < http_session->ptype_req_counts[i] &&
+ (!http_session->num_matches ||
+ http_session->total_found < http_session->num_matches)))
+ {
+ http_session->chp_candidate = 0;
+ break;
+ }
+ /* We are finished if we have a num_matches target and we've met it or
+ if we have done all the scans */
+ if (!http_session->num_scans ||
+ (http_session->num_matches && http_session->total_found >=
+ http_session->num_matches))
+ {
+ http_session->chp_finished = 1;
+ break;
+ }
+ }
+ else if (ptype_scan_counts[i] && !http_session->chp_hold_flow)
+ {
+ /* we have a scan count, but nothing in the buffer, so we should drop out of CHP */
+ http_session->chp_candidate = 0;
+ break;
+ }
+ }
+ if (!http_session->chp_candidate)
+ {
+ http_session->chp_finished = 1;
+ if (*version)
+ {
+ snort_free(*version);
+ *version = nullptr;
+ }
+ if (user)
+ {
+ snort_free(user);
+ user = nullptr;
+ }
+ for (i = 0; i < NUMBER_OF_PTYPES; i++)
+ {
+ if (nullptr != chp_rewritten[i])
+ {
+ snort_free(chp_rewritten[i]);
+ chp_rewritten[i] = nullptr;
+ }
+ }
+ memset(ptype_scan_counts, 0, 7 * sizeof(ptype_scan_counts[0]));
+
+ // Make it possible for other detectors to run.
+ http_session->skip_simple_detect = false;
+ return;
+ }
+ if (http_session->chp_candidate && http_session->chp_finished)
+ {
+ chp_final = http_session->chp_alt_candidate ?
+ http_session->chp_alt_candidate :
+ http_session->chp_candidate >> CHP_APPID_BITS_FOR_INSTANCE; // transform the
+ // instance into the
+ // appId.
+ if (http_session->app_type_flags & APP_TYPE_SERVICE)
+ {
+ set_service_appid_data(chp_final, nullptr, version);
+ }
+
+ if (http_session->app_type_flags & APP_TYPE_CLIENT)
+ {
+ set_client_app_id_data(chp_final, version);
+ }
+
+ if (http_session->app_type_flags & APP_TYPE_PAYLOAD)
+ {
+ set_payload_app_id_data((ApplicationId)chp_final, version);
+ }
+
+ if (http_session->fflow && http_session->fflow->flow_prepared)
+ {
+ finalizeFflow(http_session->fflow, http_session->app_type_flags,
+ (http_session->fflow->appId ? http_session->fflow->appId : chp_final), p);
+ snort_free(http_session->fflow);
+ http_session->fflow = nullptr;
+ }
+ if (*version)
+ *version = nullptr;
+ if (user)
+ {
+ username = user;
+ user = nullptr;
+ if (http_session->app_type_flags & APP_TYPE_SERVICE)
+ username_service = chp_final;
+ else
+ username_service = serviceAppId;
+ setAppIdFlag(APPID_SESSION_LOGIN_SUCCEEDED);
+ }
+ for (i = 0; i < NUMBER_OF_PTYPES; i++)
+ {
+ if (nullptr != chp_rewritten[i])
+ {
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s rewritten %s: %s\n", app_id_debug_session,
+ httpFieldName[i], chp_rewritten[i]);
+ if (http_session->new_field[i])
+ snort_free(http_session->new_field[i]);
+ http_session->new_field[i] = chp_rewritten[i];
+ chp_rewritten[i] = nullptr;
+ }
+ }
+ http_session->chp_candidate = 0;
+ //if we're doing safesearch rewrites, we want to continue to hold the flow
+ if (!http_session->get_offsets_from_rebuilt)
+ http_session->chp_hold_flow = 0;
+ scan_flags &= ~SCAN_HTTP_VIA_FLAG;
+ scan_flags &= ~SCAN_HTTP_USER_AGENT_FLAG;
+ scan_flags &= ~SCAN_HTTP_HOST_URL_FLAG;
+ memset(ptype_scan_counts, 0, 7 * sizeof(ptype_scan_counts[0]));
+ }
+ else /* if we have a candidate, but we're not finished */
+ {
+ if (user)
+ {
+ snort_free(user);
+ user = nullptr;
+ }
+ for (i = 0; i < NUMBER_OF_PTYPES; i++)
+ {
+ if (nullptr != chp_rewritten[i])
+ {
+ snort_free(chp_rewritten[i]);
+ chp_rewritten[i] = nullptr;
+ }
+ }
+ }
+ }
+}
+
+bool AppIdSession::is_payload_appid_set()
+{
+ return ( payload_app_id || tp_payload_app_id );
+}
+
+void AppIdSession::clearMiscHttpFlags()
+{
+ if (!getAppIdFlag(APPID_SESSION_SPDY_SESSION))
+ {
+ clearAppIdFlag(APPID_SESSION_CHP_INSPECTING);
+ if (thirdparty_appid_module)
+ thirdparty_appid_module->session_attr_clear(tpsession,
+ TP_ATTR_CONTINUE_MONITORING);
+ }
+}
+
+void AppIdSession::pickHttpXffAddress(Packet*, ThirdPartyAppIDAttributeData* attribute_data)
+{
+ int i;
+ static const char* defaultXffPrecedence[] =
+ {
+ HTTP_XFF_FIELD_X_FORWARDED_FOR,
+ HTTP_XFF_FIELD_TRUE_CLIENT_IP
+ };
+
+ // XFF precedence configuration cannot change for a session. Do not get it again if we already
+ // got it.
+// FIXIT-M:
+#ifdef REMOVED_WHILE_NOT_IN_USE
+ if (!hsession->xffPrecedence)
+ hsession->xffPrecedence = _dpd.sessionAPI->get_http_xff_precedence(
+ p->flow, p->packet_flags, &hsession->numXffFields);
+#endif
+
+ if (!hsession->xffPrecedence)
+ {
+ hsession->xffPrecedence = defaultXffPrecedence;
+ hsession->numXffFields = sizeof(defaultXffPrecedence) /
+ sizeof(defaultXffPrecedence[0]);
+ }
+
+ if (app_id_debug_session_flag)
+ {
+ for (i = 0; i < attribute_data->numXffFields; i++)
+ LogMessage("AppIdDbg %s %s : %s\n", app_id_debug_session,
+ attribute_data->xffFieldValue[i].field, attribute_data->xffFieldValue[i].value);
+ }
+
+ // xffPrecedence array is sorted based on precedence
+ for (i = 0; (i < hsession->numXffFields) &&
+ hsession->xffPrecedence[i]; i++)
+ {
+ int j;
+ for (j = 0; j < attribute_data->numXffFields; j++)
+ {
+ if (hsession->xffAddr)
+ sfip_free(hsession->xffAddr);
+
+ if (strncasecmp(attribute_data->xffFieldValue[j].field,
+ hsession->xffPrecedence[i], UINT8_MAX) == 0)
+ {
+ char* tmp = strchr(attribute_data->xffFieldValue[j].value, ',');
+ SFIP_RET status;
+
+ if (!tmp)
+ {
+ hsession->xffAddr = sfip_alloc(
+ attribute_data->xffFieldValue[j].value, &status);
+ }
+ // For a comma-separated list of addresses, pick the first address
+ else
+ {
+ attribute_data->xffFieldValue[j].value[tmp -
+ attribute_data->xffFieldValue[j].value] = '\0';
+ hsession->xffAddr = sfip_alloc(
+ attribute_data->xffFieldValue[j].value, &status);
+ }
+ break;
+ }
+ }
+ if (hsession->xffAddr)
+ break;
+ }
+}
+
+int AppIdSession::processHTTPPacket(Packet* p, int direction, HttpParsedHeaders* const, const AppIdConfig* pConfig)
+{
+ Profile http_profile_context(httpPerfStats);
+ constexpr auto RESPONSE_CODE_LENGTH = 3;
+ HeaderMatchedPatterns hmp;
+ httpSession* http_session;
+ int start, end, size;
+ char* version = nullptr;
+ char* vendorVersion = nullptr;
+ char* vendor = nullptr;
+ AppId service_id = 0;
+ AppId client_id = 0;
+ AppId payload_id = 0;
+ AppId referredPayloadAppId = 0;
+ char* host;
+ char* url;
+ char* useragent;
+ char* referer;
+ char* via;
+ AppInfoTableEntry* entry;
+
+ http_session = hsession;
+ if (!http_session)
+ {
+ clear_app_id_data();
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s attempt to process HTTP packet with no HTTP data\n",
+ app_id_debug_session);
+
+ return 0;
+ }
+
+ // 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 ((!http_session->useragent) && (!http_session->host) && (!http_session->referer) &&
+ (!http_session->uri))
+ {
+ if (!http_session->skip_simple_detect)
+ clearMiscHttpFlags();
+
+ return 0;
+ }
+
+ if (direction == APP_ID_FROM_RESPONDER && !getAppIdFlag(
+ APPID_SESSION_RESPONSE_CODE_CHECKED))
+ {
+ if (http_session->response_code)
+ {
+ setAppIdFlag(APPID_SESSION_RESPONSE_CODE_CHECKED);
+ if (strlen(http_session->response_code) != RESPONSE_CODE_LENGTH)
+ {
+ /* received bad response code. Stop processing this session */
+ clear_app_id_data();
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s bad http response code\n", app_id_debug_session);
+
+ return 0;
+ }
+ }
+#if RESPONSE_CODE_PACKET_THRESHHOLD
+ else if (++(http_session->response_code_packets) == RESPONSE_CODE_PACKET_THRESHHOLD)
+ {
+ setAppIdFlag(APPID_SESSION_RESPONSE_CODE_CHECKED);
+ /* didn't receive response code in first X packets. Stop processing this session */
+ clear_app_id_data(session);
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s no response code received\n", app_id_debug_session);
+ PREPROC_PROFILE_END(httpPerfStats);
+ return 0;
+ }
+#endif
+ }
+ host = http_session->host;
+ url = http_session->url;
+ via = http_session->via;
+ useragent = http_session->useragent;
+ referer = http_session->referer;
+ memset(&hmp, 0, sizeof(hmp));
+
+ if (serviceAppId == APP_ID_NONE)
+ {
+ serviceAppId = APP_ID_HTTP;
+ if (pAppidActiveConfig->mod_config->instance_id)
+ checkSandboxDetection(APP_ID_HTTP);
+ }
+
+ if (app_id_debug_session_flag)
+ LogMessage("AppIdDbg %s chp_finished %d chp_hold_flow %d\n", app_id_debug_session,
+ http_session->chp_finished, http_session->chp_hold_flow);
+
+ if (!http_session->chp_finished || http_session->chp_hold_flow)
+ processCHP(&version, p, pConfig);
+
+ if (!http_session->skip_simple_detect) // false unless a match happened with a call to
+ // processCHP().
+ {
+ if (!getAppIdFlag(APPID_SESSION_APP_REINSPECT))
+ {
+ // Scan Server Header for Vendor & Version
+ if ((thirdparty_appid_module && (scan_flags & SCAN_HTTP_VENDOR_FLAG) &&
+ hsession->server) ||
+ (!thirdparty_appid_module && getHTTPHeaderLocation(p->data, p->dsize,
+ HTTP_ID_SERVER, &start, &end, &hmp, &pConfig->detectorHttpConfig) == 1))
+ {
+ if (serviceAppId == APP_ID_NONE || serviceAppId == APP_ID_HTTP)
+ {
+ RNAServiceSubtype* subtype = nullptr;
+ RNAServiceSubtype** tmpSubtype;
+
+ if (thirdparty_appid_module)
+ getServerVendorVersion((uint8_t*)hsession->server,
+ strlen(hsession->server), &vendorVersion, &vendor, &subtype);
+ else
+ getServerVendorVersion(p->data + start, end - start, &vendorVersion,
+ &vendor, &subtype);
+ if (vendor || vendorVersion)
+ {
+ if (serviceVendor)
+ {
+ snort_free(serviceVendor);
+ serviceVendor = nullptr;
+ }
+ if (serviceVersion)
+ {
+ snort_free(serviceVersion);
+ serviceVersion = nullptr;
+ }
+ if (vendor)
+ serviceVendor = vendor;
+ if (vendorVersion)
+ serviceVersion = vendorVersion;
+ scan_flags &= ~SCAN_HTTP_VENDOR_FLAG;
+ }
+ if (subtype)
+ {
+ for (tmpSubtype = &subtype; *tmpSubtype; tmpSubtype =
+ &(*tmpSubtype)->next)
+ ;
+
+ *tmpSubtype = subtype;
+ }
+ }
+ }
+
+ if (webdav_found(&hmp))
+ {
+ if (app_id_debug_session_flag && payload_id > APP_ID_NONE &&
+ payload_app_id != payload_id)
+ LogMessage("AppIdDbg %s data is webdav\n", app_id_debug_session);
+ set_payload_app_id_data(APP_ID_WEBDAV, nullptr);
+ }
+
+ // Scan User-Agent for Browser types or Skype
+ if ((scan_flags & SCAN_HTTP_USER_AGENT_FLAG) && client_app_id <= APP_ID_NONE
+ && useragent && (size = strlen(useragent)) > 0)
+ {
+ if (version)
+ {
+ snort_free(version);
+ version = nullptr;
+ }
+ identifyUserAgent((uint8_t*)useragent, size, &service_id, &client_id, &version,
+ &pConfig->detectorHttpConfig);
+ if (app_id_debug_session_flag && service_id > APP_ID_NONE && service_id !=
+ APP_ID_HTTP && serviceAppId != service_id)
+ LogMessage("AppIdDbg %s User Agent is service %d\n", app_id_debug_session,
+ service_id);
+ set_service_appid_data(service_id, nullptr, nullptr);
+ if (app_id_debug_session_flag && client_id > APP_ID_NONE && client_id !=
+ APP_ID_HTTP && client_app_id != client_id)
+ LogMessage("AppIdDbg %s User Agent is client %d\n", app_id_debug_session,
+ client_id);
+ set_client_app_id_data(client_id, &version);
+ scan_flags &= ~SCAN_HTTP_USER_AGENT_FLAG;
+ }
+
+ /* Scan Via Header for squid */
+ if (!is_payload_appid_set() && (scan_flags & SCAN_HTTP_VIA_FLAG) && via &&
+ (size = strlen(via)) > 0)
+ {
+ if (version)
+ {
+ snort_free(version);
+ version = nullptr;
+ }
+ payload_id = geAppidByViaPattern((uint8_t*)via, size, &version,
+ &pConfig->detectorHttpConfig);
+ if (app_id_debug_session_flag && payload_id > APP_ID_NONE &&
+ payload_app_id != payload_id)
+ LogMessage("AppIdDbg %s VIA is data %d\n", app_id_debug_session,
+ payload_id);
+ set_payload_app_id_data((ApplicationId)payload_id, nullptr);
+ scan_flags &= ~SCAN_HTTP_VIA_FLAG;
+ }
+ }
+
+ /* Scan X-Working-With HTTP header */
+ if ((thirdparty_appid_module && (scan_flags & SCAN_HTTP_XWORKINGWITH_FLAG) &&
+ hsession->x_working_with) ||
+ (!thirdparty_appid_module && getHTTPHeaderLocation(p->data, p->dsize,
+ HTTP_ID_X_WORKING_WITH, &start, &end, &hmp, &pConfig->detectorHttpConfig) == 1))
+ {
+ AppId appId;
+
+ if (thirdparty_appid_module)
+ appId = scan_header_x_working_with((uint8_t*)hsession->x_working_with,
+ strlen(hsession->x_working_with), &version);
+ else
+ appId = scan_header_x_working_with(p->data + start, end - start, &version);
+
+ if (appId)
+ {
+ if (direction == APP_ID_FROM_INITIATOR)
+ {
+ if (app_id_debug_session_flag && client_id > APP_ID_NONE && client_id !=
+ APP_ID_HTTP && client_app_id != client_id)
+ LogMessage("AppIdDbg %s X is client %d\n", app_id_debug_session, appId);
+ set_client_app_id_data(appId, &version);
+ }
+ else
+ {
+ if (app_id_debug_session_flag && service_id > APP_ID_NONE && service_id !=
+ APP_ID_HTTP && serviceAppId != service_id)
+ LogMessage("AppIdDbg %s X is service %d\n", app_id_debug_session, appId);
+ set_service_appid_data(appId, nullptr, &version);
+ }
+ scan_flags &= ~SCAN_HTTP_XWORKINGWITH_FLAG;
+ }
+ }
+
+ // Scan Content-Type Header for multimedia types and scan contents
+ if ((thirdparty_appid_module && (scan_flags & SCAN_HTTP_CONTENT_TYPE_FLAG)
+ && hsession->content_type && !is_payload_appid_set()) ||
+ (!thirdparty_appid_module && !is_payload_appid_set() &&
+ getHTTPHeaderLocation(p->data, p->dsize, HTTP_ID_CONTENT_TYPE, &start, &end,
+ &hmp, &pConfig->detectorHttpConfig) == 1))
+ {
+ if (thirdparty_appid_module)
+ payload_id = geAppidByContentType((uint8_t*)hsession->content_type,
+ strlen(hsession->content_type), &pConfig->detectorHttpConfig);
+ else
+ payload_id = geAppidByContentType(p->data + start, end - start,
+ &pConfig->detectorHttpConfig);
+ if (app_id_debug_session_flag && payload_id > APP_ID_NONE
+ && payload_app_id != payload_id)
+ LogMessage("AppIdDbg %s Content-Type is data %d\n", app_id_debug_session,
+ payload_id);
+ set_payload_app_id_data((ApplicationId)payload_id, nullptr);
+ scan_flags &= ~SCAN_HTTP_CONTENT_TYPE_FLAG;
+ }
+
+ if (scan_flags & SCAN_HTTP_HOST_URL_FLAG)
+ {
+ if (version)
+ {
+ snort_free(version);
+ version = nullptr;
+ }
+ if (getAppIdFromUrl(host, url, &version, referer, &client_id, &service_id,
+ &payload_id, &referredPayloadAppId, 0, &pConfig->detectorHttpConfig) == 1)
+ {
+ // do not overwrite a previously-set client or service
+ if (client_app_id <= APP_ID_NONE)
+ {
+ if (app_id_debug_session_flag && client_id > APP_ID_NONE && client_id !=
+ APP_ID_HTTP && client_app_id != client_id)
+ LogMessage("AppIdDbg %s URL is client %d\n", app_id_debug_session,
+ client_id);
+ set_client_app_id_data(client_id, nullptr);
+ }
+ if (serviceAppId <= APP_ID_NONE)
+ {
+ if (app_id_debug_session_flag && service_id > APP_ID_NONE && service_id !=
+ APP_ID_HTTP && serviceAppId != service_id)
+ LogMessage("AppIdDbg %s URL is service %d\n", app_id_debug_session,
+ service_id);
+ set_service_appid_data(service_id, nullptr, nullptr);
+ }
+ // DO overwrite a previously-set data
+ if (app_id_debug_session_flag && payload_id > APP_ID_NONE &&
+ payload_app_id != payload_id)
+ LogMessage("AppIdDbg %s URL is data %d\n", app_id_debug_session, payload_id);
+ set_payload_app_id_data((ApplicationId)payload_app_id, &version);
+ set_referred_payload_app_id_data(referredPayloadAppId);
+ }
+ scan_flags &= ~SCAN_HTTP_HOST_URL_FLAG;
+ }
+
+ if (client_app_id == APP_ID_APPLE_CORE_MEDIA)
+ {
+ if (tp_payload_app_id > APP_ID_NONE)
+ {
+ entry = appInfoEntryGet(tp_payload_app_id, pConfig);
+ // only move tpPayloadAppId to client if its got a clientAppId
+ if (entry->clientId > APP_ID_NONE)
+ {
+ misc_app_id = client_app_id;
+ client_app_id = tp_payload_app_id;
+ }
+ }
+ else if (payload_app_id > APP_ID_NONE)
+ {
+ entry = appInfoEntryGet(payload_app_id, pConfig);
+ // only move payloadAppId to client if it has a ClientAppid
+ if (entry->clientId > APP_ID_NONE)
+ {
+ misc_app_id = client_app_id;
+ client_app_id = payload_app_id;
+ }
+ }
+ }
+
+ clearMiscHttpFlags();
+ } // end DON'T skip_simple_detect
+
+ return 0;
+}
+#endif
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//--------------------------------------------------------------------------
-// appid_flow_data.h author Sourcefire Inc.
+// appid_session.h author Sourcefire Inc.
#ifndef APPID_SESSION_H
#define APPID_SESSION_H
#include "service_state.h"
#include "thirdparty_appid_api.h"
#include "thirdparty_appid_types.h"
+#include "http_common.h"
+
+#define MAX_ATTR_LEN 1024
+#define HTTP_PREFIX "http://"
#define SF_DEBUG_FILE stdout
#define NUMBER_OF_PTYPES 9
RNA_STATE_FINISHED
};
-using AppIdFreeFCN = void(*)(void*);
-
-#define FINGERPRINT_UDP_FLAGS_XENIX 0x00000800
-#define FINGERPRINT_UDP_FLAGS_NT 0x00001000
-#define FINGERPRINT_UDP_FLAGS_MASK (FINGERPRINT_UDP_FLAGS_XENIX | FINGERPRINT_UDP_FLAGS_NT)
-
struct AppIdFlowData
{
AppIdFlowData* next;
int tls_orgUnit_strlen;
};
-class AppIdData : public FlowData
-{
-public:
- AppIdData() : FlowData(flow_id) { service_ip.clear(); }
- ~AppIdData();
+extern char app_id_debug_session[];
+extern bool app_id_debug_session_flag;
- void reset()
- { *this = AppIdData(); }
+/* The UNSYNCED_SNORT_ID value is to cheaply insure we get
+ the value from snort rather than assume */
+#define UNSYNCED_SNORT_ID 0x5555
+void map_app_names_to_snort_ids();
+class AppIdSession : public FlowData
+{
+public:
+ AppIdSession(IpProtocol proto, const sfip_t* ip);
+ ~AppIdSession();
+
+ static AppIdSession* allocate_session(const Packet*, IpProtocol, int);
+ static AppIdSession* create_future_session(const Packet*, const sfip_t*, uint16_t, const sfip_t*,
+ uint16_t, IpProtocol, int16_t, int);
+ static void do_application_discovery(Packet*);
+
+private:
+ bool do_client_discovery(int, Packet*);
+ bool do_service_discovery(IpProtocol, int, AppId, AppId, Packet*);
+ int exec_client_detectors(Packet*, int, AppIdConfig*);
+
+ static uint64_t is_session_monitored(const Packet*, int, AppIdSession*);
+ static bool is_packet_ignored(Packet* p);
+ bool is_payload_appid_set();
+ void clear_app_id_data();
+ void reinit_shared_data();
+ bool is_ssl_decryption_enabled();
+ void check_app_detection_restart();
+ void update_encrypted_app_id(AppId serviceAppId);
+ void sync_with_snort_id(AppId, Packet*, AppIdConfig*);
+ void examine_ssl_metadata(Packet*, AppIdConfig*);
+ void examine_rtmp_metadata();
+ void set_client_app_id_data(AppId clientAppId, char** version);
+ void set_service_appid_data( AppId, char*, char**);
+ void set_referred_payload_app_id_data( AppId);
+ void set_payload_app_id_data( ApplicationId, char**);
+ void stop_rna_service_inspection(Packet*, int);
+
+#ifdef REMOVED_WHILE_NOT_IN_USE
+ // FIXIT-M: these are not needed until appid for snort3 supports 3rd party detectors (e.g. NAVL)
+ void ProcessThirdPartyResults(Packet*, int, AppId*, ThirdPartyAppIDAttributeData*);
+ void checkTerminateTpModule(uint16_t tpPktCount);
+ bool do_third_party_discovery(IpProtocol, const sfip_t*, Packet*, int&);
+
+ // FIXIT-H: when http detection is made functional we need to look at these methods and determine if they are
+ // needed and what changes are required for snort3
+ void pickHttpXffAddress(Packet*, ThirdPartyAppIDAttributeData*);
+ int initial_CHP_sweep(char**, MatchedCHPAction**, const DetectorHttpConfig*);
+ void clearMiscHttpFlags();
+ int processHTTPPacket(Packet*, int, HttpParsedHeaders* const, const AppIdConfig*);
+ void processCHP(char**, Packet*, const AppIdConfig*);
+#endif
+
+public:
CommonAppIdData common;
- AppIdData* next = nullptr;
- Flow* ssn = nullptr;
+ AppIdSession* next = nullptr;
+ Flow* flow = nullptr;
sfip_t service_ip;
uint16_t service_port = 0;
- IpProtocol proto = IpProtocol::PROTO_NOT_SET;
+ IpProtocol protocol = IpProtocol::PROTO_NOT_SET;
uint8_t previous_tcp_flags = 0;
AppIdFlowData* flowData = nullptr;
int got_incompatible_services = 0;
/**AppId matching client side */
- AppId ClientAppId = APP_ID_NONE;
- AppId ClientServiceAppId = APP_ID_NONE;
- char* clientVersion = nullptr;
+ AppId client_app_id = APP_ID_NONE;
+ AppId client_service_app_id = APP_ID_NONE;
+ char* client_version = nullptr;
/**RNAClientAppModule for identifying client detector*/
- const RNAClientAppModule* clientData = nullptr;
- RNA_INSPECTION_STATE rnaClientState = RNA_STATE_NONE;
+ const RNAClientAppModule* rna_client_data = nullptr;
+ RNA_INSPECTION_STATE rna_client_state = RNA_STATE_NONE;
SF_LIST* candidate_client_list = nullptr;
unsigned int num_candidate_clients_tried = 0;
bool tried_reverse_service = false;
/**AppId matching payload*/
- AppId payloadAppId = APP_ID_NONE;
- AppId referredPayloadAppId = APP_ID_NONE;
- AppId miscAppId = APP_ID_NONE;
+ AppId payload_app_id = APP_ID_NONE;
+ AppId referred_payload_app_id = APP_ID_NONE;
+ AppId misc_app_id = APP_ID_NONE;
//appId determined by 3rd party library
- AppId tpAppId = APP_ID_NONE;
- AppId tpPayloadAppId = APP_ID_NONE;
+ AppId tp_app_id = APP_ID_NONE;
+ AppId tp_payload_app_id = APP_ID_NONE;
char* username = nullptr;
- AppId usernameService = APP_ID_NONE;
-
- char* netbiosDomain = nullptr;
-
+ AppId username_service = APP_ID_NONE;
+ char* netbios_domain = nullptr;
uint32_t id = 0;
-
httpSession* hsession = nullptr;
tlsSession* tsession = nullptr;
-
unsigned scan_flags = 0;
-#if RESPONSE_CODE_PACKET_THRESHHOLD
- unsigned response_code_packets = 0;
-#endif
-
AppId referredAppId = APP_ID_NONE;
-
- AppId tmpAppId = APP_ID_NONE;
+ AppId temp_app_id = APP_ID_NONE;
void* tpsession = nullptr;
uint16_t init_tpPackets = 0;
uint16_t resp_tpPackets = 0;
- uint8_t tpReinspectByInitiator = 0;
- char* payloadVersion = nullptr;
-
+ uint8_t tp_reinspect_by_initiator = 0;
+ char* payload_version = nullptr;
uint16_t session_packet_count = 0;
- int16_t snortId = 0;
+ int16_t snort_id = UNSYNCED_SNORT_ID;
/* Length-based detectors. */
LengthKey length_sequence;
} stats = {0, 0, 0, 0};
// Policy and rule ID for related flows (e.g. ftp-data)
- AppIdData* expectedFlow = nullptr;
+ AppIdSession* expectedFlow = nullptr;
//appIds picked from encrypted session.
struct
static unsigned flow_id;
static void init() { flow_id = FlowData::get_flow_id(); }
- void appHttpFieldClear();
- void appHttpSessionDataFree();
- void appDNSSessionDataFree();
- void appTlsSessionDataFree();
- void AppIdFlowdataFree();
- void appSharedDataDelete();
-};
-
-inline void setAppIdFlag(AppIdData* flow, uint64_t flags)
-{ flow->common.flags |= flags; }
-
-inline void clearAppIdFlag(AppIdData* flow, uint64_t flags)
-{ flow->common.flags &= ~flags; }
+ void setAppIdFlag(uint64_t flags)
+ {
+ common.flags |= flags;
+ }
-inline uint64_t getAppIdFlag(AppIdData* flow, uint64_t flags)
-{ return (flow->common.flags & flags); }
+ void clearAppIdFlag(uint64_t flags)
+ {
+ common.flags &= ~flags;
+ }
-void AppIdFlowdataFini();
-void* AppIdFlowdataGet(AppIdData*, unsigned id);
-int AppIdFlowdataAdd(AppIdData*, void* data, unsigned id, AppIdFreeFCN);
-void* AppIdFlowdataRemove(AppIdData*, unsigned id);
-void AppIdFlowdataDelete(AppIdData*, unsigned id);
-void AppIdFlowdataDeleteAllByMask(AppIdData*, unsigned mask);
-AppIdData* AppIdEarlySessionCreate(AppIdData*, const Packet* ctrlPkt, const sfip_t* cliIp,
- uint16_t cliPort, const sfip_t* srvIp, uint16_t srvPort, IpProtocol proto, int16_t app_id, int flags);
-int AppIdFlowdataAddId(AppIdData*, uint16_t port, const RNAServiceElement*);
+ inline uint64_t getAppIdFlag(uint64_t flags)
+ {
+ return (common.flags & flags);
+ }
+
+ static void release_free_list_flow_data();
+ void* get_flow_data(unsigned id);
+ int add_flow_data(void* data, unsigned id, AppIdFreeFCN);
+ int add_flow_data_id(uint16_t port, const RNAServiceElement*);
+ void* remove_flow_data(unsigned id);
+ void free_flow_data_by_id(unsigned id);
+ void free_flow_data_by_mask(unsigned mask);
+
+ void clear_http_field();
+ void free_http_session_data();
+ void free_dns_session_data();
+ void free_tls_session_data();
+ void free_flow_data();
+ void delete_shared_data();
+
+ AppId is_appid_detection_done();
+ AppId pick_service_app_id();
+ AppId pick_only_service_app_id();
+ AppId pick_misc_app_id();
+ AppId pick_client_app_id();
+ AppId pick_payload_app_id();
+ AppId pick_referred_payload_app_id();
+ AppId fw_pick_service_app_id();
+ AppId fw_pick_misc_app_id();
+ AppId fw_pick_client_app_id();
+ AppId fw_pick_payload_app_id();
+ AppId fw_pick_referred_payload_app_id();
+ bool is_ssl_session_decrypted();
+};
#endif
#include "utils/util.h"
#include "appid_api.h"
-#include "appid_flow_data.h"
+#include "appid_session.h"
#include "fw_appid.h"
-#include "util/fw_avltree.h"
-#include "util/output_file.h"
+#include "appid_utils/fw_avltree.h"
+#include "appid_utils/output_file.h"
#define URLCATBUCKETS 100
#define URLREPBUCKETS 5
return now - (now % bucketInterval);
}
-void appIdStatsUpdate(AppIdData* session)
+void appIdStatsUpdate(AppIdSession* session)
{
if ( !enableAppStats )
return;
bucket->totalStats.txByteCnt += session->stats.initiatorBytes;
bucket->totalStats.rxByteCnt += session->stats.responderBytes;
- const uint32_t web_app_id = pickPayloadId(session);
+ const uint32_t web_app_id = session->pick_payload_app_id();
if (web_app_id > APP_ID_NONE)
{
const uint32_t app_id = web_app_id;
}
}
- const uint32_t service_app_id = pickServiceAppId(session);
+ const uint32_t service_app_id = session->pick_service_app_id();
if ((service_app_id) &&
(service_app_id != web_app_id))
{
}
}
- const uint32_t client_app_id = pickClientAppId(session);
+ const uint32_t client_app_id = session->pick_client_app_id();
if (client_app_id > APP_ID_NONE
&& client_app_id != service_app_id
&& client_app_id != web_app_id)
#ifndef APPID_STATS_H
#define APPID_STATS_H
-class AppIdData;
+class AppIdSession;
class AppIdModuleConfig;
-void appIdStatsUpdate(AppIdData*);
+void appIdStatsUpdate(AppIdSession*);
void appIdStatsInit(AppIdModuleConfig* config);
void appIdStatsReinit();
void appIdStatsIdleFlush();
static CLIENT_APP_RETCODE aim_init(const IniClientAppAPI* const, SF_LIST* config);
static CLIENT_APP_RETCODE aim_validate(
- const uint8_t* data, uint16_t size, const int dir, AppIdData*, Packet*,
+ const uint8_t* data, uint16_t size, const int dir, AppIdSession*, Packet*,
Detector*, const AppIdConfig*);
RNAClientAppModule aim_client_mod =
}
static CLIENT_APP_RETCODE aim_validate(
- const uint8_t* const data, uint16_t size, const int dir, AppIdData* flowp,
+ const uint8_t* const data, uint16_t size, const int dir, AppIdSession* flowp,
Packet*, Detector*, const AppIdConfig*)
{
if ( dir != APP_ID_FROM_INITIATOR )
return CLIENT_APP_INPROCESS;
bail:
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_DETECTED);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
return CLIENT_APP_SUCCESS;
}
#include <cstdint>
#include "appid_api.h"
-#include "appid_flow_data.h"
+#include "appid_session.h"
struct Packet;
struct Detector;
const uint8_t* data,
uint16_t size,
const int dir,
- AppIdData*,
+ AppIdSession*,
Packet*,
Detector*,
const AppIdConfig*
using RNAClientAppFinalizeFCN = CLIENT_APP_RETCODE (*)(const FinalizeClientAppAPI* const);
using RNAClientAppCleanFCN = void(*)(const CleanClientAppAPI* const);
-using ClientAppFlowdataGet = void*(*)(AppIdData*, unsigned);
-using ClientAppFlowdataAdd = int(*)(AppIdData*, void*, unsigned, AppIdFreeFCN);
-using ClientAppAddApp = void(*)(AppIdData*, AppId, AppId, const char*);
-using ClientAppAddInfo = void(*)(AppIdData*, const char*);
-using ClientAppAddUser = void(*)(AppIdData*, const char*, AppId, int);
-using ClientAppAddPayload = void(*)(AppIdData*, AppId);
+using ClientAppFlowdataGet = void*(*)(AppIdSession*, unsigned);
+using ClientAppFlowdataAdd = int(*)(AppIdSession*, void*, unsigned, AppIdFreeFCN);
+using ClientAppAddApp = void(*)(AppIdSession*, AppId, AppId, const char*);
+using ClientAppAddInfo = void(*)(AppIdSession*, const char*);
+using ClientAppAddUser = void(*)(AppIdSession*, const char*, AppId, int);
+using ClientAppAddPayload = void(*)(AppIdSession*, AppId);
struct ClientAppApi
{
* already exist). */
#define MAX_CANDIDATE_CLIENTS 10
-static void* client_app_flowdata_get(AppIdData* flowp, unsigned client_id);
-static int client_app_flowdata_add(AppIdData* flowp, void* data, unsigned client_id, AppIdFreeFCN
+static void* client_app_flowdata_get(AppIdSession* flowp, unsigned client_id);
+static int client_app_flowdata_add(AppIdSession* flowp, void* data, unsigned client_id, AppIdFreeFCN
fcn);
-static void AppIdAddClientAppInfo(AppIdData* flowp, const char* info);
+static void AppIdAddClientAppInfo(AppIdSession* flowp, const char* info);
static const ClientAppApi client_app_api =
{
/*static const char * const MODULE_NAME = "ClientApp"; */
+void appSetClientValidator(RNAClientAppFCN fcn, AppId appId, unsigned extractsInfo,
+ AppIdConfig* pConfig)
+{
+ AppInfoTableEntry* pEntry = appInfoEntryGet(appId, pConfig);
+ if (!pEntry)
+ {
+ ErrorMessage("AppId: invalid direct client application AppId: %d\n", appId);
+ return;
+ }
+ extractsInfo &= (APPINFO_FLAG_CLIENT_ADDITIONAL | APPINFO_FLAG_CLIENT_USER);
+ if (!extractsInfo)
+ {
+ DebugFormat(DEBUG_LOG,
+ "Ignoring direct client application without info for AppId: %d", appId);
+ return;
+ }
+ pEntry->clntValidator = ClientAppGetClientAppModule(fcn, nullptr, &pConfig->clientAppConfig);
+ if (pEntry->clntValidator)
+ pEntry->flags |= extractsInfo;
+ else
+ ErrorMessage("Appid: Failed to find a client application module for AppId: %d\n", appId);
+}
+
const ClientAppApi* getClientApi(void)
{
return &client_app_api;
if (pConfig->clientAppConfig.enabled)
{
- client_init_api.debug = app_id_debug;
+ client_init_api.debug = pAppidActiveConfig->mod_config->debug;
client_init_api.pAppidConfig = pConfig;
// FIXIT - active config global must go...
client_init_api.instance_id = pAppidActiveConfig->mod_config->instance_id;
return 0;
}
-void AppIdAddClientApp(AppIdData* flowp, AppId service_id, AppId id, const char* version)
+void AppIdAddClientApp(AppIdSession* flowp, AppId service_id, AppId id, const char* version)
{
if (version)
{
- if (flowp->clientVersion)
+ if (flowp->client_version)
{
- if (strcmp(version, flowp->clientVersion))
+ if (strcmp(version, flowp->client_version))
{
- snort_free(flowp->clientVersion);
- flowp->clientVersion = snort_strdup(version);
+ snort_free(flowp->client_version);
+ flowp->client_version = snort_strdup(version);
}
}
else
- flowp->clientVersion = snort_strdup(version);
+ flowp->client_version = snort_strdup(version);
}
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_DETECTED);
- flowp->ClientServiceAppId = service_id;
- flowp->ClientAppId = id;
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
+ flowp->client_service_app_id = service_id;
+ flowp->client_app_id = id;
checkSandboxDetection(id);
}
-static void AppIdAddClientAppInfo(AppIdData* flowp, const char* info)
+static void AppIdAddClientAppInfo(AppIdSession* flowp, const char* info)
{
if (flowp->hsession && !flowp->hsession->url)
flowp->hsession->url = snort_strdup(info);
*
* @param p packet to process
*/
-static void ClientAppID(Packet* p, const int /*direction*/, AppIdData* flowp, const
+static void ClientAppID(Packet* p, const int /*direction*/, AppIdSession* flowp, const
AppIdConfig* pConfig)
{
const RNAClientAppModule* client = nullptr;
if (!p->dsize)
return;
- if (flowp->clientData != nullptr)
+ if (flowp->rna_client_data != nullptr)
return;
if (flowp->candidate_client_list != nullptr)
flowp->num_candidate_clients_tried = 0;
}
- match_list = BuildClientPatternList(p, flowp->proto, &pConfig->clientAppConfig);
+ match_list = BuildClientPatternList(p, flowp->protocol, &pConfig->clientAppConfig);
while (flowp->num_candidate_clients_tried < MAX_CANDIDATE_CLIENTS)
{
const RNAClientAppModule* tmp = GetNextFromClientPatternList(&match_list);
switch (p->ptrs.dp)
{
case 465:
- if (getAppIdFlag(flowp, APPID_SESSION_DECRYPTED))
+ if (flowp->getAppIdFlag(APPID_SESSION_DECRYPTED))
client = &smtp_client_mod;
break;
default:
}
}
-int AppIdDiscoverClientApp(Packet* p, int direction, AppIdData* rnaData,
+int AppIdDiscoverClientApp(Packet* p, int direction, AppIdSession* rnaData,
const AppIdConfig* pConfig)
{
if (!pConfig->clientAppConfig.enabled)
if (direction == APP_ID_FROM_INITIATOR)
{
/* get out if we've already tried to validate a client app */
- if (!getAppIdFlag(rnaData, APPID_SESSION_CLIENT_DETECTED))
+ if (!rnaData->getAppIdFlag(APPID_SESSION_CLIENT_DETECTED))
ClientAppID(p, direction, rnaData, pConfig);
}
- else if (rnaData->rnaServiceState != RNA_STATE_STATEFUL && getAppIdFlag(rnaData,
- APPID_SESSION_CLIENT_GETS_SERVER_PACKETS))
+ else if ( rnaData->rnaServiceState != RNA_STATE_STATEFUL
+ && rnaData->getAppIdFlag(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS))
ClientAppID(p, direction, rnaData, pConfig);
return APPID_SESSION_SUCCESS;
return (&patternLists->appUrlList);
}
-static void* client_app_flowdata_get(AppIdData* flowp, unsigned client_id)
+static void* client_app_flowdata_get(AppIdSession* flowp, unsigned client_id)
{
- return AppIdFlowdataGet(flowp, client_id);
+ return flowp->get_flow_data(client_id);
}
-static int client_app_flowdata_add(AppIdData* flowp, void* data, unsigned client_id, AppIdFreeFCN
+static int client_app_flowdata_add(AppIdSession* flowp, void* data, unsigned client_id, AppIdFreeFCN
fcn)
{
- return AppIdFlowdataAdd(flowp, data, client_id, fcn);
+ return flowp->add_flow_data(data, client_id, fcn);
}
#define GENERIC_APP_OFFSET 2000000000
-class AppIdData;
+class AppIdSession;
class AppIdConfig;
struct Detector;
struct DetectorSipConfig;
void CleanupClientApp(AppIdConfig*);
int ClientAppLoadCallback(void* symbol);
int ClientAppLoadForConfigCallback(void* symbol, ClientAppConfig*);
+void appSetClientValidator(RNAClientAppFCN, AppId, unsigned extractsInfo, AppIdConfig*);
int LoadClientAppModules(AppIdConfig*);
void ClientAppRegisterPattern(RNAClientAppFCN, IpProtocol proto, const uint8_t* const pattern,
unsigned size, int position, unsigned nocase, Detector*, ClientAppConfig*);
const ClientAppApi* getClientApi();
RNAClientAppModuleConfig* getClientAppModuleConfig(const char* moduleName, ClientAppConfig*);
-int AppIdDiscoverClientApp(Packet* p, int direction, AppIdData*, const AppIdConfig*);
-void AppIdAddClientApp(AppIdData*, AppId service_id, AppId id, const char* version);
+int AppIdDiscoverClientApp(Packet* p, int direction, AppIdSession*, const AppIdConfig*);
+void AppIdAddClientApp(AppIdSession*, AppId service_id, AppId id, const char* version);
DetectorAppUrlList* getAppUrlList(AppIdConfig*);
const RNAClientAppModule* ClientAppGetClientAppModule(RNAClientAppFCN, Detector*,
ClientAppConfig*);
static CLIENT_APP_RETCODE bit_init(const IniClientAppAPI* const init_api, SF_LIST* config);
static CLIENT_APP_RETCODE bit_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet* pkt, struct Detector* userData,
+ AppIdSession* flowp, Packet* pkt, struct Detector* userData,
const AppIdConfig* pConfig);
SO_PUBLIC RNAClientAppModule bit_client_mod =
}
static CLIENT_APP_RETCODE bit_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet*, struct Detector*, const AppIdConfig*)
+ AppIdSession* flowp, Packet*, struct Detector*, const AppIdConfig*)
{
ClientBITData* fd;
uint16_t offset;
done:
bit_client_mod.api->add_app(flowp, APP_ID_BITTORRENT, APP_ID_BITTORRENT, nullptr);
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_DETECTED);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
appid_stats.bit_clients++;
return CLIENT_APP_SUCCESS;
}
static CLIENT_APP_RETCODE udp_bit_init(const IniClientAppAPI* const init_api, SF_LIST* config);
static CLIENT_APP_RETCODE udp_bit_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet* pkt, struct Detector* userData, const AppIdConfig* pConfig);
+ AppIdSession* flowp, Packet* pkt, struct Detector* userData, const AppIdConfig* pConfig);
SO_PUBLIC RNAClientAppModule bit_tracker_client_mod =
{
}
static CLIENT_APP_RETCODE udp_bit_validate(const uint8_t* data, uint16_t size, const int /*dir*/,
- AppIdData* flowp, Packet*, struct Detector*, const AppIdConfig*)
+ AppIdSession* flowp, Packet*, struct Detector*, const AppIdConfig*)
{
ClientBITData* fd;
uint16_t offset;
done:
bit_tracker_client_mod.api->add_app(flowp, APP_ID_BITTORRENT, APP_ID_BITTRACKER_CLIENT,
nullptr);
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_DETECTED);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
appid_stats.bittracker_clients++;
return CLIENT_APP_SUCCESS;
}
THREAD_LOCAL MSN_CLIENT_APP_CONFIG msn_config;
static CLIENT_APP_RETCODE msn_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet* pkt, struct Detector* userData, const AppIdConfig* pConfig);
+ AppIdSession* flowp, Packet* pkt, struct Detector* userData, const AppIdConfig* pConfig);
struct Client_App_Pattern
{
}
static CLIENT_APP_RETCODE msn_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet* pkt, struct Detector*, const AppIdConfig*)
+ AppIdSession* flowp, Packet* pkt, struct Detector*, const AppIdConfig*)
{
const u_int8_t* end;
u_int8_t version[MAX_VERSION_SIZE];
done:
msn_client_mod.api->add_app(flowp, APP_ID_MSN_MESSENGER, product_id, (char*)version);
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_DETECTED);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
return CLIENT_APP_SUCCESS;
}
static CLIENT_APP_RETCODE rtp_init(const IniClientAppAPI* const init_api, SF_LIST* config);
static CLIENT_APP_RETCODE rtp_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet* pkt, struct Detector* userData, const AppIdConfig* pConfig);
+ AppIdSession* flowp, Packet* pkt, struct Detector* userData, const AppIdConfig* pConfig);
SO_PUBLIC RNAClientAppModule rtp_client_mod =
{
}
static CLIENT_APP_RETCODE rtp_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet*, struct Detector*, const AppIdConfig*)
+ AppIdSession* flowp, Packet*, struct Detector*, const AppIdConfig*)
{
ClientRTPData* fd;
ClientRTPMsg* hdr;
}
rtp_client_mod.api->add_app(flowp, APP_ID_RTP, APP_ID_RTP, nullptr);
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_DETECTED);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
return CLIENT_APP_SUCCESS;
}
static CLIENT_APP_RETCODE smtp_init(const IniClientAppAPI* const init_api, SF_LIST* config);
static CLIENT_APP_RETCODE smtp_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet* pkt, struct Detector* userData, const AppIdConfig* pConfig);
+ AppIdSession* flowp, Packet* pkt, struct Detector* userData, const AppIdConfig* pConfig);
SO_PUBLIC RNAClientAppModule smtp_client_mod =
{
}
static int ExtractVersion(ClientSMTPData* const fd, const uint8_t* product,
- const uint8_t* data, AppIdData* flowp, Packet*)
+ const uint8_t* data, AppIdSession* flowp, Packet*)
{
const u_int8_t* p;
u_int8_t* v;
}
static CLIENT_APP_RETCODE smtp_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet* pkt, struct Detector*, const AppIdConfig*)
+ AppIdSession* flowp, Packet* pkt, struct Detector*, const AppIdConfig*)
{
ClientSMTPData* fd;
const uint8_t* end;
{
fd->flags &= ~(CLIENT_FLAG_STARTTLS_SENT);
fd->flags |= CLIENT_FLAG_SMTPS;
- clearAppIdFlag(flowp, APPID_SESSION_CLIENT_GETS_SERVER_PACKETS); // we no longer need
+ flowp->clearAppIdFlag(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS); // we no longer need
// to examine the
// response.
- if (!getAppIdFlag(flowp, APPID_SESSION_DECRYPTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_DECRYPTED))
{
/* Because we can't see any further info without decryption we settle for
plain APP_ID_SMTPS instead of perhaps finding data that would make calling
}
return CLIENT_APP_INPROCESS;
}
- if (getAppIdFlag(flowp, APPID_SESSION_ENCRYPTED))
+ if (flowp->getAppIdFlag(APPID_SESSION_ENCRYPTED))
{
- if (!getAppIdFlag(flowp, APPID_SESSION_DECRYPTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_DECRYPTED))
return CLIENT_APP_INPROCESS;
}
fd->pos = 0;
fd->nextstate = fd->state;
fd->state = SMTP_STATE_SKIP_LINE;
- setAppIdFlag(flowp, APPID_SESSION_ENCRYPTED);
+ flowp->setAppIdFlag(APPID_SESSION_ENCRYPTED);
}
}
else
return CLIENT_APP_INPROCESS;
done:
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_DETECTED);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
return CLIENT_APP_SUCCESS;
}
static CLIENT_APP_RETCODE ssh_client_init(const IniClientAppAPI* const init_api, SF_LIST* config);
static CLIENT_APP_RETCODE ssh_client_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet* pkt, struct Detector* userData,
+ AppIdSession* flowp, Packet* pkt, struct Detector* userData,
const AppIdConfig* pConfig);
SO_PUBLIC RNAClientAppModule ssh_client_mod =
}
static CLIENT_APP_RETCODE ssh_client_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet*, struct Detector*, const AppIdConfig*)
+ AppIdSession* flowp, Packet*, struct Detector*, const AppIdConfig*)
{
ClientSSHData* fd;
CLIENT_APP_RETCODE sm_ret;
return sm_ret;
ssh_client_mod.api->add_app(flowp, APP_ID_SSH, fd->client_id, (const char*)fd->version);
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_DETECTED);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
appid_stats.ssh_clients++;
return CLIENT_APP_SUCCESS;
}
static CLIENT_APP_RETCODE timbuktu_init(const IniClientAppAPI* const init_api, SF_LIST* config);
static CLIENT_APP_RETCODE timbuktu_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet* pkt, struct Detector* userData, const AppIdConfig* pConfig);
+ AppIdSession* flowp, Packet* pkt, struct Detector* userData, const AppIdConfig* pConfig);
SO_PUBLIC RNAClientAppModule timbuktu_client_mod =
{
}
static CLIENT_APP_RETCODE timbuktu_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet*, struct Detector*, const AppIdConfig*)
+ AppIdSession* flowp, Packet*, struct Detector*, const AppIdConfig*)
{
ClientTIMBUKTUData* fd;
uint16_t offset;
done:
timbuktu_client_mod.api->add_app(flowp, APP_ID_TIMBUKTU, APP_ID_TIMBUKTU, nullptr);
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_DETECTED);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
return CLIENT_APP_SUCCESS;
}
static CLIENT_APP_RETCODE tns_init(const IniClientAppAPI* const init_api, SF_LIST* config);
static CLIENT_APP_RETCODE tns_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet* pkt, struct Detector* userData, const AppIdConfig* pConfig);
+ AppIdSession* flowp, Packet* pkt, struct Detector* userData, const AppIdConfig* pConfig);
SO_PUBLIC RNAClientAppModule tns_client_mod =
{
#define TNS_MAX_INFO_SIZE 63
static CLIENT_APP_RETCODE tns_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet*, struct Detector*, const AppIdConfig*)
+ AppIdSession* flowp, Packet*, struct Detector*, const AppIdConfig*)
{
char username[TNS_MAX_INFO_SIZE+1];
ClientTNSData* fd;
username[user_size] = 0;
tns_client_mod.api->add_user(flowp, username, APP_ID_ORACLE_DATABASE, 1);
}
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_DETECTED);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
return CLIENT_APP_SUCCESS;
}
static CLIENT_APP_RETCODE vnc_init(const IniClientAppAPI* const init_api, SF_LIST* config);
static CLIENT_APP_RETCODE vnc_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet* pkt, struct Detector* userData,
+ AppIdSession* flowp, Packet* pkt, struct Detector* userData,
const AppIdConfig* pConfig);
SO_PUBLIC RNAClientAppModule vnc_client_mod =
}
static CLIENT_APP_RETCODE vnc_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet*, struct Detector*, const AppIdConfig*)
+ AppIdSession* flowp, Packet*, struct Detector*, const AppIdConfig*)
{
ClientVNCData* fd;
uint16_t offset;
done:
vnc_client_mod.api->add_app(flowp, APP_ID_VNC_RFB, APP_ID_VNC, (const char*)fd->version);
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_DETECTED);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
return CLIENT_APP_SUCCESS;
}
static CLIENT_APP_RETCODE ym_init(const IniClientAppAPI* const init_api, SF_LIST* config);
static CLIENT_APP_RETCODE ym_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet* pkt, struct Detector* userData, const AppIdConfig* pConfig);
+ AppIdSession* flowp, Packet* pkt, struct Detector* userData, const AppIdConfig* pConfig);
RNAClientAppModule ym_client_mod =
{
}
static CLIENT_APP_RETCODE ym_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet* pkt, Detector*, const AppIdConfig*)
+ AppIdSession* flowp, Packet* pkt, Detector*, const AppIdConfig*)
{
#define HEADERSIZE 20
#define VERSIONID "135"
done:
ym_client_mod.api->add_app(flowp, APP_ID_YAHOO, product_id, (char*)version);
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_DETECTED);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
return CLIENT_APP_SUCCESS;
}
#ifndef DETECTOR_API_H
#define DETECTOR_API_H
-#include "appid_flow_data.h"
+#include "appid_session.h"
struct RNAServiceValidationModule;
struct RNAClientAppModule;
-struct StreamAPI;
-using DetectorFlowdataGet = void*(*)(AppIdData*, unsigned);
-using DetectorFlowdataAdd = int(*)(AppIdData*, void*, unsigned, AppIdFreeFCN);
+using DetectorFlowdataGet = void*(*)(AppIdSession*, unsigned);
+using DetectorFlowdataAdd = int(*)(AppIdSession*, void*, unsigned, AppIdFreeFCN);
struct DetectorApi
{
const DetectorApi* api;
unsigned flow_data_index;
- StreamAPI* streamAPI;
};
#endif
#include "log/messages.h"
#include "service_plugins/service_base.h"
-static void* detector_flowdata_get(AppIdData* flowp, unsigned detector_id);
-static int detector_flowdata_add(AppIdData* flowp, void* data, unsigned detector_id,
+static void* detector_flowdata_get(AppIdSession* flowp, unsigned detector_id);
+static int detector_flowdata_add(AppIdSession* flowp, void* data, unsigned detector_id,
AppIdFreeFCN fcn);
static const DetectorApi detector_api
extern RNADetectorValidationModule imap_detector_mod;
extern RNADetectorValidationModule pop3_detector_mod;
extern RNADetectorValidationModule kerberos_detector_mod;
-extern RNADetectorValidationModule pattern_detector_mod;
static RNADetectorValidationModule* static_detector_list[]
{
svm->api = &detector_api;
svm->flow_data_index = detector_module_index | APPID_SESSION_DATA_DETECTOR_MODSTATE_BIT;
-// svm->streamAPI = _dpd.streamAPI; FIXIT - removed to permit compilation.
detector_module_index++;
return 0;
*
* @return RNA flow data structure for success
*/
-static void* detector_flowdata_get(AppIdData* flowp, unsigned detector_id)
+static void* detector_flowdata_get(AppIdSession* flowp, unsigned detector_id)
{
- return AppIdFlowdataGet(flowp, detector_id);
+ return flowp->get_flow_data(detector_id);
}
/**
*
* @return RNA flow data structure for success
*/
-static int detector_flowdata_add(AppIdData* flowp, void* data, unsigned detector_id,
+static int detector_flowdata_add(AppIdSession* flowp, void* data, unsigned detector_id,
AppIdFreeFCN fcn)
{
- return AppIdFlowdataAdd(flowp, data, detector_id, fcn);
+ return flowp->add_flow_data(data, detector_id, fcn);
}
#include "appid_module.h"
#include "app_info_table.h"
#include "application_ids.h"
-#include "dns_defs.h"
-
#include "client_plugins/client_app_api.h"
#include "service_plugins/service_api.h"
#include "service_plugins/service_config.h"
+#define MAX_OPCODE 5
+#define INVALID_OPCODE 3
+
+#define MAX_RCODE 10
+
+#define RCODE_NXDOMAIN 3
+
+#define DNS_LENGTH_FLAGS 0xC0
+
+#define PATTERN_A_REC 1
+#define PATTERN_AAAA_REC 28
+#define PATTERN_CNAME_REC 5
+#define PATTERN_SRV_REC 33
+#define PATTERN_TXT_REC 16
+#define PATTERN_MX_REC 15
+#define PATTERN_SOA_REC 6
+#define PATTERN_NS_REC 2
+#define PATTERN_PTR_REC 12
+
+#pragma pack(1)
+
+// FIXIT-H J bitfields should be replaced with getters/setters
+struct DNSHeader
+{
+ uint16_t id;
+#if defined(SF_BIGENDIAN)
+ uint8_t QR : 1,
+ Opcode : 4,
+ AA : 1,
+ TC : 1,
+ RD : 1;
+ uint8_t RA : 1,
+ Z : 1,
+ AD : 1,
+ CD : 1,
+ RCODE : 4;
+#else
+ uint8_t RD : 1,
+ TC : 1,
+ AA : 1,
+ Opcode : 4,
+ QR : 1;
+ uint8_t RCODE : 4,
+ CD : 1,
+ AD : 1,
+ Z : 1,
+ RA : 1;
+#endif
+ uint16_t QDCount;
+ uint16_t ANCount;
+ uint16_t NSCount;
+ uint16_t ARCount;
+};
+
+struct DNSTCPHeader
+{
+ uint16_t length;
+};
+
+struct DNSLabel
+{
+ uint8_t len;
+ uint8_t name;
+};
+
+struct DNSLabelPtr
+{
+ uint16_t position;
+ uint8_t data;
+};
+
+struct DNSLabelBitfield
+{
+ uint8_t id;
+ uint8_t len;
+ uint8_t data;
+};
+
+struct DNSQueryFixed
+{
+ uint16_t QType;
+ uint16_t QClass;
+};
+
+struct DNSAnswerData
+{
+ uint16_t type;
+ uint16_t klass;
+ uint32_t ttl;
+ uint16_t r_len;
+};
+
+#pragma pack()
+
enum DNSState
{
DNS_STATE_QUERY,
static CLIENT_APP_RETCODE dns_udp_client_init(const IniClientAppAPI* const, SF_LIST*);
static CLIENT_APP_RETCODE dns_tcp_client_init(const IniClientAppAPI* const, SF_LIST*);
static CLIENT_APP_RETCODE dns_udp_client_validate(
- const uint8_t*, uint16_t, const int, AppIdData*, Packet*, Detector*, const AppIdConfig*);
+ const uint8_t*, uint16_t, const int, AppIdSession*, Packet*, Detector*, const AppIdConfig*);
static CLIENT_APP_RETCODE dns_tcp_client_validate(
- const uint8_t*, uint16_t, const int, AppIdData*, Packet*, Detector*, const AppIdConfig*);
+ const uint8_t*, uint16_t, const int, AppIdSession*, Packet*, Detector*, const AppIdConfig*);
SO_PUBLIC RNAClientAppModule dns_udp_client_mod =
{
{ return CLIENT_APP_SUCCESS; }
static CLIENT_APP_RETCODE dns_udp_client_validate(
- const uint8_t*, uint16_t, const int, AppIdData*, Packet*, Detector*, const AppIdConfig*)
+ const uint8_t*, uint16_t, const int, AppIdSession*, Packet*, Detector*, const AppIdConfig*)
{ return CLIENT_APP_INPROCESS; }
static CLIENT_APP_RETCODE dns_tcp_client_validate(
- const uint8_t*, uint16_t, const int, AppIdData*, Packet*, Detector*, const AppIdConfig*)
+ const uint8_t*, uint16_t, const int, AppIdSession*, Packet*, Detector*, const AppIdConfig*)
{ return CLIENT_APP_INPROCESS; }
static int dns_host_pattern_match(void* id, void*, int index, void* data, void*)
}
static int dns_validate_query(const uint8_t* data, uint16_t* offset, uint16_t size,
- uint16_t id, unsigned host_reporting, AppIdData* flowp)
+ uint16_t id, unsigned host_reporting, AppIdSession* flowp)
{
int ret;
const uint8_t* host;
}
static int dns_validate_answer(const uint8_t* data, uint16_t* offset, uint16_t size,
- uint16_t id, uint8_t rcode, unsigned host_reporting, AppIdData* flowp)
+ uint16_t id, uint8_t rcode, unsigned host_reporting, AppIdSession* flowp)
{
int ret;
const uint8_t* host;
}
static int dns_validate_header(const int dir, DNSHeader* hdr,
- unsigned host_reporting, AppIdData* flowp)
+ unsigned host_reporting, AppIdSession* flowp)
{
if (hdr->Opcode > MAX_OPCODE || hdr->Opcode == INVALID_OPCODE)
{
}
static int validate_packet(const uint8_t* data, uint16_t size, const int,
- unsigned host_reporting, AppIdData* flowp)
+ unsigned host_reporting, AppIdSession* flowp)
{
uint16_t i;
uint16_t count;
static int dns_udp_validate(ServiceValidationArgs* args)
{
int rval;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
const int dir = args->dir;
uint16_t size = args->size;
{
if (dir == APP_ID_FROM_RESPONDER)
{
- if (getAppIdFlag(flowp, APPID_SESSION_UDP_REVERSED))
+ if (flowp->getAppIdFlag(APPID_SESSION_UDP_REVERSED))
{
// To get here, we missed the initial query, got a
// response, and now we've got another query.
pAppidActiveConfig->mod_config->dns_host_reporting, flowp);
if (rval == SERVICE_SUCCESS)
{
- setAppIdFlag(flowp, APPID_SESSION_UDP_REVERSED);
+ flowp->setAppIdFlag(APPID_SESSION_UDP_REVERSED);
goto success;
}
goto nomatch;
{
case SERVICE_SUCCESS:
success:
- setAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->setAppIdFlag(APPID_SESSION_CONTINUE);
dns_service_mod.api->add_service(flowp, args->pkt, dir, &udp_svc_element,
APP_ID_DNS, nullptr, nullptr, nullptr);
appid_stats.dns_udp_flows++;
const DNSTCPHeader* hdr;
uint16_t tmp;
int rval;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
const int dir = args->dir;
uint16_t size = args->size;
}
success:
- setAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->setAppIdFlag(APPID_SESSION_CONTINUE);
dns_service_mod.api->add_service(flowp, args->pkt, dir, &tcp_svc_element,
APP_ID_DNS, nullptr, nullptr, nullptr);
appid_stats.dns_tcp_flows++;
#include "service_plugins/service_api.h"
#include "service_plugins/service_util.h"
-#include "util/sf_mlmp.h"
+#include "appid_utils/sf_mlmp.h"
#include "utils/util.h"
#include "app_info_table.h"
void finalizeFflow(fflow_info* fflow, unsigned app_type_flags, AppId target_appId, Packet* p)
{
- AppIdData* fp;
+ AppIdSession* fp;
sfip_t saddr, daddr;
sfip_set_raw(&saddr, &fflow->sip, AF_INET);
sfip_set_raw(&daddr, &fflow->dip, AF_INET);
- if (!(fp = AppIdEarlySessionCreate(nullptr, p, &saddr, fflow->sport, &daddr, fflow->dport,
+ if (!(fp = AppIdSession::create_future_session(p, &saddr, fflow->sport, &daddr, fflow->dport,
fflow->protocol, target_appId, 0)))
return;
{
fp->serviceAppId = target_appId;
fp->rnaServiceState = RNA_STATE_FINISHED;
- fp->rnaClientState = RNA_STATE_FINISHED;
+ fp->rna_client_state = RNA_STATE_FINISHED;
}
if (app_type_flags & APP_TYPE_CLIENT)
{
- fp->ClientAppId = target_appId;
- fp->rnaClientState = RNA_STATE_FINISHED;
+ fp->client_app_id = target_appId;
+ fp->rna_client_state = RNA_STATE_FINISHED;
}
if (app_type_flags & APP_TYPE_PAYLOAD)
{
- fp->payloadAppId = target_appId;
+ fp->payload_app_id = target_appId;
}
}
static CLIENT_APP_RETCODE http_client_init(const IniClientAppAPI* const init_api, SF_LIST* config);
static CLIENT_APP_RETCODE http_client_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet* pkt, struct Detector* userData, const AppIdConfig* pConfig);
+ AppIdSession* flowp, Packet* pkt, struct Detector* userData, const AppIdConfig* pConfig);
static int http_service_init(const IniServiceAPI* const init_api);
static int http_service_validate(ServiceValidationArgs* args);
}
static CLIENT_APP_RETCODE http_client_validate(const uint8_t*, uint16_t, const int dir,
- AppIdData* flowp, Packet* pkt, struct Detector*, const AppIdConfig*)
+ AppIdSession* flowp, Packet* pkt, struct Detector*, const AppIdConfig*)
{
http_client_mod.api->add_app(flowp, APP_ID_HTTP, APP_ID_HTTP + GENERIC_APP_OFFSET, nullptr);
- flowp->rnaClientState = RNA_STATE_FINISHED;
+ flowp->rna_client_state = RNA_STATE_FINISHED;
http_service_mod.api->add_service(flowp, pkt, dir, &http_service_element,
APP_ID_HTTP, nullptr, nullptr, nullptr);
flowp->rnaServiceState = RNA_STATE_FINISHED;
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_DETECTED | APPID_SESSION_SERVICE_DETECTED);
- clearAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED | APPID_SESSION_SERVICE_DETECTED);
+ flowp->clearAppIdFlag(APPID_SESSION_CONTINUE);
flowp->is_http2 = true;
return CLIENT_APP_SUCCESS;
#include "utils/util.h"
+struct httpSession;
+struct fflow_info;
struct CHPAction;
struct CHPApp;
struct DetectorHttpConfig;
int searched;
};
-struct MatchedCHPAction
-{
- CHPAction* mpattern;
- int index;
- MatchedCHPAction* next;
-};
-
-// This is an array element for the dynamically growing tally below
-struct CHPMatchCandidate
-{
- CHPApp* chpapp;
- int key_pattern_length_sum;
- int key_pattern_countdown;
-};
-
-// This is a structure which will grow using realloc as needed to keep all candidates
-struct CHPMatchTally
-{
- int allocated_elements;
- int in_use_elements;
- CHPMatchCandidate item[1]; // FIXIT-H: Was item[0]; must account for this in allocation and freeing.
-};
-int geAppidByViaPattern(const u_int8_t* data, unsigned size, char** version, const
- DetectorHttpConfig* pHttpConfig);
-int getHTTPHeaderLocation(const uint8_t* data, unsigned size, HttpId id, int* start, int* end,
- HeaderMatchedPatterns* hmp,
- const DetectorHttpConfig* pHttpConfig);
+int geAppidByViaPattern(const u_int8_t*, unsigned, char**, const DetectorHttpConfig*);
+int getHTTPHeaderLocation(const uint8_t*, unsigned, HttpId, int*, int*, HeaderMatchedPatterns*,
+ const DetectorHttpConfig*);
inline void FreeMatchedCHPActions(MatchedCHPAction* ma)
{
MatchedCHPAction* tmp;
}
}
-int scanKeyCHP(PatternType ptype, char* buf, int buf_size,
- CHPMatchTally** ppTally, MatchedCHPAction** ppmatches, const DetectorHttpConfig* pHttpConfig);
-
-AppId scanCHP(PatternType ptype, char* buf, int buf_size, MatchedCHPAction* mp,
- char** version, char** user, char** new_field,
- int* total_found, httpSession* hsession, Packet* p, const
- DetectorHttpConfig* pHttpConfig);
-AppId getAppIdFromUrl(char* host, char* url, char** version,
- char* referer, AppId* ClientAppId, AppId* serviceAppId,
- AppId* payloadAppId, AppId* referredPayloadAppId, unsigned from_rtmp,
- const DetectorHttpConfig* pHttpConfig);
-AppId geAppidByContentType(const uint8_t* data, int size, const
- DetectorHttpConfig* pHttpConfig);
-AppId scan_header_x_working_with(const uint8_t* data, uint32_t size, char** version);
-void identifyUserAgent(const u_int8_t* start, int size, AppId* serviceAppId, AppId* ClientAppId,
- char** version,
- const DetectorHttpConfig* pHttpConfig);
-void getServerVendorVersion(const uint8_t* data, int len, char** version, char** vendor,
- RNAServiceSubtype** subtype);
-int webdav_found(HeaderMatchedPatterns* hmp);
-int http_detector_finalize(AppIdConfig* pConfig);
-void http_detector_clean(DetectorHttpConfig* pHttpConfig);
-void finalizeFflow(fflow_info* fflow, unsigned app_type_flags, AppId target_appId,
- Packet* p);
+int scanKeyCHP(PatternType, char*, int, CHPMatchTally**, MatchedCHPAction**,
+ const DetectorHttpConfig*);
+AppId scanCHP(PatternType, char*, int, MatchedCHPAction*, char**, char**, char**, int*,
+ httpSession*, Packet*, const DetectorHttpConfig*);
+AppId getAppIdFromUrl(char*, char*, char**, char*, AppId*, AppId*, AppId*, AppId*, unsigned,
+ const DetectorHttpConfig*);
+AppId geAppidByContentType(const uint8_t*, int, const DetectorHttpConfig*);
+AppId scan_header_x_working_with(const uint8_t*, uint32_t, char**);
+void identifyUserAgent(const u_int8_t*, int, AppId*, AppId*, char**, const DetectorHttpConfig*);
+void getServerVendorVersion(const uint8_t*, int, char**, char**, RNAServiceSubtype**);
+int webdav_found(HeaderMatchedPatterns*);
+int http_detector_finalize(AppIdConfig*);
+void http_detector_clean(DetectorHttpConfig*);
+void finalizeFflow(fflow_info*, unsigned app_type_flags, AppId, Packet* );
#endif
static CLIENT_APP_RETCODE init(const IniClientAppAPI* const init_api, SF_LIST* config);
static void clean(const CleanClientAppAPI* const clean_api);
static CLIENT_APP_RETCODE validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet* pkt, Detector* userData,
+ AppIdSession* flowp, Packet* pkt, Detector* userData,
const AppIdConfig* pConfig);
static RNAClientAppModule client_app_mod =
&client_app_mod,
nullptr,
0,
- nullptr
};
static AppRegistryEntry appIdRegistry[] =
}
static int imap_server_validate(DetectorData* dd, const uint8_t* data, uint16_t size,
- AppIdData* flowp)
+ AppIdSession* flowp)
{
const uint8_t* end = data + size;
ServiceIMAPData* id = &dd->server;
{
if (id->flags & IMAP_FLAG_RESULT_OK)
{
- clearAppIdFlag(flowp, APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
+ flowp->clearAppIdFlag(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
/* we are potentially overriding any APP_ID_IMAP assessment that was made earlier. */
client_app_mod.api->add_app(flowp, APP_ID_IMAPS, APP_ID_IMAPS, nullptr); // sets
// APPID_SESSION_CLIENT_DETECTED
}
static CLIENT_APP_RETCODE validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet*, struct Detector*,
+ AppIdSession* flowp, Packet*, struct Detector*,
const AppIdConfig* pConfig)
{
const uint8_t* s = data;
{
dd->need_continue = 1;
fd->set_flags = 1;
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
}
if (dir == APP_ID_FROM_RESPONDER)
{
if (imap_server_validate(dd, data, size, flowp))
- clearAppIdFlag(flowp, APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
+ flowp->clearAppIdFlag(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
return CLIENT_APP_INPROCESS;
}
if (end == s || !isblank(*s))
{
dd->need_continue = 0;
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_DETECTED);
- clearAppIdFlag(flowp, APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
+ flowp->clearAppIdFlag(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
return CLIENT_APP_SUCCESS;
}
for (; (s < end) && isblank(*s); s++)
if ((length = (end - s)) <= 0)
{
dd->need_continue = 0;
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_DETECTED);
- clearAppIdFlag(flowp, APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
+ flowp->clearAppIdFlag(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
return CLIENT_APP_SUCCESS;
}
cmd = nullptr;
fd->detected = 1;
if (fd->got_user)
{
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_DETECTED);
- clearAppIdFlag(flowp,
- APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
+ flowp->clearAppIdFlag(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
}
fd->state = IMAP_CLIENT_STATE_AUTH;
}
fd->detected = 1;
if (fd->got_user)
{
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_DETECTED);
- clearAppIdFlag(flowp,
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
+ flowp->clearAppIdFlag(
APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
}
}
fd->detected = 1;
if (fd->got_user)
{
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_DETECTED);
- clearAppIdFlag(flowp, APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
+ flowp->clearAppIdFlag(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
}
}
if (!cmd->eoc)
fd->detected = 1;
if (fd->got_user)
{
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_DETECTED);
- clearAppIdFlag(flowp, APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
+ flowp->clearAppIdFlag(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
}
}
if (!cmd->eoc)
{
DetectorData* dd;
ServiceIMAPData* id;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
uint16_t size = args->size;
id = &dd->server;
if (dd->need_continue)
- setAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->setAppIdFlag(APPID_SESSION_CONTINUE);
else
{
- clearAppIdFlag(flowp, APPID_SESSION_CONTINUE);
- if (getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ flowp->clearAppIdFlag(APPID_SESSION_CONTINUE);
+ if (flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
appid_stats.imap_flows++;
return SERVICE_SUCCESS;
}
if (id->count >= IMAP_COUNT_THRESHOLD &&
- !getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ !flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
service_mod.api->add_service(flowp, args->pkt, args->dir, &svc_element,
APP_ID_IMAP, nullptr, nullptr, nullptr);
return SERVICE_SUCCESS;
}
}
- else if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ else if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
service_mod.api->fail_service(flowp, args->pkt, args->dir, &svc_element,
service_mod.flow_data_index, args->pConfig);
}
else
{
- clearAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->clearAppIdFlag(APPID_SESSION_CONTINUE);
return SERVICE_SUCCESS;
}
static CLIENT_APP_RETCODE krb_client_init(const IniClientAppAPI* const init_api, SF_LIST* config);
static CLIENT_APP_RETCODE krb_client_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet* pkt, struct Detector* userData,
+ AppIdSession* flowp, Packet* pkt, struct Detector* userData,
const AppIdConfig* pConfig);
static RNAClientAppModule client_app_mod =
&client_app_mod,
nullptr,
0,
- nullptr
};
static AppRegistryEntry appIdRegistry[] =
#define ERROR_MSG_TYPE 0x1e
static KRB_RETCODE krb_walk_client_packet(KRBState* krbs, const uint8_t* s, const uint8_t* end,
- AppIdData* flowp)
+ AppIdSession* flowp)
{
static const uint8_t KRB_CLIENT_VERSION[] = "\x0a1\x003\x002\x001";
static const uint8_t KRB_CLIENT_TYPE[] = "\x0a2\x003\x002\x001";
}
static KRB_RETCODE krb_walk_server_packet(KRBState* krbs, const uint8_t* s, const uint8_t* end,
- AppIdData* flowp, Packet* pkt, const int dir,
+ AppIdSession* flowp, Packet* pkt, const int dir,
const char* reqCname)
{
static const uint8_t KRB_SERVER_VERSION[] = "\x0a0\x003\x002\x001";
DebugFormat(DEBUG_INSPECTOR,"%p Valid\n", (void*)flowp);
if (krbs->flags & KRB_FLAG_SERVICE_DETECTED)
{
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED) && pkt)
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED) && pkt)
{
service_mod.api->add_service(flowp, pkt, dir, &svc_element, APP_ID_KERBEROS,
nullptr, krbs->ver, nullptr);
- setAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED);
+ flowp->setAppIdFlag(APPID_SESSION_SERVICE_DETECTED);
appid_stats.kerberos_flows++;
}
}
}
static CLIENT_APP_RETCODE krb_client_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet* pkt, struct Detector*, const AppIdConfig*)
+ AppIdSession* flowp, Packet* pkt, struct Detector*, const AppIdConfig*)
{
const uint8_t* s = data;
const uint8_t* end = (data + size);
#ifdef DEBUG_MSGS
DebugFormat(DEBUG_INSPECTOR, "%p Processing %u %u->%u %u %d",
- (void*)flowp, (unsigned int)flowp->proto, pkt->ptrs.sp, pkt->ptrs.dp, size, dir);
+ (void*)flowp, (unsigned int)flowp->protocol, pkt->ptrs.sp, pkt->ptrs.dp, size, dir);
#else
UNUSED(pkt);
#endif
fd = (DetectorData*)snort_calloc(sizeof(DetectorData));
kerberos_detector_mod.api->data_add(flowp, fd,
kerberos_detector_mod.flow_data_index, &snort_free);
- if (flowp->proto == IpProtocol::TCP)
+ if (flowp->protocol == IpProtocol::TCP)
{
fd->clnt_state.state = KRB_STATE_TCP_LENGTH;
fd->svr_state.state = KRB_STATE_TCP_LENGTH;
{
fd->need_continue = 1;
fd->set_flags = 1;
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
}
if (dir == APP_ID_FROM_INITIATOR)
if (krb_walk_client_packet(&fd->clnt_state, s, end, flowp) == KRB_FAILED)
{
DebugFormat(DEBUG_INSPECTOR,"%p Failed\n", (void*)flowp);
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_DETECTED);
- clearAppIdFlag(flowp, APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
+ flowp->clearAppIdFlag(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
return CLIENT_APP_SUCCESS;
}
}
fd->clnt_state.cname) == KRB_FAILED)
{
DebugFormat(DEBUG_INSPECTOR,"%p Server Failed\n", (void*)flowp);
- clearAppIdFlag(flowp, APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
+ flowp->clearAppIdFlag(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
}
return CLIENT_APP_INPROCESS;
}
static int krb_server_validate(ServiceValidationArgs* args)
{
DetectorData* fd;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
Packet* pkt = args->pkt;
const int dir = args->dir;
const uint8_t* end = (data + size);
DebugFormat(DEBUG_INSPECTOR, "%p Processing %u %u->%u %u %d",
- (void*)flowp, (unsigned int)flowp->proto, pkt->ptrs.sp, pkt->ptrs.dp, size, dir);
+ (void*)flowp, (unsigned int)flowp->protocol, pkt->ptrs.sp, pkt->ptrs.dp, size, dir);
if (dir != APP_ID_FROM_RESPONDER)
goto inprocess;
fd = (DetectorData*)snort_calloc(sizeof(DetectorData));
kerberos_detector_mod.api->data_add(flowp, fd,
kerberos_detector_mod.flow_data_index, &snort_free);
- if (flowp->proto == IpProtocol::TCP)
+ if (flowp->protocol == IpProtocol::TCP)
{
fd->clnt_state.state = KRB_STATE_TCP_LENGTH;
fd->svr_state.state = KRB_STATE_TCP_LENGTH;
}
if (fd->need_continue)
- setAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->setAppIdFlag(APPID_SESSION_CONTINUE);
else
{
- clearAppIdFlag(flowp, APPID_SESSION_CONTINUE);
- if (getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ flowp->clearAppIdFlag(APPID_SESSION_CONTINUE);
+ if (flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
return SERVICE_SUCCESS;
}
KRB_FAILED)
{
DebugFormat(DEBUG_INSPECTOR,"%p Failed\n", (void*)flowp);
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
service_mod.api->fail_service(flowp, pkt, dir, &svc_element,
service_mod.flow_data_index, args->pConfig);
return SERVICE_NOMATCH;
}
- clearAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->clearAppIdFlag(APPID_SESSION_CONTINUE);
return SERVICE_SUCCESS;
}
static CLIENT_APP_RETCODE client_init(const IniClientAppAPI* const init_api, SF_LIST* config);
static CLIENT_APP_RETCODE client_init_tcp(const IniClientAppAPI* const init_api, SF_LIST* config);
static CLIENT_APP_RETCODE client_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet* pkt, struct Detector* userData,
+ AppIdSession* flowp, Packet* pkt, struct Detector* userData,
const AppIdConfig* pConfig);
static void client_clean(const CleanClientAppAPI* const clean_api);
static const IniServiceAPI* iniServiceApi;
{
uint32_t id;
const RNAServiceElement* service = nullptr;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
Packet* pkt = args->pkt;
const int dir = args->dir;
if (dir != APP_ID_FROM_RESPONDER)
goto inprocess;
- id = csdPatternTreeSearch(data, size, flowp->proto, pkt, &service, false, args->pConfig);
+ id = csdPatternTreeSearch(data, size, flowp->protocol, pkt, &service, false, args->pConfig);
if (!id)
goto fail;
}
static CLIENT_APP_RETCODE client_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet* pkt, struct Detector*, const AppIdConfig* pConfig)
+ AppIdSession* flowp, Packet* pkt, struct Detector*, const AppIdConfig* pConfig)
{
AppId id;
const RNAServiceElement* service = nullptr;
if (dir == APP_ID_FROM_RESPONDER)
goto inprocess;
- id = csdPatternTreeSearch(data, size, flowp->proto, pkt, &service, true,
+ id = csdPatternTreeSearch(data, size, flowp->protocol, pkt, &service, true,
(AppIdConfig*)pConfig);
if (!id)
goto fail;
static CLIENT_APP_RETCODE pop3_ca_init(const IniClientAppAPI* const init_api, SF_LIST* config);
static void pop3_ca_clean(const CleanClientAppAPI* const clean_api);
static CLIENT_APP_RETCODE pop3_ca_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet* pkt, struct Detector* userData,
+ AppIdSession* flowp, Packet* pkt, struct Detector* userData,
const AppIdConfig* pConfig);
static RNAClientAppModule client_app_mod =
&client_app_mod,
nullptr,
0,
- nullptr
};
static AppRegistryEntry appIdRegistry[] =
}
static int pop3_server_validate(POP3DetectorData* dd, const uint8_t* data, uint16_t size,
- AppIdData* flowp, int server)
+ AppIdSession* flowp, int server)
{
static const char ven_cppop[] = "cppop";
static const char ven_cc[] = "Cubic Circle";
}
else
{
- setAppIdFlag(flowp, APPID_SESSION_ENCRYPTED);
- clearAppIdFlag(flowp, APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
+ flowp->setAppIdFlag(APPID_SESSION_ENCRYPTED);
+ flowp->clearAppIdFlag(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
/* we are potentially overriding the APP_ID_POP3 assessment that was made earlier.
*/
client_app_mod.api->add_app(flowp, APP_ID_POP3S, APP_ID_POP3S, nullptr); // sets
snort_free(dd->client.username);
dd->client.username = nullptr;
dd->need_continue = 0;
- clearAppIdFlag(flowp, APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
+ flowp->clearAppIdFlag(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
dd->client.got_user = 1;
if (dd->client.detected)
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_DETECTED);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
}
}
if (server && begin)
}
static CLIENT_APP_RETCODE pop3_ca_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet*, struct Detector*, const AppIdConfig* pConfig)
+ AppIdSession* flowp, Packet*, struct Detector*, const AppIdConfig* pConfig)
{
const uint8_t* s = data;
const uint8_t* end = (data + size);
{
dd->need_continue = 1;
fd->set_flags = 1;
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
}
if (dir == APP_ID_FROM_RESPONDER)
#endif
if (pop3_server_validate(dd, data, size, flowp, 0))
- clearAppIdFlag(flowp, APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
+ flowp->clearAppIdFlag(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
return CLIENT_APP_INPROCESS;
}
if (!cmd)
{
dd->need_continue = 0;
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_DETECTED);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
return CLIENT_APP_SUCCESS;
}
s += cmd->length;
{
POP3DetectorData* dd;
ServicePOP3Data* pd;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
Packet* pkt = args->pkt;
const int dir = args->dir;
pd = &dd->server;
if (dd->need_continue)
- setAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->setAppIdFlag(APPID_SESSION_CONTINUE);
else
{
- clearAppIdFlag(flowp, APPID_SESSION_CONTINUE);
- if (getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ flowp->clearAppIdFlag(APPID_SESSION_CONTINUE);
+ if (flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
appid_stats.pop_flows++;
return SERVICE_SUCCESS;
if (!pop3_server_validate(dd, data, size, flowp, 1))
{
- if (pd->count >= POP3_COUNT_THRESHOLD && !getAppIdFlag(flowp,
- APPID_SESSION_SERVICE_DETECTED))
+ if (pd->count >= POP3_COUNT_THRESHOLD
+ && !flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
service_mod.api->add_service_consume_subtype(flowp, pkt, dir, &svc_element,
dd->client.state == POP3_CLIENT_STATE_STLS_CMD ? APP_ID_POP3S : APP_ID_POP3,
return SERVICE_SUCCESS;
}
}
- else if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ else if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
service_mod.api->fail_service(flowp, pkt, dir, &svc_element,
service_mod.flow_data_index, args->pConfig);
}
else
{
- clearAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->clearAppIdFlag(APPID_SESSION_CONTINUE);
appid_stats.pop_flows++;
return SERVICE_SUCCESS;
}
#include "http_url_patterns.h"
#include "fw_appid.h"
#include "service_plugins/service_base.h"
-#include "util/sf_mlmp.h"
+#include "appid_utils/sf_mlmp.h"
#include "utils/util.h"
#include "log/messages.h"
static CLIENT_APP_RETCODE sip_client_init(const IniClientAppAPI* const init_api, SF_LIST* config);
static void sip_clean(const CleanClientAppAPI* const clean_api);
static CLIENT_APP_RETCODE sip_client_validate(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, Packet* pkt, Detector* userData,
+ AppIdSession* flowp, Packet* pkt, Detector* userData,
const AppIdConfig* pConfig);
static CLIENT_APP_RETCODE sip_tcp_client_init(const IniClientAppAPI* const init_api,
SF_LIST* config);
static CLIENT_APP_RETCODE sip_tcp_client_validate(const uint8_t* data, uint16_t size, const int
dir,
- AppIdData* flowp, Packet* pkt, Detector* userData,
+ AppIdSession* flowp, Packet* pkt, Detector* userData,
const AppIdConfig* pConfig);
static int sipAppGeClientApp(void* patternMatcher, char* pattern, uint32_t patternLen,
AppId* ClientAppId, char** clientVersion);
// static const char* const SIP_USRNAME_BEGIN_MARKER = "<sip:";
static CLIENT_APP_RETCODE sip_client_validate(const uint8_t*, uint16_t, const int,
- AppIdData* flowp, Packet*, struct Detector*, const AppIdConfig*)
+ AppIdSession* flowp, Packet*, struct Detector*, const AppIdConfig*)
{
ClientSIPData* fd;
sip_udp_client_mod.api->data_add(flowp, fd,
sip_udp_client_mod.flow_data_index, &clientDataFree);
fd->owner = &sip_udp_client_mod;
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
}
return CLIENT_APP_INPROCESS;
static CLIENT_APP_RETCODE sip_tcp_client_validate(const uint8_t* data, uint16_t size, const int
dir,
- AppIdData* flowp, Packet* pkt, struct Detector* userData,
+ AppIdSession* flowp, Packet* pkt, struct Detector* userData,
const AppIdConfig* pConfig)
{
return sip_client_validate(data, size, dir, flowp, pkt, userData, pConfig);
return 1;
}
-static void createRtpFlow(AppIdData* flowp, const Packet* pkt, const sfip_t* cliIp, uint16_t
+static void createRtpFlow(AppIdSession* flowp, const Packet* pkt, const sfip_t* cliIp, uint16_t
cliPort,
const sfip_t* srvIp, uint16_t srvPort, IpProtocol proto, int16_t app_id)
{
- AppIdData* fp, * fp2;
+ AppIdSession* fp, * fp2;
- fp = sip_service_mod.api->flow_new(flowp, pkt, cliIp, cliPort, srvIp, srvPort,
- proto, app_id, APPID_EARLY_SESSION_FLAG_FW_RULE);
+ fp = AppIdSession::create_future_session(pkt, cliIp, cliPort, srvIp, srvPort, proto, app_id,
+ APPID_EARLY_SESSION_FLAG_FW_RULE);
if (fp)
{
- fp->ClientAppId = flowp->ClientAppId;
- fp->payloadAppId = flowp->payloadAppId;
+ fp->client_app_id = flowp->client_app_id;
+ fp->payload_app_id = flowp->payload_app_id;
fp->serviceAppId = APP_ID_RTP;
PopulateExpectedFlow(flowp, fp, APPID_SESSION_IGNORE_ID_FLAGS);
}
// create an RTCP flow as well
- fp2 = sip_service_mod.api->flow_new(flowp, pkt, cliIp, cliPort+1, srvIp, srvPort+1,
- proto, app_id, APPID_EARLY_SESSION_FLAG_FW_RULE);
+ fp2 = AppIdSession::create_future_session(pkt, cliIp, cliPort + 1, srvIp, srvPort + 1, proto, app_id,
+ APPID_EARLY_SESSION_FLAG_FW_RULE);
if (fp2)
{
- fp2->ClientAppId = flowp->ClientAppId;
- fp2->payloadAppId = flowp->payloadAppId;
+ fp2->client_app_id = flowp->client_app_id;
+ fp2->payload_app_id = flowp->payload_app_id;
fp2->serviceAppId = APP_ID_RTCP;
PopulateExpectedFlow(flowp, fp2, APPID_SESSION_IGNORE_ID_FLAGS);
}
}
-static int addFutureRtpFlows(AppIdData* flowp, const SipDialog* dialog, const Packet* p)
+static int addFutureRtpFlows(AppIdSession* flowp, const SipDialog* dialog, const Packet* p)
{
SIP_MediaData* mdataA,* mdataB;
}
static void SipSessionCbClientProcess(const Packet* p, const SipHeaders* headers, const
- SipDialog* dialog, AppIdData* flowp)
+ SipDialog* dialog, AppIdSession* flowp)
{
ClientSIPData* fd;
AppId ClientAppId = APP_ID_SIP;
sip_udp_client_mod.api->data_add(flowp, fd,
sip_udp_client_mod.flow_data_index, &clientDataFree);
fd->owner = &sip_udp_client_mod;
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
}
if (fd->owner != &sip_udp_client_mod && fd->owner != &sip_tcp_client_mod)
if (fd->userName)
sip_udp_client_mod.api->add_user(flowp, (char*)fd->userName, APP_ID_SIP, 1);
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_DETECTED);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_DETECTED);
}
static void SipSessionCbServiceProcess(const Packet* p, const SipHeaders* headers, const
- SipDialog* dialog, AppIdData* flowp)
+ SipDialog* dialog, AppIdSession* flowp)
{
ServiceSIPData* ss;
int direction;
if (dialog->state == SIP_DLG_ESTABLISHED)
{
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
- setAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->setAppIdFlag(APPID_SESSION_CONTINUE);
sip_service_mod.api->add_service(flowp, p, direction, &svc_element,
APP_ID_SIP, ss->vendor[0] ? ss->vendor : nullptr, nullptr, nullptr);
}
void SipSessionSnortCallback(void*, ServiceEventType, void* data)
{
- AppIdData* flowp = nullptr;
+ AppIdSession* session = nullptr;
SipEventData* eventData = (SipEventData*)data;
const Packet* p = eventData->packet;
IpProtocol::UDP);
}
#endif
- if (p->flow)
- flowp = getAppIdData(p->flow);
+ if(p->flow)
+ session = appid_api.get_appid_data(p->flow);
- if (!flowp)
+ if(!session)
{
- ErrorMessage("Missing session\n");
- return;
+ WarningMessage("AppId Session does not exist.\n");
+ return;
}
- SipSessionCbClientProcess(p, headers, dialog, flowp);
- SipSessionCbServiceProcess(p, headers, dialog, flowp);
+ SipSessionCbClientProcess(p, headers, dialog, session);
+ SipSessionCbServiceProcess(p, headers, dialog, session);
}
static int sip_service_init(const IniServiceAPI* const init_api)
static int sip_service_validate(ServiceValidationArgs* args)
{
ServiceSIPData* ss;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
ss = (ServiceSIPData*)sip_service_mod.api->data_get(flowp, sip_service_mod.flow_data_index);
if (!ss)
if (ss->serverPkt > 10)
{
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
sip_service_mod.api->fail_service(flowp, args->pkt, args->dir, &svc_element,
sip_service_mod.flow_data_index, args->pConfig);
}
- clearAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->clearAppIdFlag(APPID_SESSION_CONTINUE);
return SERVICE_NOMATCH;
}
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
sip_service_mod.api->service_inprocess(flowp, args->pkt, args->dir, &svc_element);
}
// AppId structures for SIP detection
#include "detector_api.h"
-#include "util/sf_multi_mpse.h"
+#include "appid_utils/sf_multi_mpse.h"
struct RNAServiceValidationModule;
extern struct RNAClientAppModule sip_tcp_client_mod;
extern struct RNAServiceValidationModule sip_service_mod;
+// FIXIT-M: ServiceEventType enum needs to become real when SIP is supported
+enum ServiceEventType {};
+void SipSessionSnortCallback(void* ssnptr, ServiceEventType, void* eventData);
+
#endif
#include "application_ids.h"
#include "http_common.h"
-#include "util/sf_multi_mpse.h"
-#include "util/sf_mlmp.h"
+#include "appid_utils/sf_multi_mpse.h"
+#include "appid_utils/sf_mlmp.h"
#include "utils/util.h"
static const char* const FP_OPERATION_AND = "%&%";
+++ /dev/null
-//--------------------------------------------------------------------------
-// Copyright (C) 2014-2016 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.
-//--------------------------------------------------------------------------
-
-// dns_defs.h author Sourcefire Inc.
-
-#ifndef DNS_DEFS_H
-#define DNS_DEFS_H
-
-#include <cstdint>
-
-#define MAX_OPCODE 5
-#define INVALID_OPCODE 3
-
-#define MAX_RCODE 10
-
-#define RCODE_NXDOMAIN 3
-
-#define DNS_LENGTH_FLAGS 0xC0
-
-#define PATTERN_A_REC 1
-#define PATTERN_AAAA_REC 28
-#define PATTERN_CNAME_REC 5
-#define PATTERN_SRV_REC 33
-#define PATTERN_TXT_REC 16
-#define PATTERN_MX_REC 15
-#define PATTERN_SOA_REC 6
-#define PATTERN_NS_REC 2
-#define PATTERN_PTR_REC 12
-
-#pragma pack(1)
-
-// FIXIT-H J bitfields should be replaced with getters/setters
-struct DNSHeader
-{
- uint16_t id;
-#if defined(SF_BIGENDIAN)
- uint8_t QR : 1,
- Opcode : 4,
- AA : 1,
- TC : 1,
- RD : 1;
- uint8_t RA : 1,
- Z : 1,
- AD : 1,
- CD : 1,
- RCODE : 4;
-#else
- uint8_t RD : 1,
- TC : 1,
- AA : 1,
- Opcode : 4,
- QR : 1;
- uint8_t RCODE : 4,
- CD : 1,
- AD : 1,
- Z : 1,
- RA : 1;
-#endif
- uint16_t QDCount;
- uint16_t ANCount;
- uint16_t NSCount;
- uint16_t ARCount;
-};
-
-struct DNSTCPHeader
-{
- uint16_t length;
-};
-
-struct DNSLabel
-{
- uint8_t len;
- uint8_t name;
-};
-
-struct DNSLabelPtr
-{
- uint16_t position;
- uint8_t data;
-};
-
-struct DNSLabelBitfield
-{
- uint8_t id;
- uint8_t len;
- uint8_t data;
-};
-
-struct DNSQueryFixed
-{
- uint16_t QType;
- uint16_t QClass;
-};
-
-struct DNSAnswerData
-{
- uint16_t type;
- uint16_t klass;
- uint32_t ttl;
- uint16_t r_len;
-};
-
-#pragma pack()
-
-#endif
-
#include "utils/util.h"
#include "appid_stats.h"
+#include "appid_module.h"
#include "app_forecast.h"
#include "app_info_table.h"
-
+#include "appid_api.h"
#include "host_port_app_cache.h"
#include "lua_detector_module.h"
#include "client_plugins/client_app_base.h"
-#include "detector_plugins/detector_http.h"
#include "detector_plugins/detector_dns.h"
#include "service_plugins/service_base.h"
#include "service_plugins/service_ssl.h"
#include "service_plugins/service_util.h"
-#include "util/common_util.h"
-#include "util/ip_funcs.h"
-#include "util/network_set.h"
+#include "appid_utils/common_util.h"
+#include "appid_utils/ip_funcs.h"
+#include "appid_utils/network_set.h"
#include "time/packet_time.h"
#include "sfip/sf_ip.h"
#include "stream/stream_api.h"
-#if 1 // FIXIT-M hacks
-struct HttpParsedHeaders
-{
- struct HttpBuf
- {
- char* start;
- int len;
- };
-
- HttpBuf host;
- HttpBuf url;
- HttpBuf userAgent;
- HttpBuf referer;
- HttpBuf via;
- HttpBuf contentType;
- HttpBuf responseCode;
-};
-
-#define HTTP_XFF_FIELD_X_FORWARDED_FOR ""
-#define HTTP_XFF_FIELD_TRUE_CLIENT_IP ""
-
-#endif
-
-#define MAX_ATTR_LEN 1024
-#define HTTP_PREFIX "http://"
-
-#define APP_MAPPING_FILE "appMapping.data"
-
-#ifdef RNA_DEBUG_PE
-static const char* MODULE_NAME = "fw_appid";
-#endif
-
-static volatile int app_id_debug_flag;
-static FWDebugSessionConstraints app_id_debug_info;
-char app_id_debug_session[FW_DEBUG_SESSION_ID_SIZE];
-bool app_id_debug_session_flag;
-
-ProfileStats tpPerfStats;
-ProfileStats tpLibPerfStats;
-ProfileStats httpPerfStats;
-ProfileStats clientMatchPerfStats;
-ProfileStats serviceMatchPerfStats;
-
#define HTTP_PATTERN_MAX_LEN 1024
#define PORT_MAX 65535
-unsigned long app_id_raw_packet_count = 0;
-unsigned long app_id_processed_packet_count = 0;
-unsigned long app_id_ignored_packet_count = 0;
-int app_id_debug;
-static int ptype_scan_counts[NUMBER_OF_PTYPES];
-
-static void ProcessThirdPartyResults(Packet* p, AppIdData* appIdSession, int confidence,
- AppId* proto_list, ThirdPartyAppIDAttributeData* attribute_data);
-static void ExamineRtmpMetadata(AppIdData* appIdSession);
-
void dump_appid_stats()
{
LogMessage("Application Identification Preprocessor:\n");
- LogMessage(" Total packets received : %lu\n", app_id_raw_packet_count);
- LogMessage(" Total packets processed : %lu\n", app_id_processed_packet_count);
+ LogMessage(" Total packets received : %lu\n", appid_stats.packets);
+ LogMessage(" Total packets processed : %lu\n", appid_stats.processed_packets);
if (thirdparty_appid_module)
thirdparty_appid_module->print_stats();
- LogMessage(" Total packets ignored : %lu\n", app_id_ignored_packet_count);
+ LogMessage(" Total packets ignored : %lu\n", appid_stats.ignored_packets);
AppIdServiceStateDumpStats();
RNAPndDumpLuaStats();
}
void reset_appid_stats(int, void*)
{
- app_id_raw_packet_count = 0;
- app_id_processed_packet_count = 0;
- app_id_ignored_packet_count = 0;
if (thirdparty_appid_module)
thirdparty_appid_module->reset_stats();
}
-
-/* The UNSYNCED_SNORT_ID value is to cheaply insure we get
- the value from snort rather than assume */
-#define UNSYNCED_SNORT_ID 0x5555
-
-AppIdData* appSharedDataAlloc(IpProtocol proto, const sfip_t* ip)
-{
- // FIXIT - should appid_flow_data_id be global to all threads?
- static THREAD_LOCAL uint32_t appid_flow_data_id = 0;
- AppIdData* data = new AppIdData;
-
- // should be freed by flow
- // if (app_id_free_list)
- // {
- // data = app_id_free_list;
- // app_id_free_list = data->next;
- // data->reset();
- // }
-
- if (thirdparty_appid_module)
- if (!(data->tpsession = thirdparty_appid_module->session_create()))
- FatalError("Could not allocate AppIdData->tpsession data");
-
- data->id = ++appid_flow_data_id;
- data->common.fsf_type.flow_type = APPID_SESSION_TYPE_NORMAL;
- data->proto = proto;
- data->common.initiator_ip = *ip;
- data->snortId = UNSYNCED_SNORT_ID;
- data->search_support_type = SEARCH_SUPPORT_TYPE_UNKNOWN;
- return data;
-}
-
-static inline AppIdData* appSharedCreateData(const Packet* p, IpProtocol proto, int direction)
-{
- AppIdData* data;
- const sfip_t* ip;
-
- ip = (direction == APP_ID_FROM_INITIATOR)
- ? p->ptrs.ip_api.get_src() : p->ptrs.ip_api.get_dst();
- data = appSharedDataAlloc(proto, ip);
-
- if ( ( proto == IpProtocol::TCP || proto == IpProtocol::UDP ) && ( p->ptrs.sp != p->ptrs.dp ) )
- data->common.initiator_port =
- (direction == APP_ID_FROM_INITIATOR) ? p->ptrs.sp : p->ptrs.dp;
- data->ssn = p->flow;
- data->stats.firstPktsecond = p->pkth->ts.tv_sec;
-
- p->flow->set_application_data(data);
- return data;
-}
-
-static inline void appSharedReInitData(AppIdData* session)
-{
- session->miscAppId = APP_ID_NONE;
-
-#ifdef REMOVED_WHILE_NOT_IN_USE
- //data
- if (isSslServiceAppId(session->tpAppId))
- {
- session->payloadAppId = session->referredPayloadAppId = session->tpPayloadAppId =
- APP_ID_NONE;
- clearAppIdFlag(session, APPID_SESSION_CONTINUE);
- if (session->payloadVersion)
- {
- snort_free(session->payloadVersion);
- session->payloadVersion = nullptr;
- }
- if (session->hsession && session->hsession->url)
- {
- snort_free(session->hsession->url);
- session->hsession->url = nullptr;
- }
- }
-#endif
-
- //service
- if (!getAppIdFlag(session, APPID_SESSION_STICKY_SERVICE))
- {
- clearAppIdFlag(session, APPID_SESSION_STICKY_SERVICE);
-
- session->tpAppId = session->serviceAppId = session->portServiceAppId = APP_ID_NONE;
- if (session->serviceVendor)
- {
- snort_free(session->serviceVendor);
- session->serviceVendor = nullptr;
- }
- if (session->serviceVersion)
- {
- snort_free(session->serviceVersion);
- session->serviceVersion = nullptr;
- }
-
- session->service_ip.clear();
- session->service_port = 0;
- session->rnaServiceState = RNA_STATE_NONE;
- session->serviceData = nullptr;
- AppIdFlowdataDeleteAllByMask(session, APPID_SESSION_DATA_SERVICE_MODSTATE_BIT);
- }
-
- //client
- session->ClientAppId = session->ClientServiceAppId = APP_ID_NONE;
- if (session->clientVersion)
- {
- snort_free(session->clientVersion);
- session->clientVersion = nullptr;
- }
- session->rnaClientState = RNA_STATE_NONE;
- AppIdFlowdataDeleteAllByMask(session, APPID_SESSION_DATA_CLIENT_MODSTATE_BIT);
-
- //3rd party cleaning
- if (thirdparty_appid_module)
- thirdparty_appid_module->session_delete(session->tpsession, 1);
- session->init_tpPackets = 0;
- session->resp_tpPackets = 0;
-
- session->scan_flags &= ~SCAN_HTTP_HOST_URL_FLAG;
- clearAppIdFlag(session, APPID_SESSION_SERVICE_DETECTED|APPID_SESSION_CLIENT_DETECTED|
- APPID_SESSION_SSL_SESSION|APPID_SESSION_HTTP_SESSION|APPID_SESSION_APP_REINSPECT);
-}
-
void fwAppIdFini(AppIdConfig* pConfig)
{
-#ifdef RNA_FULL_CLEANUP
- AppIdData* app_id;
- TmpAppIdData* tmp_app_id;
-
- while ((app_id = app_id_free_list))
- {
- app_id_free_list = app_id->next;
- snort_free(app_id);
- }
-
- while ((tmp_app_id = tmp_app_id_free_list))
- {
- tmp_app_id_free_list = tmp_app_id->next;
- snort_free(tmp_app_id);
- }
- AppIdFlowdataFini();
-#endif
-
+ AppIdSession::release_free_list_flow_data();
appInfoTableFini(pConfig);
}
-static inline int PENetworkMatch(const sfip_t* pktAddr, const PortExclusion* pe)
-{
- const uint32_t* pkt = pktAddr->ip32;
- const uint32_t* nm = pe->netmask.u6_addr32;
- const uint32_t* peIP = pe->ip.u6_addr32;
- return (((pkt[0] & nm[0]) == peIP[0])
- && ((pkt[1] & nm[1]) == peIP[1])
- && ((pkt[2] & nm[2]) == peIP[2])
- && ((pkt[3] & nm[3]) == peIP[3]));
-}
-
-static inline int checkPortExclusion(const Packet* pkt, int reversed)
-{
- SF_LIST** src_port_exclusions;
- SF_LIST** dst_port_exclusions;
- SF_LIST* pe_list;
- PortExclusion* pe;
- const sfip_t* s_ip;
- uint16_t port;
- AppIdConfig* pConfig = pAppidActiveConfig;
-
- if ( pkt->is_tcp() )
- {
- src_port_exclusions = pConfig->tcp_port_exclusions_src;
- dst_port_exclusions = pConfig->tcp_port_exclusions_dst;
- }
- else if ( pkt->is_udp() )
- {
- src_port_exclusions = pConfig->udp_port_exclusions_src;
- dst_port_exclusions = pConfig->udp_port_exclusions_dst;
- }
- else
- return 0;
-
- /* check the source port */
- port = reversed ? pkt->ptrs.dp : pkt->ptrs.sp;
- if ( port && (pe_list=src_port_exclusions[port]) != nullptr )
- {
- s_ip = reversed ? pkt->ptrs.ip_api.get_dst() : pkt->ptrs.ip_api.get_src();
-
- SF_LNODE* node;
-
- /* walk through the list of port exclusions for this port */
- for ( pe = (PortExclusion*)sflist_first(pe_list, &node);
- pe;
- pe = (PortExclusion*)sflist_next(&node) )
- {
- if ( PENetworkMatch(s_ip, pe))
- {
-#ifdef RNA_DEBUG_PE
- char inetBuffer[INET6_ADDRSTRLEN];
- inetBuffer[0] = 0;
- sfip_ntop(s_ip, inetBuffer, sizeof(inetBuffer));
- SFDEBUG(MODULE_NAME, "excluding src port: %d",port);
- SFDEBUG(MODULE_NAME, "for addresses src: %s", inetBuffer);
-#endif
- return 1;
- }
- }
- }
-
- /* check the dest port */
- port = reversed ? pkt->ptrs.sp : pkt->ptrs.dp;
- if ( port && (pe_list=dst_port_exclusions[port]) != nullptr )
- {
- s_ip = reversed ? pkt->ptrs.ip_api.get_src() : pkt->ptrs.ip_api.get_dst();
-
- SF_LNODE* node;
- /* walk through the list of port exclusions for this port */
- for ( pe = (PortExclusion*)sflist_first(pe_list, &node);
- pe;
- pe = (PortExclusion*)sflist_next(&node) )
- {
- if ( PENetworkMatch(s_ip, pe))
- {
-#ifdef RNA_DEBUG_PE
- char inetBuffer[INET6_ADDRSTRLEN];
- inetBuffer[0] = 0;
- sfip_ntop(s_ip, inetBuffer, sizeof(inetBuffer));
- SFDEBUG(MODULE_NAME, "excluding dst port: %d",port);
- SFDEBUG(MODULE_NAME, "for addresses dst: %s", inetBuffer);
-#endif
- return 1;
- }
- }
- }
-
- return 0;
-}
-
-static inline bool fwAppIdDebugCheck(Flow* flow, AppIdData* session, volatile int debug_flag,
- FWDebugSessionConstraints* info, char* debug_session, int direction)
-{
- if (debug_flag)
- {
- assert(flow);
- const FlowKey* key = flow->key;
-
- if (((info->protocol == PktType::NONE) || info->protocol == key->pkt_type) &&
- (((!info->sport || info->sport == key->port_l) &&
- (!info->sip_flag || memcmp(&info->sip, key->ip_l, sizeof(info->sip)) == 0) &&
- (!info->dport || info->dport == key->port_h) &&
- (!info->dip_flag || memcmp(&info->dip, key->ip_h, sizeof(info->dip)) == 0)) ||
- ((!info->sport || info->sport == key->port_h) &&
- (!info->sip_flag || memcmp(&info->sip, key->ip_h, sizeof(info->sip)) == 0) &&
- (!info->dport || info->dport == key->port_l) &&
- (!info->dip_flag || memcmp(&info->dip, key->ip_l, sizeof(info->dip)) == 0))))
- {
- int af;
- sfip_t sip;
- sfip_t dip;
- unsigned offset;
- uint16_t sport;
- uint16_t dport;
- char sipstr[INET6_ADDRSTRLEN];
- char dipstr[INET6_ADDRSTRLEN];
-
- if (session && session->common.fsf_type.flow_type != APPID_SESSION_TYPE_IGNORE)
- {
- if (session->common.initiator_port)
- {
- if (session->common.initiator_port == key->port_l)
- {
- sfip_set_raw(&sip, key->ip_l, AF_INET);
- sfip_set_raw(&dip, key->ip_l, AF_INET);
- sport = key->port_l;
- dport = key->port_h;
- }
- else
- {
- sfip_set_raw(&sip, key->ip_l, AF_INET);
- sfip_set_raw(&dip, key->ip_l, AF_INET);
- sport = key->port_h;
- dport = key->port_l;
- }
- }
- else
- {
- // FIXIT-L: the key_ip var was added to be able to call sfip_fast_eq6, need to
- // verify this works... not tested as yet...
- sfip_t key_ip;
- memcpy(key_ip.ip32, key->ip_l, sizeof(key_ip.ip32));
- if (sfip_fast_eq6(&session->common.initiator_ip, &key_ip) == 0)
- {
- sfip_set_raw(&sip, key->ip_l, AF_INET);
- sfip_set_raw(&dip, key->ip_h, AF_INET);
- sport = key->port_l;
- dport = key->port_h;
- }
- else
- {
- sfip_set_raw(&sip, key->ip_l, AF_INET);
- sfip_set_raw(&dip, key->ip_h, AF_INET);
- sport = key->port_h;
- dport = key->port_l;
- }
- }
- }
- else
- {
- sfip_set_raw(&sip, key->ip_l, AF_INET);
- sfip_set_raw(&dip, key->ip_h, AF_INET);
- sport = key->port_l;
- dport = key->port_h;
- }
- sipstr[0] = 0;
- if ( sip.ip32[0] || sip.ip32[1] || sip.ip16[4] ||
- (sip.ip16[5] && sip.ip16[5] != 0xffff) )
- {
- af = AF_INET6;
- offset = 0;
- }
- else
- {
- af = AF_INET;
- offset = 12;
- }
-
- inet_ntop(af, &sip.ip8[offset], sipstr, sizeof(sipstr));
- dipstr[0] = 0;
- if ( dip.ip32[0] || dip.ip32[1] || dip.ip16[4] ||
- (dip.ip16[5] && dip.ip16[5] != 0xFFFF) )
- {
- af = AF_INET6;
- offset = 0;
- }
- else
- {
- af = AF_INET;
- offset = 12;
- }
-
- inet_ntop(af, &dip.ip8[offset], dipstr, sizeof(dipstr));
-#ifdef HAVE_DAQ_ADDRESS_SPACE_ID
- snprintf(debug_session, FW_DEBUG_SESSION_ID_SIZE, "%s-%u -> %s-%u %u%s AS %u I %u",
- sipstr, (unsigned)sport, dipstr, (unsigned)dport, (unsigned)key->pkt_type,
- (direction == APP_ID_FROM_INITIATOR) ? "" : " R",
- (unsigned)key->addressSpaceId, get_instance_id());
-#else
- snprintf(debug_session, FW_DEBUG_SESSION_ID_SIZE, "%s-%u -> %s-%u %u%s I %u",
- sipstr, (unsigned)sport, dipstr, (unsigned)dport, (unsigned)key->pkt_type,
- (direction == APP_ID_FROM_INITIATOR) ? "" : " R", get_instance_id());
-#endif
- return true;
- }
- }
- return false;
-}
-
-static inline void appIdDebugParse(const char* desc, const uint8_t* data, uint32_t length,
- volatile int* debug_flag, FWDebugSessionConstraints* info)
-{
- *debug_flag = 0;
- memset(info, 0, sizeof(*info));
- do
- {
- if (length >= sizeof(info->protocol))
- {
- info->protocol = static_cast<PktType>(*data);
- length -= sizeof(info->protocol);
- data += sizeof(info->protocol);
- }
- else
- break;
-
- if (length >= sizeof(info->sip))
- {
- memcpy(&info->sip, data, sizeof(info->sip));
- if (info->sip.u6_addr32[1] || info->sip.u6_addr32[2] || info->sip.u6_addr32[3])
- info->sip_flag = 1;
- else if (info->sip.u6_addr32[0])
- {
- info->sip.u6_addr32[3] = info->sip.u6_addr32[0];
- info->sip.u6_addr32[0] = 0;
- info->sip.u6_addr16[5] = 0xFFFF;
- info->sip_flag = 1;
- }
- length -= sizeof(info->sip);
- data += sizeof(info->sip);
- }
- else
- break;
-
- if (length >= sizeof(info->sport))
- {
- memcpy(&info->sport, data, sizeof(info->sport));
- length -= sizeof(info->sport);
- data += sizeof(info->sport);
- }
- else
- break;
-
- if (length >= sizeof(info->dip))
- {
- memcpy(&info->dip, data, sizeof(info->dip));
- if (info->dip.u6_addr32[1] || info->dip.u6_addr32[2] || info->dip.u6_addr32[3])
- info->dip_flag = 1;
- else if (info->dip.u6_addr32[0])
- {
- info->dip.u6_addr32[3] = info->dip.u6_addr32[0];
- info->dip.u6_addr32[0] = 0;
- info->dip.u6_addr16[5] = 0xFFFF;
- info->dip_flag = 1;
- }
- length -= sizeof(info->dip);
- data += sizeof(info->dip);
- }
- else
- break;
-
- if (length >= sizeof(info->dport))
- memcpy(&info->dport, data, sizeof(info->dport));
- else
- break;
- }
- while (0);
-
- if (info->protocol != PktType::NONE || info->sip_flag || info->sport || info->dip_flag ||
- info->dport)
- {
- int saf;
- int daf;
- char sipstr[INET6_ADDRSTRLEN];
- char dipstr[INET6_ADDRSTRLEN];
-
- if (!info->sip.u6_addr32[0] && !info->sip.u6_addr32[0] && !info->sip.u6_addr16[4] &&
- info->sip.u6_addr16[5] == 0xFFFF)
- {
- saf = AF_INET;
- }
- else
- saf = AF_INET6;
- if (!info->dip.u6_addr32[0] && !info->dip.u6_addr32[0] && !info->dip.u6_addr16[4] &&
- info->dip.u6_addr16[5] == 0xFFFF)
- {
- daf = AF_INET;
- }
- else
- daf = AF_INET6;
- if (!info->sip_flag)
- saf = daf;
- if (!info->dip_flag)
- daf = saf;
- sipstr[0] = 0;
- inet_ntop(saf, saf == AF_INET ? &info->sip.u6_addr32[3] : info->sip.u6_addr32, sipstr,
- sizeof(sipstr));
- dipstr[0] = 0;
- inet_ntop(daf, daf == AF_INET ? &info->dip.u6_addr32[3] : info->dip.u6_addr32, dipstr,
- sizeof(dipstr));
- LogMessage("Debugging %s with %s-%u and %s-%u %u\n", desc,
- sipstr, (unsigned)info->sport,
- dipstr, (unsigned)info->dport,
- (unsigned)info->protocol);
- *debug_flag = 1;
- }
- else
- LogMessage("Debugging %s disabled\n", desc);
-}
-
-int AppIdDebug(uint16_t, const uint8_t* const data, uint32_t length, void**, char*, int)
-{
- appIdDebugParse("appId", data, length, &app_id_debug_flag, &app_id_debug_info);
- return 0;
-}
-
unsigned isIPv4HostMonitored(uint32_t ip4, int32_t zone)
{
NetworkSet* net_list;
return flags;
}
-static inline unsigned isIPMonitored(const Packet* p, int dst)
+void AppIdAddUser(AppIdSession* session, const char* username, AppId appId, int success)
{
- const sfip_t* sf_ip;
- NetworkSet* net_list;
- unsigned flags;
- int32_t zone;
- NSIPv6Addr ip6;
- AppIdConfig* pConfig = pAppidActiveConfig;
-
- if (!dst)
- {
- zone = p->pkth->ingress_group;
- sf_ip = p->ptrs.ip_api.get_src();
- }
- else
- {
- zone = (p->pkth->egress_index == DAQ_PKTHDR_UNKNOWN) ? p->pkth->ingress_group
- :
- p->pkth->egress_group;
- if (zone == DAQ_PKTHDR_FLOOD)
- return 0;
- sf_ip = p->ptrs.ip_api.get_dst();
- }
-
- if (zone >= 0 && zone < MAX_ZONES && pConfig->net_list_by_zone[zone])
- net_list = pConfig->net_list_by_zone[zone];
- else
- net_list = pConfig->net_list;
-
- if ( sf_ip->is_ip4() )
- {
- if (sf_ip->ip32[0] == 0xFFFFFFFF)
- return IPFUNCS_CHECKED;
- NetworkSet_ContainsEx(net_list, ntohl(sf_ip->ip32[0]), &flags);
- }
+ if (session->username)
+ snort_free(session->username);
+ session->username = snort_strdup(username);
+ session->username_service = appId;
+ if (success)
+ session->setAppIdFlag(APPID_SESSION_LOGIN_SUCCEEDED);
else
- {
- memcpy(&ip6, sf_ip->ip32, sizeof(ip6));
- NSIPv6AddrNtoH(&ip6);
- NetworkSet_Contains6Ex(net_list, &ip6, &flags);
- }
-
- return flags | IPFUNCS_CHECKED;
+ session->clearAppIdFlag(APPID_SESSION_LOGIN_SUCCEEDED);
}
-static inline bool isSpecialSessionMonitored(const Packet* p)
+void AppIdAddDnsQueryInfo(AppIdSession* session, uint16_t id, const uint8_t* host, uint8_t host_len,
+ uint16_t host_offset, uint16_t record_type)
{
- if ( p->is_ip4() )
+ if ( session->dsession )
{
- if (p->is_udp() && ((p->ptrs.sp == 68 && p->ptrs.dp == 67)
- || (p->ptrs.sp == 67 && p->ptrs.dp == 68)))
- {
- return true;
- }
+ if ( ( session->dsession->state != 0 ) && ( session->dsession->id != id ) )
+ AppIdResetDnsInfo(session);
}
- return false;
-}
-
-static inline uint64_t isSessionMonitored(const Packet* p, int dir, AppIdData* session)
-{
- uint64_t flags;
-// FIXIT-M: Determine correct replacement for this _dpd call
-#ifdef REMOVED_WHILE_NOT_IN_USE
- uint64_t flow_flags = _dpd.isAppIdRequired() ? APPID_SESSION_DISCOVER_APP : 0;
-#else
- uint64_t flow_flags = APPID_SESSION_DISCOVER_APP;
-#endif
-
- flow_flags |= (dir == APP_ID_FROM_INITIATOR) ? APPID_SESSION_INITIATOR_SEEN :
- APPID_SESSION_RESPONDER_SEEN;
- if (session)
- {
- flow_flags |= session->common.flags;
- if (session->common.policyId != appIdPolicyId)
- {
- if (checkPortExclusion(p, dir == APP_ID_FROM_RESPONDER))
- {
- flow_flags |= APPID_SESSION_INITIATOR_SEEN | APPID_SESSION_RESPONDER_SEEN |
- APPID_SESSION_INITIATOR_CHECKED | APPID_SESSION_RESPONDER_CHECKED;
- flow_flags &= ~(APPID_SESSION_INITIATOR_MONITORED |
- APPID_SESSION_RESPONDER_MONITORED);
- return flow_flags;
- }
- if (dir == APP_ID_FROM_INITIATOR)
- {
- if (getAppIdFlag(session, APPID_SESSION_INITIATOR_CHECKED))
- {
- flags = isIPMonitored(p, 0);
- if (flags & IPFUNCS_HOSTS_IP)
- flow_flags |= APPID_SESSION_INITIATOR_MONITORED;
- else
- flow_flags &= ~APPID_SESSION_INITIATOR_MONITORED;
- }
-
- if (getAppIdFlag(session, APPID_SESSION_RESPONDER_CHECKED))
- {
- flags = isIPMonitored(p, 1);
- if (flags & IPFUNCS_HOSTS_IP)
- flow_flags |= APPID_SESSION_RESPONDER_MONITORED;
- else
- flow_flags &= ~APPID_SESSION_RESPONDER_MONITORED;
- }
- }
- else
- {
- if (getAppIdFlag(session, APPID_SESSION_RESPONDER_CHECKED))
- {
- flags = isIPMonitored(p, 0);
- if (flags & IPFUNCS_HOSTS_IP)
- flow_flags |= APPID_SESSION_RESPONDER_MONITORED;
- else
- flow_flags &= ~APPID_SESSION_RESPONDER_MONITORED;
- }
-
- if (getAppIdFlag(session, APPID_SESSION_INITIATOR_CHECKED))
- {
- flags = isIPMonitored(p, 1);
- if (flags & IPFUNCS_HOSTS_IP)
- flow_flags |= APPID_SESSION_INITIATOR_MONITORED;
- else
- flow_flags &= ~APPID_SESSION_INITIATOR_MONITORED;
- }
- }
- }
+ else
+ session->dsession = (dnsSession*)snort_calloc(sizeof(dnsSession));
- if (getAppIdFlag(session, APPID_SESSION_BIDIRECTIONAL_CHECKED) ==
- APPID_SESSION_BIDIRECTIONAL_CHECKED)
- return flow_flags;
+ if (session->dsession->state & DNS_GOT_QUERY)
+ return;
+ session->dsession->state |= DNS_GOT_QUERY;
- if (dir == APP_ID_FROM_INITIATOR)
- {
- if (!getAppIdFlag(session, APPID_SESSION_INITIATOR_CHECKED))
- {
- flags = isIPMonitored(p, 0);
- flow_flags |= APPID_SESSION_INITIATOR_CHECKED;
- if (flags & IPFUNCS_HOSTS_IP)
- flow_flags |= APPID_SESSION_INITIATOR_MONITORED;
- if (flags & IPFUNCS_USER_IP)
- flow_flags |= APPID_SESSION_DISCOVER_USER;
- if (flags & IPFUNCS_APPLICATION)
- flow_flags |= APPID_SESSION_DISCOVER_APP;
+ session->dsession->id = id;
+ session->dsession->record_type = record_type;
- if (isSpecialSessionMonitored(p))
- {
- flow_flags |= APPID_SESSION_SPECIAL_MONITORED;
- }
- }
- if (!(flow_flags & APPID_SESSION_DISCOVER_APP) && !getAppIdFlag(session,
- APPID_SESSION_RESPONDER_CHECKED))
- {
- flags = isIPMonitored(p, 1);
- if (flags & IPFUNCS_CHECKED)
- flow_flags |= APPID_SESSION_RESPONDER_CHECKED;
- if (flags & IPFUNCS_HOSTS_IP)
- flow_flags |= APPID_SESSION_RESPONDER_MONITORED;
- if (flags & IPFUNCS_APPLICATION)
- flow_flags |= APPID_SESSION_DISCOVER_APP;
- if (isSpecialSessionMonitored(p))
- {
- flow_flags |= APPID_SESSION_SPECIAL_MONITORED;
- }
- }
- }
- else
- {
- if (!getAppIdFlag(session, APPID_SESSION_RESPONDER_CHECKED))
- {
- flags = isIPMonitored(p, 0);
- flow_flags |= APPID_SESSION_RESPONDER_CHECKED;
- if (flags & IPFUNCS_HOSTS_IP)
- flow_flags |= APPID_SESSION_RESPONDER_MONITORED;
- if (flags & IPFUNCS_APPLICATION)
- flow_flags |= APPID_SESSION_DISCOVER_APP;
- if (isSpecialSessionMonitored(p))
- {
- flow_flags |= APPID_SESSION_SPECIAL_MONITORED;
- }
- }
- if (!(flow_flags & APPID_SESSION_DISCOVER_APP) && !getAppIdFlag(session,
- APPID_SESSION_INITIATOR_CHECKED))
- {
- flags = isIPMonitored(p, 1);
- if (flags & IPFUNCS_CHECKED)
- flow_flags |= APPID_SESSION_INITIATOR_CHECKED;
- if (flags & IPFUNCS_HOSTS_IP)
- flow_flags |= APPID_SESSION_INITIATOR_MONITORED;
- if (flags & IPFUNCS_USER_IP)
- flow_flags |= APPID_SESSION_DISCOVER_USER;
- if (flags & IPFUNCS_APPLICATION)
- flow_flags |= APPID_SESSION_DISCOVER_APP;
- if (isSpecialSessionMonitored(p))
- {
- flow_flags |= APPID_SESSION_SPECIAL_MONITORED;
- }
- }
- }
- }
- else if (checkPortExclusion(p, 0))
- {
- flow_flags |= APPID_SESSION_INITIATOR_SEEN | APPID_SESSION_RESPONDER_SEEN |
- APPID_SESSION_INITIATOR_CHECKED | APPID_SESSION_RESPONDER_CHECKED;
- }
- else if (dir == APP_ID_FROM_INITIATOR)
- {
- flags = isIPMonitored(p, 0);
- flow_flags |= APPID_SESSION_INITIATOR_CHECKED;
- if (flags & IPFUNCS_HOSTS_IP)
- flow_flags |= APPID_SESSION_INITIATOR_MONITORED;
- if (flags & IPFUNCS_USER_IP)
- flow_flags |= APPID_SESSION_DISCOVER_USER;
- if (flags & IPFUNCS_APPLICATION)
- flow_flags |= APPID_SESSION_DISCOVER_APP;
- if (!(flow_flags & APPID_SESSION_DISCOVER_APP))
- {
- flags = isIPMonitored(p, 1);
- if (flags & IPFUNCS_CHECKED)
- flow_flags |= APPID_SESSION_RESPONDER_CHECKED;
- if (flags & IPFUNCS_HOSTS_IP)
- flow_flags |= APPID_SESSION_RESPONDER_MONITORED;
- if (flags & IPFUNCS_APPLICATION)
- flow_flags |= APPID_SESSION_DISCOVER_APP;
- }
- if (isSpecialSessionMonitored(p))
- {
- flow_flags |= APPID_SESSION_SPECIAL_MONITORED;
- }
- }
- else
+ if (!session->dsession->host)
{
- flags = isIPMonitored(p, 0);
- flow_flags |= APPID_SESSION_RESPONDER_CHECKED;
- if (flags & IPFUNCS_HOSTS_IP)
- flow_flags |= APPID_SESSION_RESPONDER_MONITORED;
- if (flags & IPFUNCS_APPLICATION)
- flow_flags |= APPID_SESSION_DISCOVER_APP;
- if (!(flow_flags & APPID_SESSION_DISCOVER_APP))
- {
- flags = isIPMonitored(p, 1);
- if (flags & IPFUNCS_CHECKED)
- flow_flags |= APPID_SESSION_INITIATOR_CHECKED;
- if (flags & IPFUNCS_HOSTS_IP)
- flow_flags |= APPID_SESSION_INITIATOR_MONITORED;
- if (flags & IPFUNCS_USER_IP)
- flow_flags |= APPID_SESSION_DISCOVER_USER;
- if (flags & IPFUNCS_APPLICATION)
- flow_flags |= APPID_SESSION_DISCOVER_APP;
- }
-
- if (isSpecialSessionMonitored(p))
+ if ((host != nullptr) && (host_len > 0) && (host_offset > 0))
{
- flow_flags |= APPID_SESSION_SPECIAL_MONITORED;
+ session->dsession->host_len = host_len;
+ session->dsession->host_offset = host_offset;
+ session->dsession->host = dns_parse_host(host, host_len);
}
}
-
- return flow_flags;
}
-static inline void seServiceAppIdData(AppIdData* session, AppId serviceAppId, char* vendor,
- char** version)
+void AppIdAddDnsResponseInfo(AppIdSession* session, uint16_t id, const uint8_t* host,
+ uint8_t host_len, uint16_t host_offset, uint8_t response_type, uint32_t ttl)
{
- if (serviceAppId <= APP_ID_NONE)
- return;
-
- //in drambuie, 3rd party is in INIT state after processing first GET requuest.
- if (serviceAppId == APP_ID_HTTP)
+ if ( session->dsession )
{
- if (session->ClientServiceAppId == APP_ID_NONE)
- {
- session->ClientServiceAppId = serviceAppId;
- }
- return;
+ if ( ( session->dsession->state != 0 ) && ( session->dsession->id != id ) )
+ AppIdResetDnsInfo(session);
}
+ else
+ session->dsession = (dnsSession*)snort_calloc(sizeof(*session->dsession));
- if (session->serviceAppId != serviceAppId)
- {
- session->serviceAppId = serviceAppId;
-
- if (pAppidActiveConfig->mod_config->instance_id)
- checkSandboxDetection(serviceAppId);
-
- /* Clear out previous values of vendor & version */
- if (session->serviceVendor)
- {
- snort_free(session->serviceVendor);
- session->serviceVendor = nullptr;
- }
- if (session->serviceVersion)
- {
- snort_free(session->serviceVersion);
- session->serviceVersion = nullptr;
- }
+ if (session->dsession->state & DNS_GOT_RESPONSE)
+ return;
+ session->dsession->state |= DNS_GOT_RESPONSE;
- if (vendor)
- session->serviceVendor = vendor;
+ session->dsession->id = id;
+ session->dsession->response_type = response_type;
+ session->dsession->ttl = ttl;
- if (version && *version)
- {
- session->serviceVersion = *version;
- *version = nullptr;
- }
- }
- else
+ if (!session->dsession->host)
{
- if (vendor || version)
+ if ((host != nullptr) && (host_len > 0) && (host_offset > 0))
{
- /* Clear previous values */
- if (session->serviceVendor)
- snort_free(session->serviceVendor);
- if (session->serviceVersion)
- snort_free(session->serviceVersion);
-
- /* set vendor */
- if (vendor)
- session->serviceVendor = vendor;
- else
- session->serviceVendor = nullptr;
-
- /* set version */
- if (version && *version)
- {
- session->serviceVersion = *version;
- *version = nullptr;
- }
- else
- session->serviceVersion = nullptr;
+ session->dsession->host_len = host_len;
+ session->dsession->host_offset = host_offset;
+ session->dsession->host = dns_parse_host(host, host_len);
}
}
}
-static inline void setClientAppIdData(AppIdData* session, AppId clientAppId, char** version)
+void AppIdResetDnsInfo(AppIdSession* session)
{
- AppIdConfig* pConfig = pAppidActiveConfig;
- if (clientAppId <= APP_ID_NONE || clientAppId == APP_ID_HTTP)
- return;
-
- if (session->ClientAppId != clientAppId)
- {
- unsigned prev_priority = appInfoEntryPriorityGet(session->ClientAppId, pConfig);
- unsigned curr_priority = appInfoEntryPriorityGet(clientAppId, pConfig);
-
- if (pAppidActiveConfig->mod_config->instance_id)
- checkSandboxDetection(clientAppId);
-
- if ((session->ClientAppId) && (prev_priority > curr_priority ))
- return;
- session->ClientAppId = clientAppId;
-
- if (session->clientVersion)
- snort_free(session->clientVersion);
-
- if (version && *version)
- {
- session->clientVersion = *version;
- *version = nullptr;
- }
- else
- session->clientVersion = nullptr;
- }
- else if (version && *version)
+ if (session->dsession)
{
- if (session->clientVersion)
- snort_free(session->clientVersion);
- session->clientVersion = *version;
- *version = nullptr;
+ snort_free(session->dsession->host);
+ memset(session->dsession, 0, sizeof(*(session->dsession)));
}
}
-static inline void setReferredPayloadAppIdData(AppIdData* session, AppId referredPayloadAppId)
+void AppIdAddPayload(AppIdSession* session, AppId payload_id)
{
- if (referredPayloadAppId <= APP_ID_NONE)
- return;
-
- if (session->referredPayloadAppId != referredPayloadAppId)
- {
- if (pAppidActiveConfig->mod_config->instance_id)
- checkSandboxDetection(referredPayloadAppId);
-
- session->referredPayloadAppId = referredPayloadAppId;
- }
+ if (pAppidActiveConfig->mod_config->instance_id)
+ checkSandboxDetection(payload_id);
+ session->payload_app_id = payload_id;
}
-static inline void setPayloadAppIdData(AppIdData* session, ApplicationId payloadAppId,
- char** version)
+
+void checkSandboxDetection(AppId appId)
{
+ AppInfoTableEntry* entry;
AppIdConfig* pConfig = pAppidActiveConfig;
- if (payloadAppId <= APP_ID_NONE)
- return;
-
- if (session->payloadAppId != payloadAppId)
- {
- unsigned prev_priority = appInfoEntryPriorityGet(session->payloadAppId, pConfig);
- unsigned curr_priority = appInfoEntryPriorityGet(payloadAppId, pConfig);
-
- if (pAppidActiveConfig->mod_config->instance_id)
- checkSandboxDetection(payloadAppId);
-
- if ((session->payloadAppId ) && (prev_priority > curr_priority ))
- return;
-
- session->payloadAppId = payloadAppId;
-
- if (session->payloadVersion)
- snort_free(session->payloadVersion);
-
- if (version && *version)
- {
- session->payloadVersion = *version;
- *version = nullptr;
- }
- else
- session->payloadVersion = nullptr;
- }
- else if (version && *version)
- {
- if (session->payloadVersion)
- snort_free(session->payloadVersion);
- session->payloadVersion = *version;
- *version = nullptr;
- }
-}
-
-static inline void clearSessionAppIdData(AppIdData* session)
-{
- session->payloadAppId = APP_ID_UNKNOWN;
- session->serviceAppId = APP_ID_UNKNOWN;
- session->tpPayloadAppId = APP_ID_UNKNOWN;
- session->tpAppId = APP_ID_UNKNOWN;
- if (session->payloadVersion)
- {
- snort_free(session->payloadVersion);
- session->payloadVersion = nullptr;
- }
- if (session->serviceVendor)
- {
- snort_free(session->serviceVendor);
- session->serviceVendor = nullptr;
- }
- if (session->serviceVersion)
+ if (pAppidActiveConfig->mod_config->instance_id && pConfig)
{
- snort_free(session->serviceVersion);
- session->serviceVersion = nullptr;
+ entry = appInfoEntryGet(appId, pConfig);
+ if ( entry && ( entry->flags & APPINFO_FLAG_ACTIVE ) )
+ fprintf(SF_DEBUG_FILE, "Detected AppId %d\n", entry->appId);
}
-
- if (session->tsession)
- session->appTlsSessionDataFree();
-
- if (session->hsession)
- session->appHttpSessionDataFree();
-
- if (session->dsession)
- session->appDNSSessionDataFree();
-
- if (thirdparty_appid_module)
- thirdparty_appid_module->session_delete(session->tpsession, 1);
}
-
-static inline int initial_CHP_sweep(char** chp_buffers, MatchedCHPAction** ppmatches,
- AppIdData* session, const DetectorHttpConfig* pHttpConfig)
-{
- CHPApp* cah = nullptr;
- int longest = 0;
- int size, i;
- httpSession* hsession;
- int scanKeyFoundSomething=0;
- CHPMatchTally* pTally = nullptr; // scanKeyCHP allocates a pointer, but we free it when ready
-
- hsession = session->hsession;
-
- for (i = 0; i <= MAX_KEY_PATTERN; i++)
- {
- ppmatches[i] = nullptr;
- if (chp_buffers[i] && (size = strlen(chp_buffers[i])) &&
- scanKeyCHP((PatternType)i, chp_buffers[i], size, &pTally, &ppmatches[i], pHttpConfig))
- scanKeyFoundSomething=1;
- }
- if (!scanKeyFoundSomething)
- return 0;
-
- for (i = 0; i < pTally->in_use_elements; i++)
- {
- // Only those items which have had their key_pattern_countdown field reduced to zero are a
- // full match
- if (pTally->item[i].key_pattern_countdown)
- continue;
- if (longest < pTally->item[i].key_pattern_length_sum)
- {
- // We've found a new longest pattern set
- longest = pTally->item[i].key_pattern_length_sum;
- cah = pTally->item[i].chpapp;
- }
- }
- // either we have a candidate or we don't so we can free the tally structure either way.
- free(pTally);
-
- if (cah == nullptr)
- {
- // We were planning to pass along the content of ppmatches to the second phase and let
- // them be freed inside scanCHP, but we have no candidate so we free here
- for (i = 0; i <= MAX_KEY_PATTERN; i++)
- {
- if (ppmatches[i])
- {
- FreeMatchedCHPActions(ppmatches[i]);
- ppmatches[i] = nullptr;
- }
- }
- return 0;
- }
-
- /***************************************************************
- candidate has been chosen and it is pointed to by cah
- we will preserve any match sets until the calls to scanCHP()
- ***************************************************************/
- for (i = 0; i < NUMBER_OF_PTYPES; i++)
- {
- ptype_scan_counts[i] = cah->ptype_scan_counts[i];
- hsession->ptype_req_counts[i] = cah->ptype_req_counts[i] +
- cah->ptype_rewrite_insert_used[i];
- if (i > 3 && !cah->ptype_scan_counts[i] && !getAppIdFlag(session,
- APPID_SESSION_SPDY_SESSION))
- {
- clearAppIdFlag(session, APPID_SESSION_CHP_INSPECTING);
- if (thirdparty_appid_module)
- thirdparty_appid_module->session_attr_clear(session->tpsession,
- TP_ATTR_CONTINUE_MONITORING);
- }
- }
- hsession->chp_candidate = cah->appIdInstance;
- hsession->app_type_flags = cah->app_type_flags;
- hsession->num_matches = cah->num_matches;
- hsession->num_scans = cah->num_scans;
-
- if (thirdparty_appid_module)
- {
- if ((ptype_scan_counts[CONTENT_TYPE_PT]))
- thirdparty_appid_module->session_attr_set(session->tpsession,
- TP_ATTR_COPY_RESPONSE_CONTENT);
- else
- thirdparty_appid_module->session_attr_clear(session->tpsession,
- TP_ATTR_COPY_RESPONSE_CONTENT);
-
- if ((ptype_scan_counts[LOCATION_PT]))
- thirdparty_appid_module->session_attr_set(session->tpsession,
- TP_ATTR_COPY_RESPONSE_LOCATION);
- else
- thirdparty_appid_module->session_attr_clear(session->tpsession,
- TP_ATTR_COPY_RESPONSE_LOCATION);
-
- if ((ptype_scan_counts[BODY_PT]))
- thirdparty_appid_module->session_attr_set(session->tpsession,
- TP_ATTR_COPY_RESPONSE_BODY);
- else
- thirdparty_appid_module->session_attr_clear(session->tpsession,
- TP_ATTR_COPY_RESPONSE_BODY);
- }
-
- return 1;
-}
-
-static const char* httpFieldName[ NUMBER_OF_PTYPES ] = // for use in debug messages
-{
- "useragent",
- "host",
- "referer",
- "uri",
- "cookie",
- "req_body",
- "content_type",
- "location",
- "body",
-};
-
-static inline void processCHP(AppIdData* session, char** version, Packet* p, const
- AppIdConfig* pConfig)
-{
- int i, size;
- int found_in_buffer = 0;
- char* user = nullptr;
- AppId chp_final;
- AppId ret = 0;
- httpSession* http_session = session->hsession;
-
- char* chp_buffers[NUMBER_OF_PTYPES] =
- {
- http_session->useragent,
- http_session->host,
- http_session->referer,
- http_session->uri,
- http_session->cookie,
- http_session->req_body,
- http_session->content_type,
- http_session->location,
- http_session->body,
- };
-
- char* chp_rewritten[NUMBER_OF_PTYPES] =
- {
- nullptr,nullptr,nullptr,
- nullptr,nullptr,nullptr,
- nullptr,nullptr,nullptr
- };
-
- MatchedCHPAction* chp_matches[NUMBER_OF_PTYPES] =
- {
- nullptr,nullptr,nullptr,
- nullptr,nullptr,nullptr,
- nullptr,nullptr,nullptr
- };
-
- if (http_session->chp_hold_flow)
- http_session->chp_finished = 0;
-
- if (!http_session->chp_candidate)
- {
- // remove artifacts from previous matches before we start again.
- for (i = 0; i < NUMBER_OF_PTYPES; i++)
- {
- if (http_session->new_field[i])
- {
- snort_free(http_session->new_field[i]);
- http_session->new_field[i] = nullptr;
- }
- }
-
- if (!initial_CHP_sweep(chp_buffers, chp_matches, session, &pConfig->detectorHttpConfig))
- http_session->chp_finished = 1; // this is a failure case.
- }
- if (!http_session->chp_finished && http_session->chp_candidate)
- {
- for (i = 0; i < NUMBER_OF_PTYPES; i++)
- {
- if (ptype_scan_counts[i] && chp_buffers[i] && (size = strlen(chp_buffers[i])) > 0)
- {
- found_in_buffer = 0;
- ret = scanCHP((PatternType)i, chp_buffers[i], size, chp_matches[i], version,
- &user, &chp_rewritten[i], &found_in_buffer,
- http_session, p, &pConfig->detectorHttpConfig);
- chp_matches[i] = nullptr; // freed by scanCHP()
- http_session->total_found += found_in_buffer;
- http_session->num_scans--;
- ptype_scan_counts[i] = 0;
- // Give up if scanCHP returns nothing, OR
- // (if we did not match the right numbher of patterns in this field AND EITHER
- // (there is no match quota [all must match]) OR
- // (the total number of matches is less than our match quota))
- if (!ret ||
- (found_in_buffer < http_session->ptype_req_counts[i] &&
- (!http_session->num_matches ||
- http_session->total_found < http_session->num_matches)))
- {
- http_session->chp_candidate = 0;
- break;
- }
- /* We are finished if we have a num_matches target and we've met it or
- if we have done all the scans */
- if (!http_session->num_scans ||
- (http_session->num_matches && http_session->total_found >=
- http_session->num_matches))
- {
- http_session->chp_finished = 1;
- break;
- }
- }
- else if (ptype_scan_counts[i] && !http_session->chp_hold_flow)
- {
- /* we have a scan count, but nothing in the buffer, so we should drop out of CHP */
- http_session->chp_candidate = 0;
- break;
- }
- }
- if (!http_session->chp_candidate)
- {
- http_session->chp_finished = 1;
- if (*version)
- {
- snort_free(*version);
- *version = nullptr;
- }
- if (user)
- {
- snort_free(user);
- user = nullptr;
- }
- for (i = 0; i < NUMBER_OF_PTYPES; i++)
- {
- if (nullptr != chp_rewritten[i])
- {
- snort_free(chp_rewritten[i]);
- chp_rewritten[i] = nullptr;
- }
- }
- memset(ptype_scan_counts, 0, 7 * sizeof(ptype_scan_counts[0]));
-
- // Make it possible for other detectors to run.
- http_session->skip_simple_detect = false;
- return;
- }
- if (http_session->chp_candidate && http_session->chp_finished)
- {
- chp_final = http_session->chp_alt_candidate ?
- http_session->chp_alt_candidate :
- http_session->chp_candidate >> CHP_APPID_BITS_FOR_INSTANCE; // transform the
- // instance into the
- // appId.
- if (http_session->app_type_flags & APP_TYPE_SERVICE)
- {
- seServiceAppIdData(session, chp_final, nullptr, version);
- }
-
- if (http_session->app_type_flags & APP_TYPE_CLIENT)
- {
- setClientAppIdData(session, chp_final, version);
- }
-
- if (http_session->app_type_flags & APP_TYPE_PAYLOAD)
- {
- setPayloadAppIdData(session, (ApplicationId)chp_final, version);
- }
-
- if (http_session->fflow && http_session->fflow->flow_prepared)
- {
- finalizeFflow(http_session->fflow, http_session->app_type_flags,
- (http_session->fflow->appId ? http_session->fflow->appId : chp_final), p);
- snort_free(http_session->fflow);
- http_session->fflow = nullptr;
- }
- if (*version)
- *version = nullptr;
- if (user)
- {
- session->username = user;
- user = nullptr;
- if (http_session->app_type_flags & APP_TYPE_SERVICE)
- session->usernameService = chp_final;
- else
- session->usernameService = session->serviceAppId;
- setAppIdFlag(session, APPID_SESSION_LOGIN_SUCCEEDED);
- }
- for (i = 0; i < NUMBER_OF_PTYPES; i++)
- {
- if (nullptr != chp_rewritten[i])
- {
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s rewritten %s: %s\n", app_id_debug_session,
- httpFieldName[i], chp_rewritten[i]);
- if (http_session->new_field[i])
- snort_free(http_session->new_field[i]);
- http_session->new_field[i] = chp_rewritten[i];
- chp_rewritten[i] = nullptr;
- }
- }
- http_session->chp_candidate = 0;
- //if we're doing safesearch rewrites, we want to continue to hold the flow
- if (!http_session->get_offsets_from_rebuilt)
- http_session->chp_hold_flow = 0;
- session->scan_flags &= ~SCAN_HTTP_VIA_FLAG;
- session->scan_flags &= ~SCAN_HTTP_USER_AGENT_FLAG;
- session->scan_flags &= ~SCAN_HTTP_HOST_URL_FLAG;
- memset(ptype_scan_counts, 0, 7 * sizeof(ptype_scan_counts[0]));
- }
- else /* if we have a candidate, but we're not finished */
- {
- if (user)
- {
- snort_free(user);
- user = nullptr;
- }
- for (i = 0; i < NUMBER_OF_PTYPES; i++)
- {
- if (nullptr != chp_rewritten[i])
- {
- snort_free(chp_rewritten[i]);
- chp_rewritten[i] = nullptr;
- }
- }
- }
- }
-}
-
-static inline bool payloadAppIdIsSet(AppIdData* session)
-{
- return ( session->payloadAppId || session->tpPayloadAppId );
-}
-
-static inline void clearMiscHttpFlags(AppIdData* session)
-{
- if (!getAppIdFlag(session, APPID_SESSION_SPDY_SESSION))
- {
- clearAppIdFlag(session, APPID_SESSION_CHP_INSPECTING);
- if (thirdparty_appid_module)
- thirdparty_appid_module->session_attr_clear(session->tpsession,
- TP_ATTR_CONTINUE_MONITORING);
- }
-}
-
-static inline int processHTTPPacket(Packet* p, AppIdData* session, int direction,
- HttpParsedHeaders* const, const AppIdConfig* pConfig)
-{
- Profile http_profile_context(httpPerfStats);
- constexpr auto RESPONSE_CODE_LENGTH = 3;
- HeaderMatchedPatterns hmp;
- httpSession* http_session;
- int start, end, size;
- char* version = nullptr;
- char* vendorVersion = nullptr;
- char* vendor = nullptr;
- AppId serviceAppId = 0;
- AppId clientAppId = 0;
- AppId payloadAppId = 0;
- AppId referredPayloadAppId = 0;
- char* host;
- char* url;
- char* useragent;
- char* referer;
- char* via;
- AppInfoTableEntry* entry;
-
- http_session = session->hsession;
- if (!http_session)
- {
- clearSessionAppIdData(session);
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s attempt to process HTTP packet with no HTTP data\n",
- app_id_debug_session);
-
- return 0;
- }
-
- // 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 ((!http_session->useragent) && (!http_session->host) && (!http_session->referer) &&
- (!http_session->uri))
- {
- if (!http_session->skip_simple_detect)
- clearMiscHttpFlags(session);
-
- return 0;
- }
-
- if (direction == APP_ID_FROM_RESPONDER && !getAppIdFlag(session,
- APPID_SESSION_RESPONSE_CODE_CHECKED))
- {
- if (http_session->response_code)
- {
- setAppIdFlag(session, APPID_SESSION_RESPONSE_CODE_CHECKED);
- if (strlen(http_session->response_code) != RESPONSE_CODE_LENGTH)
- {
- /* received bad response code. Stop processing this session */
- clearSessionAppIdData(session);
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s bad http response code\n", app_id_debug_session);
-
- return 0;
- }
- }
-#if RESPONSE_CODE_PACKET_THRESHHOLD
- else if (++(http_session->response_code_packets) == RESPONSE_CODE_PACKET_THRESHHOLD)
- {
- setAppIdFlag(session, APPID_SESSION_RESPONSE_CODE_CHECKED);
- /* didn't receive response code in first X packets. Stop processing this session */
- clearSessionAppIdData(session);
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s no response code received\n", app_id_debug_session);
- PREPROC_PROFILE_END(httpPerfStats);
- return 0;
- }
-#endif
- }
- host = http_session->host;
- url = http_session->url;
- via = http_session->via;
- useragent = http_session->useragent;
- referer = http_session->referer;
- memset(&hmp, 0, sizeof(hmp));
-
- if (session->serviceAppId == APP_ID_NONE)
- {
- session->serviceAppId = APP_ID_HTTP;
- if (pAppidActiveConfig->mod_config->instance_id)
- checkSandboxDetection(APP_ID_HTTP);
- }
-
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s chp_finished %d chp_hold_flow %d\n", app_id_debug_session,
- http_session->chp_finished, http_session->chp_hold_flow);
-
- if (!http_session->chp_finished || http_session->chp_hold_flow)
- processCHP(session, &version, p, pConfig);
-
- if (!http_session->skip_simple_detect) // false unless a match happened with a call to
- // processCHP().
- {
- if (!getAppIdFlag(session, APPID_SESSION_APP_REINSPECT))
- {
- // Scan Server Header for Vendor & Version
- if ((thirdparty_appid_module && (session->scan_flags & SCAN_HTTP_VENDOR_FLAG) &&
- session->hsession->server) ||
- (!thirdparty_appid_module && getHTTPHeaderLocation(p->data, p->dsize,
- HTTP_ID_SERVER, &start, &end, &hmp, &pConfig->detectorHttpConfig) == 1))
- {
- if (session->serviceAppId == APP_ID_NONE || session->serviceAppId == APP_ID_HTTP)
- {
- RNAServiceSubtype* subtype = nullptr;
- RNAServiceSubtype** tmpSubtype;
-
- if (thirdparty_appid_module)
- getServerVendorVersion((uint8_t*)session->hsession->server, strlen(
- session->hsession->server), &vendorVersion, &vendor, &subtype);
- else
- getServerVendorVersion(p->data + start, end - start, &vendorVersion,
- &vendor, &subtype);
- if (vendor || vendorVersion)
- {
- if (session->serviceVendor)
- {
- snort_free(session->serviceVendor);
- session->serviceVendor = nullptr;
- }
- if (session->serviceVersion)
- {
- snort_free(session->serviceVersion);
- session->serviceVersion = nullptr;
- }
- if (vendor)
- session->serviceVendor = vendor;
- if (vendorVersion)
- session->serviceVersion = vendorVersion;
- session->scan_flags &= ~SCAN_HTTP_VENDOR_FLAG;
- }
- if (subtype)
- {
- for (tmpSubtype = &session->subtype; *tmpSubtype; tmpSubtype =
- &(*tmpSubtype)->next)
- ;
-
- *tmpSubtype = subtype;
- }
- }
- }
-
- if (webdav_found(&hmp))
- {
- if (app_id_debug_session_flag && payloadAppId > APP_ID_NONE &&
- session->payloadAppId != payloadAppId)
- LogMessage("AppIdDbg %s data is webdav\n", app_id_debug_session);
- setPayloadAppIdData(session, APP_ID_WEBDAV, nullptr);
- }
-
- // Scan User-Agent for Browser types or Skype
- if ((session->scan_flags & SCAN_HTTP_USER_AGENT_FLAG) && session->ClientAppId <=
- APP_ID_NONE && useragent && (size = strlen(useragent)) > 0)
- {
- if (version)
- {
- snort_free(version);
- version = nullptr;
- }
- identifyUserAgent((uint8_t*)useragent, size, &serviceAppId, &clientAppId, &version,
- &pConfig->detectorHttpConfig);
- if (app_id_debug_session_flag && serviceAppId > APP_ID_NONE && serviceAppId !=
- APP_ID_HTTP && session->serviceAppId != serviceAppId)
- LogMessage("AppIdDbg %s User Agent is service %d\n", app_id_debug_session,
- serviceAppId);
- seServiceAppIdData(session, serviceAppId, nullptr, nullptr);
- if (app_id_debug_session_flag && clientAppId > APP_ID_NONE && clientAppId !=
- APP_ID_HTTP && session->ClientAppId != clientAppId)
- LogMessage("AppIdDbg %s User Agent is client %d\n", app_id_debug_session,
- clientAppId);
- setClientAppIdData(session, clientAppId, &version);
- session->scan_flags &= ~SCAN_HTTP_USER_AGENT_FLAG;
- }
-
- /* Scan Via Header for squid */
- if (!payloadAppIdIsSet(session) && (session->scan_flags & SCAN_HTTP_VIA_FLAG) && via &&
- (size = strlen(via)) > 0)
- {
- if (version)
- {
- snort_free(version);
- version = nullptr;
- }
- payloadAppId = geAppidByViaPattern((uint8_t*)via, size, &version,
- &pConfig->detectorHttpConfig);
- if (app_id_debug_session_flag && payloadAppId > APP_ID_NONE &&
- session->payloadAppId != payloadAppId)
- LogMessage("AppIdDbg %s VIA is data %d\n", app_id_debug_session,
- payloadAppId);
- setPayloadAppIdData(session, (ApplicationId)payloadAppId, nullptr);
- session->scan_flags &= ~SCAN_HTTP_VIA_FLAG;
- }
- }
-
- /* Scan X-Working-With HTTP header */
- if ((thirdparty_appid_module && (session->scan_flags & SCAN_HTTP_XWORKINGWITH_FLAG) &&
- session->hsession->x_working_with) ||
- (!thirdparty_appid_module && getHTTPHeaderLocation(p->data, p->dsize,
- HTTP_ID_X_WORKING_WITH, &start, &end, &hmp, &pConfig->detectorHttpConfig) == 1))
- {
- AppId appId;
-
- if (thirdparty_appid_module)
- appId = scan_header_x_working_with((uint8_t*)session->hsession->x_working_with,
- strlen(session->hsession->x_working_with), &version);
- else
- appId = scan_header_x_working_with(p->data + start, end - start, &version);
-
- if (appId)
- {
- if (direction == APP_ID_FROM_INITIATOR)
- {
- if (app_id_debug_session_flag && clientAppId > APP_ID_NONE && clientAppId !=
- APP_ID_HTTP && session->ClientAppId != clientAppId)
- LogMessage("AppIdDbg %s X is client %d\n", app_id_debug_session, appId);
- setClientAppIdData(session, appId, &version);
- }
- else
- {
- if (app_id_debug_session_flag && serviceAppId > APP_ID_NONE && serviceAppId !=
- APP_ID_HTTP && session->serviceAppId != serviceAppId)
- LogMessage("AppIdDbg %s X is service %d\n", app_id_debug_session, appId);
- seServiceAppIdData(session, appId, nullptr, &version);
- }
- session->scan_flags &= ~SCAN_HTTP_XWORKINGWITH_FLAG;
- }
- }
-
- // Scan Content-Type Header for multimedia types and scan contents
- if ((thirdparty_appid_module && (session->scan_flags & SCAN_HTTP_CONTENT_TYPE_FLAG)
- && session->hsession->content_type && !payloadAppIdIsSet(session)) ||
- (!thirdparty_appid_module && !payloadAppIdIsSet(session) &&
- getHTTPHeaderLocation(p->data, p->dsize, HTTP_ID_CONTENT_TYPE, &start, &end,
- &hmp, &pConfig->detectorHttpConfig) == 1))
- {
- if (thirdparty_appid_module)
- payloadAppId = geAppidByContentType((uint8_t*)session->hsession->content_type,
- strlen(session->hsession->content_type), &pConfig->detectorHttpConfig);
- else
- payloadAppId = geAppidByContentType(p->data + start, end - start,
- &pConfig->detectorHttpConfig);
- if (app_id_debug_session_flag && payloadAppId > APP_ID_NONE && session->payloadAppId !=
- payloadAppId)
- LogMessage("AppIdDbg %s Content-Type is data %d\n", app_id_debug_session,
- payloadAppId);
- setPayloadAppIdData(session, (ApplicationId)payloadAppId, nullptr);
- session->scan_flags &= ~SCAN_HTTP_CONTENT_TYPE_FLAG;
- }
-
- if (session->scan_flags & SCAN_HTTP_HOST_URL_FLAG)
- {
- if (version)
- {
- snort_free(version);
- version = nullptr;
- }
- if (getAppIdFromUrl(host, url, &version, referer, &clientAppId, &serviceAppId,
- &payloadAppId, &referredPayloadAppId, 0, &pConfig->detectorHttpConfig) == 1)
- {
- // do not overwrite a previously-set client or service
- if (session->ClientAppId <= APP_ID_NONE)
- {
- if (app_id_debug_session_flag && clientAppId > APP_ID_NONE && clientAppId !=
- APP_ID_HTTP && session->ClientAppId != clientAppId)
- LogMessage("AppIdDbg %s URL is client %d\n", app_id_debug_session,
- clientAppId);
- setClientAppIdData(session, clientAppId, nullptr);
- }
- if (session->serviceAppId <= APP_ID_NONE)
- {
- if (app_id_debug_session_flag && serviceAppId > APP_ID_NONE && serviceAppId !=
- APP_ID_HTTP && session->serviceAppId != serviceAppId)
- LogMessage("AppIdDbg %s URL is service %d\n", app_id_debug_session,
- serviceAppId);
- seServiceAppIdData(session, serviceAppId, nullptr, nullptr);
- }
- // DO overwrite a previously-set data
- if (app_id_debug_session_flag && payloadAppId > APP_ID_NONE &&
- session->payloadAppId != payloadAppId)
- LogMessage("AppIdDbg %s URL is data %d\n", app_id_debug_session,
- payloadAppId);
- setPayloadAppIdData(session, (ApplicationId)payloadAppId, &version);
- setReferredPayloadAppIdData(session, referredPayloadAppId);
- }
- session->scan_flags &= ~SCAN_HTTP_HOST_URL_FLAG;
- }
-
- if (session->ClientAppId == APP_ID_APPLE_CORE_MEDIA)
- {
- if (session->tpPayloadAppId > APP_ID_NONE)
- {
- entry = appInfoEntryGet(session->tpPayloadAppId, pConfig);
- // only move tpPayloadAppId to client if its got a clientAppId
- if (entry->clientId > APP_ID_NONE)
- {
- session->miscAppId = session->ClientAppId;
- session->ClientAppId = session->tpPayloadAppId;
- }
- }
- else if (session->payloadAppId > APP_ID_NONE)
- {
- entry = appInfoEntryGet(session->payloadAppId, pConfig);
- // only move payloadAppId to client if it has a ClientAppid
- if (entry->clientId > APP_ID_NONE)
- {
- session->miscAppId = session->ClientAppId;
- session->ClientAppId = session->payloadAppId;
- }
- }
- }
-
- clearMiscHttpFlags(session);
- } // end DON'T skip_simple_detect
-
- return 0;
-}
-
-static inline void stopRnaServiceInspection(Packet* p, AppIdData* session, int direction)
-{
- if (direction == APP_ID_FROM_INITIATOR)
- {
- session->service_ip = *p->ptrs.ip_api.get_dst();
- session->service_port = p->ptrs.dp;
- }
- else
- {
- session->service_ip = *p->ptrs.ip_api.get_src();
- session->service_port = p->ptrs.sp;
- }
-
- session->rnaServiceState = RNA_STATE_FINISHED;
- setAppIdFlag(session, APPID_SESSION_SERVICE_DETECTED);
- clearAppIdFlag(session, APPID_SESSION_CONTINUE);
-}
-
-static inline bool isSslDecryptionEnabled(AppIdData* session)
-{
- if (getAppIdFlag(session, APPID_SESSION_DECRYPTED))
- return 1;
-// FIXIT-M J bad bad bad
-// #ifdef UNIT_TEST
-// if (session->session_packet_count >= 12)
-// return 1;
-// return 0;
-// #else
- return session->ssn->is_proxied();
-// #endif
-}
-
-static inline void checkRestartAppDetection(AppIdData* session)
-{
- if (getAppIdFlag(session, APPID_SESSION_DECRYPTED))
- return;
- if (!isSslDecryptionEnabled(session))
- return;
-
- AppId serviceAppId = pickServiceAppId(session);
-#ifdef REMOVED_WHILE_NOT_IN_USE
- isSslServiceAppId(serviceAppId);
-#else
- bool isSsl = false;
-#endif
-
- // A session could either:
- // 1. Start of as SSL - captured with isSsl flag, OR
- // 2. It could start of as a non-SSL session and later change to SSL. For example, FTP->FTPS.
- // In this case APPID_SESSION_ENCRYPTED flag is set by the protocol state machine.
- if (getAppIdFlag(session, APPID_SESSION_ENCRYPTED) || isSsl)
- {
- setAppIdFlag(session, APPID_SESSION_DECRYPTED);
- session->encrypted.serviceAppId = serviceAppId;
- session->encrypted.payloadAppId = pickPayloadId(session);
- session->encrypted.ClientAppId = pickClientAppId(session);
- session->encrypted.miscAppId = pickMiscAppId(session);
- session->encrypted.referredAppId = pickReferredPayloadId(session);
- appSharedReInitData(session);
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s SSL decryption is available, restarting app Detection\n",
- app_id_debug_session);
-
- // APPID_SESSION_ENCRYPTED is set upon receiving a command which upgrades the session to
- // SSL.
- // Next packet after the command will have encrypted traffic.
- // In the case of a session which starts as SSL, current packet itself is encrypted. Set
- // the special flag
- // APPID_SESSION_APP_REINSPECT_SSL which allows reinspection of this pcaket.
- if (isSsl)
- setAppIdFlag(session, APPID_SESSION_APP_REINSPECT_SSL);
- }
-}
-
-static inline void updateEncryptedAppId(AppIdData* session, AppId serviceAppId)
-{
- switch (serviceAppId)
- {
- case APP_ID_HTTP:
- if (session->miscAppId == APP_ID_NSIIOPS || session->miscAppId == APP_ID_DDM_SSL
- || session->miscAppId == APP_ID_MSFT_GC_SSL || session->miscAppId ==
- APP_ID_SF_APPLIANCE_MGMT)
- {
- break;
- }
- session->miscAppId = APP_ID_HTTPS;
- break;
- case APP_ID_SMTP:
- session->miscAppId = APP_ID_SMTPS;
- break;
- case APP_ID_NNTP:
- session->miscAppId = APP_ID_NNTPS;
- break;
- case APP_ID_IMAP:
- session->miscAppId = APP_ID_IMAPS;
- break;
- case APP_ID_SHELL:
- session->miscAppId = APP_ID_SSHELL;
- break;
- case APP_ID_LDAP:
- session->miscAppId = APP_ID_LDAPS;
- break;
- case APP_ID_FTP_DATA:
- session->miscAppId = APP_ID_FTPSDATA;
- break;
- case APP_ID_FTP:
- session->miscAppId = APP_ID_FTPS;
- break;
- case APP_ID_TELNET:
- session->miscAppId = APP_ID_TELNET;
- break;
- case APP_ID_IRC:
- session->miscAppId = APP_ID_IRCS;
- break;
- case APP_ID_POP3:
- session->miscAppId = APP_ID_POP3S;
- break;
- default:
- break;
- }
-}
-
-// FIXIT - H Refactor to get this to work with SSL in snort++ environment
-//static inline void ExamineSslMetadata(Packet* p, AppIdData* session, AppIdConfig* pConfig)
-static inline void ExamineSslMetadata(Packet*, AppIdData*, AppIdConfig*)
-{
-#ifdef REMOVED_WHILE_NOT_IN_USE
- size_t size;
- int ret;
- AppId clientAppId = 0;
- AppId payloadAppId = 0;
-
- if ((session->scan_flags & SCAN_SSL_HOST_FLAG) && session->tsession->tls_host)
- {
- size = strlen(session->tsession->tls_host);
- if ((ret = ssl_scan_hostname((const u_int8_t*)session->tsession->tls_host, size,
- &clientAppId, &payloadAppId, &pConfig->serviceSslConfig)))
- {
- setClientAppIdData(session, clientAppId, nullptr);
- setPayloadAppIdData(session, (ApplicationId)payloadAppId, nullptr);
- setSSLSquelch(p, ret, (ret == 1 ? payloadAppId : clientAppId));
- }
- session->scan_flags &= ~SCAN_SSL_HOST_FLAG;
- // ret = 0;
- }
- if (session->tsession->tls_cname)
- {
- size = strlen(session->tsession->tls_cname);
- if ((ret = ssl_scan_cname((const u_int8_t*)session->tsession->tls_cname, size,
- &clientAppId, &payloadAppId, &pConfig->serviceSslConfig)))
- {
- setClientAppIdData(session, clientAppId, nullptr);
- setPayloadAppIdData(session, (ApplicationId)payloadAppId, nullptr);
- setSSLSquelch(p, ret, (ret == 1 ? payloadAppId : clientAppId));
- }
- snort_free(session->tsession->tls_cname);
- session->tsession->tls_cname = nullptr;
- // ret = 0;
- }
- if (session->tsession->tls_orgUnit)
- {
- size = strlen(session->tsession->tls_orgUnit);
- if ((ret = ssl_scan_cname((const u_int8_t*)session->tsession->tls_orgUnit, size,
- &clientAppId, &payloadAppId, &pConfig->serviceSslConfig)))
- {
- setClientAppIdData(session, clientAppId, nullptr);
- setPayloadAppIdData(session, (ApplicationId)payloadAppId, nullptr);
- setSSLSquelch(p, ret, (ret == 1 ? payloadAppId : clientAppId));
- }
- snort_free(session->tsession->tls_orgUnit);
- session->tsession->tls_orgUnit = nullptr;
- // ret = 0;
- }
-#endif
-}
-
-static inline int RunClientDetectors(AppIdData* session,
- Packet* p,
- int direction,
- AppIdConfig* pConfig)
-{
- int ret = CLIENT_APP_INPROCESS;
-
- if (session->clientData != nullptr)
- {
- ret = session->clientData->validate(p->data, p->dsize, direction,
- session, p, session->clientData->userData, pConfig);
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s %s client detector returned %d\n", app_id_debug_session,
- session->clientData->name ? session->clientData->name : "UNKNOWN", ret);
- }
- else if ( (session->candidate_client_list != nullptr)
- && (sflist_count(session->candidate_client_list) > 0) )
- {
- SF_LNODE* node;
- RNAClientAppModule* client;
-
- ret = CLIENT_APP_INPROCESS;
- (void)sflist_first(session->candidate_client_list, &node);
- while (node != nullptr)
- {
- int result;
- SF_LNODE* node_tmp;
-
- client = (RNAClientAppModule*)node->ndata;
- result = client->validate(p->data, p->dsize, direction,
- session, p, client->userData, pConfig);
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s %s client detector returned %d\n", app_id_debug_session,
- client->name ? client->name : "UNKNOWN", result);
-
- node_tmp = node;
- sflist_next(&node);
- if (result == CLIENT_APP_SUCCESS)
- {
- ret = CLIENT_APP_SUCCESS;
- session->clientData = client;
- sflist_free(session->candidate_client_list);
- session->candidate_client_list = nullptr;
- break; /* done */
- }
- else if (result != CLIENT_APP_INPROCESS) /* fail */
- {
- sflist_remove_node(session->candidate_client_list, node_tmp);
- }
- }
- }
-
- return ret;
-}
-
-static inline void getOffsetsFromRebuilt(Packet* pkt, httpSession* hsession)
-{
-// size of "GET /\r\n\r\n"
-#define MIN_HTTP_REQ_HEADER_SIZE 9
- const uint8_t cookieStr[] = "Cookie: ";
- unsigned cookieStrLen = sizeof(cookieStr)-1;
- const uint8_t crlf[] = "\r\n";
- unsigned crlfLen = sizeof(crlf)-1;
- const uint8_t crlfcrlf[] = "\r\n\r\n";
- unsigned crlfcrlfLen = sizeof(crlfcrlf)-1;
- const uint8_t* p;
- uint8_t* headerEnd;
- uint16_t headerSize;
-
- if (!pkt || !pkt->data || pkt->dsize < MIN_HTTP_REQ_HEADER_SIZE)
- return;
-
- p = pkt->data;
-
- if (!(headerEnd = (uint8_t*)service_strstr(p, pkt->dsize, crlfcrlf, crlfcrlfLen)))
- return;
-
- headerEnd += crlfcrlfLen;
-
- headerSize = headerEnd - p;
-
- //uri offset is the index of the first char after the first space in the data
- if (!(p = (uint8_t*)memchr(pkt->data, ' ', headerSize)))
- return;
- hsession->uriOffset = ++p - pkt->data;
- headerSize = headerEnd - p;
-
- //uri end offset is the index of the first CRLF sequence after uri offset
- if (!(p = (uint8_t*)service_strstr(p, headerSize, crlf, crlfLen)))
- {
- // clear uri offset if we can't find an end offset
- hsession->uriOffset = 0;
- return;
- }
- hsession->uriEndOffset = p - pkt->data;
- headerSize = headerEnd - p;
-
- //cookie offset is the index of the first char after the cookie header, "Cookie: "
- if (!(p = (uint8_t*)service_strstr(p, headerSize, cookieStr, cookieStrLen)))
- return;
- hsession->cookieOffset = p + cookieStrLen - pkt->data;
- headerSize = headerEnd - p;
-
- //cookie end offset is the index of the first CRLF sequence after cookie offset
- if (!(p = (uint8_t*)service_strstr(p, headerSize, crlf, crlfLen)))
- {
- // clear cookie offset if we can't find a cookie end offset
- hsession->cookieOffset = 0;
- return;
- }
- hsession->cookieEndOffset = p - pkt->data;
-}
-
-static int16_t snortId_for_ftp;
-static int16_t snortId_for_ftp_data;
-static int16_t snortId_for_imap;
-static int16_t snortId_for_pop3;
-static int16_t snortId_for_smtp;
-static int16_t snortId_for_http2;
-
-static inline void synchAppIdWithSnortId(AppId newAppId, Packet* p, AppIdData* session,
- AppIdConfig* pConfig)
-{
- AppInfoTableEntry* entry;
- int16_t tempSnortId = session->snortId;
-
- if (tempSnortId == UNSYNCED_SNORT_ID)
- {
- tempSnortId = session->snortId = p->flow->ssn_state.application_protocol;
- }
-
- if (tempSnortId == snortId_for_ftp || tempSnortId == snortId_for_ftp_data ||
- tempSnortId == snortId_for_imap || tempSnortId == snortId_for_pop3 ||
- tempSnortId == snortId_for_smtp || tempSnortId == snortId_for_http2)
- {
- return; // These preprocessors, in snort proper, already know and expect these to remain
- // unchanged.
- }
- if ((entry = appInfoEntryGet(newAppId, pConfig)) && (tempSnortId = entry->snortId))
- {
- // Snort has a separate protocol ID for HTTP/2. We don't. So, when we
- // talk to them about it, we have to play by their rules.
- if ((newAppId == APP_ID_HTTP) && (session->is_http2))
- tempSnortId = snortId_for_http2;
-
- if (tempSnortId != session->snortId)
- {
- if (app_id_debug_session_flag)
- if (tempSnortId == snortId_for_http2)
- LogMessage("AppIdDbg %s Telling Snort that it's HTTP/2\n",
- app_id_debug_session);
-
- p->flow->ssn_state.application_protocol = tempSnortId;
- session->snortId = tempSnortId;
- }
- }
-}
-
-static inline void checkTerminateTpModule(uint16_t tpPktCount, AppIdData* session)
-{
- if ((tpPktCount >= pAppidActiveConfig->mod_config->max_tp_flow_depth) ||
- (getAppIdFlag(session, APPID_SESSION_HTTP_SESSION | APPID_SESSION_APP_REINSPECT) ==
- (APPID_SESSION_HTTP_SESSION | APPID_SESSION_APP_REINSPECT) &&
- session->hsession && session->hsession->uri &&
- (!session->hsession->chp_candidate || session->hsession->chp_finished)))
- {
- if (session->tpAppId == APP_ID_NONE)
- session->tpAppId = APP_ID_UNKNOWN;
- if (session->payloadAppId == APP_ID_NONE)
- session->payloadAppId = APP_ID_UNKNOWN;
- if (thirdparty_appid_module)
- thirdparty_appid_module->session_delete(session->tpsession, 1);
- }
-}
-
-//#define DEBUG_PACKETS
-#ifdef DEBUG_PACKETS
-#define printSnortPacket(SFSnortPacket_ptr) debug_printSnortPacket(SFSnortPacket_ptr)
-
-#define CHAR_DUMP_WIDTH 60
-static inline void debug_printSnortPacket(SFSnortPacket* p)
-{
- if (app_id_debug_flag)
- {
- char* tweakedPayload;
- char* hexPayload;
- LogMessage("AppIdDbg \n");
- LogMessage("AppIdDbg ------------------------------------------------\n");
- LogMessage("AppIdDbg \n");
- if (p->data != nullptr && p->dsize)
- {
- tweakedPayload= (char*)snort_calloc((CHAR_DUMP_WIDTH*2)+1); // room for hex
- if (tweakedPayload)
- {
- int j;
- int i;
- LogMessage("AppIdDbg data: (%d chars per line)\n",CHAR_DUMP_WIDTH);
- for (j=0; j<p->dsize; j+=CHAR_DUMP_WIDTH)
- {
- for (i=j; i<p->dsize && i<(j+CHAR_DUMP_WIDTH); i++)
- {
- if ((int)p->data[i] >= 32 && (int)p->data[i] <=126)
- tweakedPayload[i-j] = p->data[i];
- else
- tweakedPayload[i-j] = '.';
- }
- tweakedPayload[i-j] = '\0';
- LogMessage("AppIdDbg %s\n", tweakedPayload);
- }
-//#define DUMP_IN_HEX
-#ifdef DUMP_IN_HEX
- LogMessage("AppIdDbg HEX data: (%d chars per line)\n",CHAR_DUMP_WIDTH);
- for (j=0; j<p->dsize; j+=CHAR_DUMP_WIDTH)
- {
- for (i=j; i<p->dsize && i<(j+CHAR_DUMP_WIDTH); i++)
- {
- sprintf(&tweakedPayload[(i-j)*2], "%02x", (p->data)[i]);
- }
- // terminating '\0' provided by sprintf()
- LogMessage("AppIdDbg %s\n", tweakedPayload);
- }
-#endif
- snort_free(tweakedPayload); tweakedPayload = nullptr;
- }
- }
- if (p->flow)
- {
- LogMessage(
- "AppIdDbg \nAppIdDbg for p->flow=%p is_session_decrypted=%d direction=%d\n",
- p->flow, _dpd.streamAPI->is_session_decrypted(p->flow),
- _dpd.sessionAPI->get_ignore_direction(p->flow));
- }
-
- LogMessage("AppIdDbg ptrs.sp: %d\n", p->ptrs.sp);
- LogMessage("AppIdDbg ptrs.dp: %d\n", p->ptrs.dp);
- LogMessage("AppIdDbg orig_src_port: %d\n", p->orig_src_port);
- LogMessage("AppIdDbg rig_dst_port: %d\n", p->orig_dst_port);
- LogMessage("AppIdDbg payloadsize: %d\n", p->dsize);
-
- if ((p->packet_flags) & 0x00000080)
- {
- LogMessage("AppIdDbg direction: client\n");
- }
- else if ((p->packet_flags) & 0x00000040)
- {
- LogMessage("AppIdDbg direction: server\n");
- }
- else
- {
- LogMessage("AppIdDbg direction: unknown\n");
- }
-
- if ((p->packet_flags) & 0x00000001)
- LogMessage("AppIdDbg A rebuilt fragment\n");
- if ((p->packet_flags) & 0x00000002)
- LogMessage("AppIdDbg A rebuilt stream\n");
- if ((p->packet_flags) & 0x00000004)
- LogMessage(
- "AppIdDbg From an unestablished stream, traffic send one direction only\n");
- if ((p->packet_flags) & 0x00000008)
- LogMessage("AppIdDbg From an established stream\n");
- if ((p->packet_flags) & 0x00000010)
- LogMessage("AppIdDbg this packet has been queued for stream reassembly\n");
- if ((p->packet_flags) & 0x00000020)
- LogMessage("AppIdDbg packet completes the 3 way handshake\n");
- if ((p->packet_flags) & 0x00000040)
- LogMessage("AppIdDbg packet come from server side of a connection(tcp)\n");
- if ((p->packet_flags) & 0x00000080)
- LogMessage("AppIdDbg packet come from client side of a connection(tcp)\n");
- if ((p->packet_flags) & 0x00000100)
- LogMessage("AppIdDbg start of PDU\n");
- if ((p->packet_flags) & 0x00000200)
- LogMessage("AppIdDbg end of PDU\n");
- if ((p->packet_flags) & 0x00800000)
- LogMessage("AppIdDbg packet has new size\n");
- }
-}
-
-#else
-#define printSnortPacket(SFSnortPacket_ptr)
-#endif
-
-void fwAppIdInit()
-{
- /* init globals for snortId compares */
- snortId_for_ftp = FindProtocolReference("ftp");
- snortId_for_ftp_data = FindProtocolReference("ftp-data");
- snortId_for_imap = FindProtocolReference("imap");
- snortId_for_pop3 = FindProtocolReference("pop3");
- snortId_for_smtp = FindProtocolReference("smtp");
- snortId_for_http2 = FindProtocolReference("http2");
-}
-
-void fwAppIdSearch(Packet* p)
-{
- AppIdData* session;
- IpProtocol protocol;
- AppId tpAppId = 0;
- AppId serviceAppId = 0;
- AppId ClientAppId = 0;
- AppId payloadAppId = 0;
- bool isTpAppidDiscoveryDone = false;
- uint64_t flow_flags;
- int direction;
- const sfip_t* ip;
- uint16_t port;
- size_t size;
- int tp_confidence;
- AppId* tp_proto_list;
- ThirdPartyAppIDAttributeData* tp_attribute_data;
- AppInfoTableEntry* entry;
- AppIdConfig* pConfig = pAppidActiveConfig;
- bool is_decrypted;
- bool is_rebuilt;
- bool is_http2;
-
- app_id_raw_packet_count++;
-
- if (!p->flow)
- {
- app_id_ignored_packet_count++;
- return;
- }
-
- is_decrypted = p->flow->is_proxied();
- is_rebuilt = p->is_rebuilt();
-// FIXIT-M - Need to convert this _dpd stream api call to the correct snort++ method
-#ifdef REMOVED_WHILE_NOT_IN_USE
- is_http2 = _dpd.streamAPI->is_session_http2(p->flow);
-#else
- is_http2 = false;
-#endif
- if (is_http2)
- {
- session = getAppIdData(p->flow);
- if (session)
- session->is_http2 = true;
- if (!is_rebuilt)
- {
- // For HTTP/2, we only want to look at the ones that are rebuilt from
- // Stream / HTTP Inspect as HTTP/1 packets.
- app_id_ignored_packet_count++;
- return;
- }
- }
- else // not HTTP/2
- {
- if (is_rebuilt && !is_decrypted)
- {
- session = getAppIdData(p->flow);
- if (session && session->hsession && session->hsession->get_offsets_from_rebuilt)
- {
- getOffsetsFromRebuilt(p, session->hsession);
- if (app_id_debug_session_flag)
- LogMessage(
- "AppIdDbg %s offsets from rebuilt packet: uri: %u-%u cookie: %u-%u\n",
- app_id_debug_session, session->hsession->uriOffset,
- session->hsession->uriEndOffset, session->hsession->cookieOffset,
- session->hsession->cookieEndOffset);
- }
- app_id_ignored_packet_count++;
- return;
- }
- }
-
- session = appSharedGetData(p);
- if (session)
- {
- if (session->common.fsf_type.flow_type == APPID_SESSION_TYPE_IGNORE)
- return;
- if (session->common.fsf_type.flow_type == APPID_SESSION_TYPE_NORMAL)
- {
- protocol = session->proto;
- session->ssn = p->flow;
- }
- else if (p->is_tcp())
- protocol = IpProtocol::TCP;
- else
- protocol = IpProtocol::UDP;
-
- ip = p->ptrs.ip_api.get_src();
- if (session->common.initiator_port)
- direction = (session->common.initiator_port == p->ptrs.sp) ? APP_ID_FROM_INITIATOR :
- APP_ID_FROM_RESPONDER;
- else
- direction = (sfip_fast_equals_raw(ip, &session->common.initiator_ip)) ?
- APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
- }
- else
- {
- if (p->is_tcp())
- protocol = IpProtocol::TCP;
- else if (p->is_udp())
- protocol = IpProtocol::UDP;
- else if ( p->is_ip4() || p->is_ip6() )
- protocol = p->get_ip_proto_next();
- else
- return;
-
- // FIXIT - L Refactor to use direction symbols defined by snort proper
- direction = p->is_from_client() ? APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
- }
-
- app_id_debug_session_flag = fwAppIdDebugCheck(p->flow, session, app_id_debug_flag,
- &app_id_debug_info, app_id_debug_session, direction);
- //if (app_id_debug_session_flag)
- // LogMessage("AppIdDbg %s flag:%08x,decrypt:%s,http2:%s\n", app_id_debug_session,
- // p->packet_flags, is_decrypted?"T":"F", is_http2?"T":"F");
-
- // fwAppIdSearch() is a top-level function that is called by AppIdProcess().
- // At this point, we know that we need to use the current active config -
- // pAppidActiveConfig. This function uses pAppidActiveConfig and passes it
- // to all the functions that need to look at AppId config.
- flow_flags = isSessionMonitored(p, direction, session);
- if (!(flow_flags & (APPID_SESSION_DISCOVER_APP | APPID_SESSION_SPECIAL_MONITORED)))
- {
- if (!session)
- {
- if ((flow_flags & APPID_SESSION_BIDIRECTIONAL_CHECKED) ==
- APPID_SESSION_BIDIRECTIONAL_CHECKED)
- {
- // FIXIT-M: This _dpd call needs to be convert to correct snort++ call
- // static THREAD_LOCAL APPID_SESSION_STRUCT_FLAG ignore_fsf {
- // APPID_SESSION_TYPE_IGNORE };
-
- // _dpd.sessionAPI->set_application_data(p->flow, PP_APP_ID, &ignore_fsf,
- // nullptr);
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s not monitored\n", app_id_debug_session);
- }
- else
- {
- AppIdData* tmp_session;
-
- tmp_session = (decltype(tmp_session))snort_calloc(sizeof(AppIdData));
-
- tmp_session->common.fsf_type.flow_type = APPID_SESSION_TYPE_TMP;
- tmp_session->common.flags = flow_flags;
- ip = (direction == APP_ID_FROM_INITIATOR) ?
- p->ptrs.ip_api.get_src() : p->ptrs.ip_api.get_dst();
- tmp_session->common.initiator_ip = *ip;
- if ( (protocol == IpProtocol::TCP || protocol == IpProtocol::UDP ) &&
- p->ptrs.sp != p->ptrs.dp )
- {
- tmp_session->common.initiator_port = (direction == APP_ID_FROM_INITIATOR) ?
- p->ptrs.sp : p->ptrs.dp;
- }
- else
- tmp_session->common.initiator_port = 0;
- tmp_session->common.policyId = appIdPolicyId;
- p->flow->set_application_data(tmp_session);
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s unknown monitoring\n", app_id_debug_session);
- }
- }
- else
- {
- session->common.flags = flow_flags;
- if ((flow_flags & APPID_SESSION_BIDIRECTIONAL_CHECKED) ==
- APPID_SESSION_BIDIRECTIONAL_CHECKED)
- session->common.fsf_type.flow_type = APPID_SESSION_TYPE_IGNORE;
- session->common.policyId = appIdPolicyId;
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s not monitored\n", app_id_debug_session);
- }
- return;
- }
-
- if (!session || session->common.fsf_type.flow_type == APPID_SESSION_TYPE_TMP)
- {
- /* This call will free the existing temporary session, if there is one */
- session = appSharedCreateData(p, protocol, direction);
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s new session\n", app_id_debug_session);
- }
-
- app_id_processed_packet_count++;
- session->session_packet_count++;
-
- if (direction == APP_ID_FROM_INITIATOR)
- session->stats.initiatorBytes += p->pkth->pktlen;
- else
- session->stats.responderBytes += p->pkth->pktlen;
-
- session->common.flags = flow_flags;
- session->common.policyId = appIdPolicyId;
-
- tpAppId = session->tpAppId;
-
- session->common.policyId = appIdPolicyId;
-
- if (getAppIdFlag(session, APPID_SESSION_IGNORE_FLOW))
- {
- if (app_id_debug_session_flag && !getAppIdFlag(session, APPID_SESSION_IGNORE_FLOW_LOGGED))
- {
- setAppIdFlag(session, APPID_SESSION_IGNORE_FLOW_LOGGED);
- LogMessage("AppIdDbg %s Ignoring connection with service %d\n",
- app_id_debug_session, session->serviceAppId);
- }
- return;
- }
-
- if (p->packet_flags & PKT_STREAM_ORDER_BAD)
- setAppIdFlag(session, APPID_SESSION_OOO);
-
- else if ( p->is_tcp() && p->ptrs.tcph )
- {
- const auto* tcph = p->ptrs.tcph;
- if ( tcph->is_rst() && session->previous_tcp_flags == TH_SYN )
- {
- AppIdServiceIDState* id_state;
-
- setAppIdFlag(session, APPID_SESSION_SYN_RST);
- if (sfip_is_set(&session->service_ip))
- {
- ip = &session->service_ip;
- port = session->service_port;
- }
- else
- {
- ip = p->ptrs.ip_api.get_src();
- port = p->ptrs.sp;
- }
-
- id_state = AppIdGetServiceIDState(ip, IpProtocol::TCP, port,
- AppIdServiceDetectionLevel(
- session));
-
- if (id_state)
- {
- if (!id_state->reset_time)
- id_state->reset_time = packet_time();
- else if ((packet_time() - id_state->reset_time) >= 60)
- {
- // FIXIT-H ip's on the packet are const
- // AppIdRemoveServiceIDState(ip, IpProtocol::TCP, port,
- // AppIdServiceDetectionLevel(session));
- setAppIdFlag(session, APPID_SESSION_SERVICE_DELETED);
- }
- }
- }
-
- session->previous_tcp_flags = p->ptrs.tcph->th_flags;
- }
-
- /*HostPort based AppId. */
- if (!(session->scan_flags & SCAN_HOST_PORT_FLAG))
- {
- HostPortVal* hv;
-
- session->scan_flags |= SCAN_HOST_PORT_FLAG;
- if (direction == APP_ID_FROM_INITIATOR)
- {
- ip = p->ptrs.ip_api.get_dst();
- port = p->ptrs.dp;
- }
- else
- {
- ip = p->ptrs.ip_api.get_src();
- port = p->ptrs.sp;
- }
-
- if ((hv = hostPortAppCacheFind(ip, port, protocol, pConfig)))
- {
- switch (hv->type)
- {
- case 1:
- session->ClientAppId = hv->appId;
- session->rnaClientState = RNA_STATE_FINISHED;
- break;
- case 2:
- session->payloadAppId = hv->appId;
- break;
- default:
- session->serviceAppId = hv->appId;
- synchAppIdWithSnortId(hv->appId, p, session, pConfig);
- session->rnaServiceState = RNA_STATE_FINISHED;
- session->rnaClientState = RNA_STATE_FINISHED;
- setAppIdFlag(session, APPID_SESSION_SERVICE_DETECTED);
- if (thirdparty_appid_module)
- thirdparty_appid_module->session_delete(session->tpsession, 1);
- session->tpsession = nullptr;
- }
- }
- }
-
- checkRestartAppDetection(session);
-
- //restart inspection by 3rd party
- if (!getAppIdFlag(session, APPID_SESSION_NO_TPI))
- {
- if (TPIsAppIdDone(session->tpsession) && getAppIdFlag(session,
- APPID_SESSION_HTTP_SESSION) && p->dsize)
- {
- if (session->tpReinspectByInitiator)
- {
- clearAppIdFlag(session, APPID_SESSION_APP_REINSPECT);
- if (direction == APP_ID_FROM_RESPONDER)
- session->tpReinspectByInitiator = 0; //toggle at OK response
- }
- else if (direction == APP_ID_FROM_INITIATOR)
- {
- session->tpReinspectByInitiator = 1; //once per request
- setAppIdFlag(session, APPID_SESSION_APP_REINSPECT);
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s 3rd party allow reinspect http\n",
- app_id_debug_session);
- session->appHttpFieldClear();
- }
- }
- }
-
- if (session->tpAppId == APP_ID_SSH && session->payloadAppId != APP_ID_SFTP &&
- session->session_packet_count >= MIN_SFTP_PACKET_COUNT && session->session_packet_count <
- MAX_SFTP_PACKET_COUNT)
- {
- if ( p->ptrs.ip_api.tos() == 8 )
- {
- session->payloadAppId = APP_ID_SFTP;
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s data is SFTP\n", app_id_debug_session);
- }
- }
-
- Profile tpPerfStats_profile_context(tpPerfStats);
-
- /*** Start of third-party processing. ***/
- if (thirdparty_appid_module &&
- !getAppIdFlag(session, APPID_SESSION_NO_TPI) &&
- (!TPIsAppIdDone(session->tpsession) ||
- getAppIdFlag(session, 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 (getAppIdFlag(session, APPID_SESSION_APP_REINSPECT_SSL))
- {
- clearAppIdFlag(session, APPID_SESSION_APP_REINSPECT_SSL);
- }
- if (p->dsize || pAppidActiveConfig->mod_config->tp_allow_probes)
- {
- if (protocol != IpProtocol::TCP || !p->dsize || (p->packet_flags &
- PKT_STREAM_ORDER_OK) ||
- pAppidActiveConfig->mod_config->tp_allow_probes)
- {
- {
- Profile tpLibPerfStats_profile_context(tpLibPerfStats);
- if (!session->tpsession)
- {
- if (!(session->tpsession = thirdparty_appid_module->session_create()))
- FatalError(
- "Could not allocate AppIdData->tpsession data");
- }
-
- printSnortPacket(p); // debug output of packet content
- thirdparty_appid_module->session_process(session->tpsession, p, direction,
- &tpAppId, &tp_confidence, &tp_proto_list, &tp_attribute_data);
- }
-
- isTpAppidDiscoveryDone = true;
- if (thirdparty_appid_module->session_state_get(session->tpsession) ==
- TP_STATE_CLASSIFIED)
- clearAppIdFlag(session, APPID_SESSION_APP_REINSPECT);
-
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s 3rd party returned %d\n", app_id_debug_session,
- tpAppId);
-
- if (appInfoEntryFlagGet(tpAppId, APPINFO_FLAG_IGNORE, pConfig))
- {
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s 3rd party ignored\n", app_id_debug_session);
- if (getAppIdFlag(session, APPID_SESSION_HTTP_SESSION))
- tpAppId = APP_ID_HTTP;
- else
- tpAppId = APP_ID_NONE;
- }
-
- // For now, third party can detect HTTP/2 (w/o metadata) for
- // some cases. Treat it like HTTP w/ is_http2 flag set.
- if ((tpAppId == APP_ID_HTTP2) && (tp_confidence == 100))
- {
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s 3rd party saw HTTP/2\n", app_id_debug_session);
- tpAppId = APP_ID_HTTP;
- session->is_http2 = true;
- }
-
- // if the third-party appId must be treated as a client, do it now
- if (appInfoEntryFlagGet(tpAppId, APPINFO_FLAG_TP_CLIENT, pAppidActiveConfig))
- session->ClientAppId = tpAppId;
-
- ProcessThirdPartyResults(p, session, tp_confidence, tp_proto_list,
- tp_attribute_data);
-#ifdef REMOVED_WHILE_NOT_IN_USE
- if (getAppIdFlag(session, APPID_SESSION_SSL_SESSION) &&
- !(session->scan_flags & SCAN_SSL_HOST_FLAG))
- {
- setSSLSquelch(p, 1, tpAppId);
- }
-#endif
- }
- else
- {
- tpAppId = APP_ID_NONE;
- if (app_id_debug_session_flag && !getAppIdFlag(session,
- APPID_SESSION_TPI_OOO_LOGGED))
- {
- setAppIdFlag(session, APPID_SESSION_TPI_OOO_LOGGED);
- LogMessage("AppIdDbg %s 3rd party packet out-of-order\n",
- app_id_debug_session);
- }
- }
-
- if (thirdparty_appid_module->session_state_get(session->tpsession) ==
- TP_STATE_MONITORING)
- {
- thirdparty_appid_module->disable_flags(session->tpsession,
- TP_SESSION_FLAG_ATTRIBUTE | TP_SESSION_FLAG_TUNNELING |
- TP_SESSION_FLAG_FUTUREFLOW);
- }
-
- if (tpAppId == APP_ID_SSL &&
- (stream.get_application_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.
- tpAppId = APP_ID_NONE;
- }
-
- if (tpAppId > APP_ID_NONE && (!getAppIdFlag(session, APPID_SESSION_APP_REINSPECT) ||
- session->payloadAppId > APP_ID_NONE))
- {
- AppId snorAppId;
-
- // if the packet is HTTP, then search for via pattern
- if (getAppIdFlag(session, APPID_SESSION_HTTP_SESSION) && session->hsession)
- {
- snorAppId = APP_ID_HTTP;
- //data should never be APP_ID_HTTP
- if (tpAppId != APP_ID_HTTP)
- session->tpPayloadAppId = tpAppId;
-
- session->tpAppId = APP_ID_HTTP;
-
- processHTTPPacket(p, session, direction, nullptr, pAppidActiveConfig);
-
- if (TPIsAppIdAvailable(session->tpsession) && session->tpAppId == APP_ID_HTTP
- && !getAppIdFlag(session, APPID_SESSION_APP_REINSPECT))
- {
- session->rnaClientState = RNA_STATE_FINISHED;
- setAppIdFlag(session, APPID_SESSION_CLIENT_DETECTED |
- APPID_SESSION_SERVICE_DETECTED);
- session->rnaServiceState = RNA_STATE_FINISHED;
- clearAppIdFlag(session, APPID_SESSION_CONTINUE);
- if (direction == APP_ID_FROM_INITIATOR)
- {
- ip = p->ptrs.ip_api.get_dst();
- session->service_ip = *ip;
- session->service_port = p->ptrs.dp;
- }
- else
- {
- ip = p->ptrs.ip_api.get_src();
- session->service_ip = *ip;
- session->service_port = p->ptrs.sp;
- }
- }
- }
- else if (getAppIdFlag(session, APPID_SESSION_SSL_SESSION) && session->tsession)
- {
- ExamineSslMetadata(p, session, pConfig);
-
- uint16_t serverPort;
- AppId porAppId;
-
- serverPort = (direction == APP_ID_FROM_INITIATOR) ? p->ptrs.dp : p->ptrs.sp;
-
-#ifdef REMOVED_WHILE_NOT_IN_USE
- porAppId = getSslServiceAppId(serverPort);
-#else
- porAppId = serverPort;
-#endif
- if (tpAppId == APP_ID_SSL )
- {
- tpAppId = porAppId;
-
- //SSL policy needs to determine IMAPS/POP3S etc before appId sees first
- // server packet
- session->portServiceAppId = porAppId;
-
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s SSL is service %d, portServiceAppId %d\n",
- app_id_debug_session, tpAppId, session->portServiceAppId);
- }
- else
- {
- session->tpPayloadAppId = tpAppId;
- tpAppId = porAppId;
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s SSL is %d\n", app_id_debug_session, tpAppId);
- }
- session->tpAppId = tpAppId;
- snorAppId = APP_ID_SSL;
- }
- else
- {
- //for non-http protocols, tp id is treated like serviceId
-
- snorAppId = tpAppId;
- session->tpAppId = tpAppId;
- }
-
- synchAppIdWithSnortId(snorAppId, p, session, pConfig);
- }
- else
- {
- if ( protocol != IpProtocol::TCP || !p->dsize ||
- (p->packet_flags & (PKT_STREAM_ORDER_OK | PKT_STREAM_ORDER_BAD)))
- {
- if (direction == APP_ID_FROM_INITIATOR)
- {
- session->init_tpPackets++;
- checkTerminateTpModule(session->init_tpPackets, session);
- }
- else
- {
- session->resp_tpPackets++;
- checkTerminateTpModule(session->resp_tpPackets, session);
- }
- }
- }
- }
- }
-
- if (direction == APP_ID_FROM_RESPONDER && !getAppIdFlag(session,
- APPID_SESSION_PORT_SERVICE_DONE|APPID_SESSION_SYN_RST))
- {
- setAppIdFlag(session, APPID_SESSION_PORT_SERVICE_DONE);
- session->portServiceAppId = getPortServiceId(protocol, p->ptrs.sp, pConfig);
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s port service %d\n", app_id_debug_session,
- session->portServiceAppId);
- }
-
- /* Length-based detectors. */
- /* Only check if:
- * - Port service didn't find anything (and we haven't yet either).
- * - We haven't hit the max packets allowed for detector sequence matches.
- * - Packet has data (we'll ignore 0-sized packets in sequencing). */
- if ( (session->portServiceAppId <= APP_ID_NONE)
- && (session->length_sequence.sequence_cnt < LENGTH_SEQUENCE_CNT_MAX)
- && (p->dsize > 0))
- {
- uint8_t index = session->length_sequence.sequence_cnt;
- session->length_sequence.proto = protocol;
- session->length_sequence.sequence_cnt++;
- session->length_sequence.sequence[index].direction = direction;
- session->length_sequence.sequence[index].length = p->dsize;
- session->portServiceAppId = lengthAppCacheFind(&session->length_sequence, pConfig);
- if (session->portServiceAppId > APP_ID_NONE)
- {
- setAppIdFlag(session, APPID_SESSION_PORT_SERVICE_DONE);
- }
- }
-
- /* exceptions for rexec and any other service detector that needs to see SYN and SYN/ACK */
- if (getAppIdFlag(session, APPID_SESSION_REXEC_STDERR))
- {
- AppIdDiscoverService(p, direction, session, pConfig);
- if (session->serviceAppId == APP_ID_DNS &&
- pAppidActiveConfig->mod_config->dns_host_reporting &&
- session->dsession && session->dsession->host )
- {
- size = session->dsession->host_len;
- dns_host_scan_hostname((const u_int8_t*)session->dsession->host, size, &ClientAppId,
- &payloadAppId, &pConfig->serviceDnsConfig);
- setClientAppIdData(session, ClientAppId, nullptr);
- }
- else if (session->serviceAppId == APP_ID_RTMP)
- ExamineRtmpMetadata(session);
- else if (getAppIdFlag(session, APPID_SESSION_SSL_SESSION) && session->tsession)
- ExamineSslMetadata(p, session, pConfig);
- }
- else if (protocol != IpProtocol::TCP || !p->dsize || (p->packet_flags & PKT_STREAM_ORDER_OK))
- {
- /*** Start of service discovery. ***/
- if (session->rnaServiceState != RNA_STATE_FINISHED)
- {
- Profile serviceMatchPerfStats_profile_context(serviceMatchPerfStats);
-
- uint32_t prevRnaServiceState;
-
- tpAppId = session->tpAppId;
- prevRnaServiceState = session->rnaServiceState;
-
- //decision to directly call validator or go through elaborate service_state tracking
- //is made once at the beginning of sesssion.
- if (session->rnaServiceState == RNA_STATE_NONE && p->dsize)
- {
- if ( p->flow->get_session_flags() & SSNFLAG_MIDSTREAM )
- {
- // Unless it could be ftp control
- if ( protocol == IpProtocol::TCP && (p->ptrs.sp == 21 || p->ptrs.dp == 21) &&
- !(p->ptrs.tcph->is_fin() || p->ptrs.tcph->is_rst()) )
- {
- setAppIdFlag(session, APPID_SESSION_CLIENT_DETECTED |
- APPID_SESSION_NOT_A_SERVICE | APPID_SESSION_SERVICE_DETECTED);
- if (!AddFTPServiceState(session))
- {
- setAppIdFlag(session, APPID_SESSION_CONTINUE);
- if (p->ptrs.dp != 21)
- setAppIdFlag(session, APPID_SESSION_RESPONDER_SEEN);
- }
- session->rnaServiceState = RNA_STATE_STATEFUL;
- }
- else
- {
- setAppIdFlag(session, APPID_SESSION_MID | APPID_SESSION_SERVICE_DETECTED);
- session->rnaServiceState = RNA_STATE_FINISHED;
- }
- }
- else if (TPIsAppIdAvailable(session->tpsession))
- {
- if (tpAppId > APP_ID_NONE)
- {
- //tp has positively identified appId, Dig deeper only if sourcefire
- // detector identifies additional information or flow is UDP reveresed.
- if ((entry = appInfoEntryGet(tpAppId, pConfig))
- && entry->svrValidator &&
- ((entry->flags & APPINFO_FLAG_SERVICE_ADDITIONAL) ||
- ((entry->flags & APPINFO_FLAG_SERVICE_UDP_REVERSED) && protocol ==
- IpProtocol::UDP &&
- getAppIdFlag(session, APPID_SESSION_INITIATOR_MONITORED |
- APPID_SESSION_RESPONDER_MONITORED))))
- {
- AppIdFlowdataDeleteAllByMask(session,
- APPID_SESSION_DATA_SERVICE_MODSTATE_BIT);
-
- session->serviceData = entry->svrValidator;
- session->rnaServiceState = RNA_STATE_STATEFUL;
- }
- else
- {
- stopRnaServiceInspection(p, session, direction);
- }
- }
- else
- session->rnaServiceState = RNA_STATE_STATEFUL;
- }
- else
- session->rnaServiceState = RNA_STATE_STATEFUL;
- }
-
- //stop rna inspection as soon as tp has classified a valid AppId later in the session
- if (session->rnaServiceState == RNA_STATE_STATEFUL &&
- prevRnaServiceState == RNA_STATE_STATEFUL &&
- !getAppIdFlag(session, APPID_SESSION_NO_TPI) &&
- TPIsAppIdAvailable(session->tpsession) &&
- tpAppId > APP_ID_NONE && tpAppId < SF_APPID_MAX)
- {
- entry = appInfoEntryGet(tpAppId, pConfig);
- if (entry && entry->svrValidator
- && !(entry->flags & APPINFO_FLAG_SERVICE_ADDITIONAL))
- {
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s Stop service detection\n", app_id_debug_session);
- stopRnaServiceInspection(p, session, direction);
- }
- }
-
- if (session->rnaServiceState == RNA_STATE_STATEFUL)
- {
- AppIdDiscoverService(p, direction, session, pConfig);
- isTpAppidDiscoveryDone = true;
- //to stop executing validator after service has been detected by RNA.
- if (getAppIdFlag(session, APPID_SESSION_SERVICE_DETECTED |
- APPID_SESSION_CONTINUE) == APPID_SESSION_SERVICE_DETECTED)
- session->rnaServiceState = RNA_STATE_FINISHED;
-
- if (session->serviceAppId == APP_ID_DNS &&
- pAppidActiveConfig->mod_config->dns_host_reporting &&
- session->dsession && session->dsession->host )
- {
- size = session->dsession->host_len;
- dns_host_scan_hostname((const u_int8_t*)session->dsession->host, size,
- &ClientAppId, &payloadAppId, &pConfig->serviceDnsConfig);
- setClientAppIdData(session, ClientAppId, nullptr);
- }
- else if (session->serviceAppId == APP_ID_RTMP)
- ExamineRtmpMetadata(session);
- else if (getAppIdFlag(session, APPID_SESSION_SSL_SESSION) && session->tsession)
- ExamineSslMetadata(p, session, pConfig);
-
- if (tpAppId <= APP_ID_NONE &&
- getAppIdFlag(session, APPID_SESSION_SERVICE_DETECTED |
- APPID_SESSION_NOT_A_SERVICE | APPID_SESSION_IGNORE_HOST) ==
- APPID_SESSION_SERVICE_DETECTED)
- {
- synchAppIdWithSnortId(session->serviceAppId, p, session, pConfig);
- }
- }
- }
- /*** End of service discovery. ***/
-
- /*** Start of client discovery. ***/
- if (session->rnaClientState != RNA_STATE_FINISHED)
- {
- Profile clientMatchPerfStats_profile_context(clientMatchPerfStats);
- uint32_t prevRnaClientState = session->rnaClientState;
- bool was_http2 = session->is_http2;
- bool was_service = getAppIdFlag(session, APPID_SESSION_SERVICE_DETECTED) ? true :
- false;
-
- //decision to directly call validator or go through elaborate service_state tracking
- //is made once at the beginning of sesssion.
- if (session->rnaClientState == RNA_STATE_NONE && p->dsize && direction ==
- APP_ID_FROM_INITIATOR)
- {
- if ( p->flow->get_session_flags() & SSNFLAG_MIDSTREAM )
- session->rnaClientState = RNA_STATE_FINISHED;
-
- else if (TPIsAppIdAvailable(session->tpsession) && (tpAppId = session->tpAppId) >
- APP_ID_NONE && tpAppId < SF_APPID_MAX)
- {
- AppInfoTableEntry* entry;
-
- if ((entry = appInfoEntryGet(tpAppId, pConfig)) && entry->clntValidator &&
- ((entry->flags & APPINFO_FLAG_CLIENT_ADDITIONAL) ||
- ((entry->flags & APPINFO_FLAG_CLIENT_USER) &&
- getAppIdFlag(session, APPID_SESSION_DISCOVER_USER))))
- {
- //tp has positively identified appId, Dig deeper only if sourcefire
- // detector
- //identifies additional information
- session->clientData = entry->clntValidator;
- session->rnaClientState = RNA_STATE_DIRECT;
- }
- else
- {
- setAppIdFlag(session, APPID_SESSION_CLIENT_DETECTED);
- session->rnaClientState = RNA_STATE_FINISHED;
- }
- }
- else if (getAppIdFlag(session, APPID_SESSION_HTTP_SESSION))
- session->rnaClientState = RNA_STATE_FINISHED;
- else
- session->rnaClientState = RNA_STATE_STATEFUL;
- }
-
- //stop rna inspection as soon as tp has classified a valid AppId later in the session
- if ((session->rnaClientState == RNA_STATE_STATEFUL ||
- session->rnaClientState == RNA_STATE_DIRECT) &&
- session->rnaClientState == prevRnaClientState &&
- !getAppIdFlag(session, APPID_SESSION_NO_TPI) &&
- TPIsAppIdAvailable(session->tpsession) &&
- tpAppId > APP_ID_NONE && tpAppId < SF_APPID_MAX)
- {
- entry = appInfoEntryGet(tpAppId, pConfig);
-
- if (!(entry && entry->clntValidator && entry->clntValidator ==
- session->clientData && (entry->flags & (APPINFO_FLAG_CLIENT_ADDITIONAL|
- APPINFO_FLAG_CLIENT_USER))))
- {
- session->rnaClientState = RNA_STATE_FINISHED;
- setAppIdFlag(session, APPID_SESSION_CLIENT_DETECTED);
- }
- }
-
- if (session->rnaClientState == RNA_STATE_DIRECT)
- {
- int ret = CLIENT_APP_INPROCESS;
-
- if (direction == APP_ID_FROM_INITIATOR)
- {
- /* get out if we've already tried to validate a client app */
- if (!getAppIdFlag(session, APPID_SESSION_CLIENT_DETECTED))
- {
- ret = RunClientDetectors(session, p, direction, pConfig);
- }
- }
- else if (session->rnaServiceState != RNA_STATE_STATEFUL &&
- getAppIdFlag(session, APPID_SESSION_CLIENT_GETS_SERVER_PACKETS))
- {
- ret = RunClientDetectors(session, p, direction, pConfig);
- }
-
- switch (ret)
- {
- case CLIENT_APP_INPROCESS:
- break;
- default:
- session->rnaClientState = RNA_STATE_FINISHED;
- break;
- }
- }
- else if (session->rnaClientState == RNA_STATE_STATEFUL)
- {
- AppIdDiscoverClientApp(p, direction, session, pConfig);
- isTpAppidDiscoveryDone = true;
- if (session->candidate_client_list != nullptr)
- {
- if (sflist_count(session->candidate_client_list) > 0)
- {
- int ret = 0;
- if (direction == APP_ID_FROM_INITIATOR)
- {
- /* get out if we've already tried to validate a client app */
- if (!getAppIdFlag(session, APPID_SESSION_CLIENT_DETECTED))
- {
- ret = RunClientDetectors(session, p, direction, pConfig);
- }
- }
- else if (session->rnaServiceState != RNA_STATE_STATEFUL &&
- getAppIdFlag(session, APPID_SESSION_CLIENT_GETS_SERVER_PACKETS))
- {
- ret = RunClientDetectors(session, p, direction, pConfig);
- }
- if (ret < 0)
- setAppIdFlag(session, APPID_SESSION_CLIENT_DETECTED);
- }
- else
- {
- setAppIdFlag(session, APPID_SESSION_CLIENT_DETECTED);
- }
- }
- }
- if (app_id_debug_session_flag)
- if (!was_http2 && session->is_http2)
- LogMessage("AppIdDbg %s Got a preface for HTTP/2\n", app_id_debug_session);
-
- if (!was_service && getAppIdFlag(session, APPID_SESSION_SERVICE_DETECTED))
- synchAppIdWithSnortId(session->serviceAppId, p, session, pConfig);
- }
- /*** End of client discovery. ***/
-
- setAppIdFlag(session, APPID_SESSION_ADDITIONAL_PACKET);
- }
- else
- {
- if (app_id_debug_session_flag && p->dsize &&
- !getAppIdFlag(session, APPID_SESSION_OOO_LOGGED))
- {
- setAppIdFlag(session, APPID_SESSION_OOO_LOGGED);
- LogMessage("AppIdDbg %s packet out-of-order\n", app_id_debug_session);
- }
- }
-
- serviceAppId = pickServiceAppId(session);
- payloadAppId = pickPayloadId(session);
-
- if (serviceAppId > APP_ID_NONE)
- {
- if (getAppIdFlag(session, APPID_SESSION_DECRYPTED))
- {
- if (session->miscAppId == APP_ID_NONE)
- updateEncryptedAppId(session, serviceAppId);
- }
-// FIXIT-M: Need to determine what api to use for this _dpd function
-#if 1
- UNUSED(isTpAppidDiscoveryDone);
-#else
- else if (isTpAppidDiscoveryDone && isSslServiceAppId(serviceAppId) &&
- _dpd.isSSLPolicyEnabled(nullptr))
- setAppIdFlag(session, APPID_SESSION_CONTINUE);
-#endif
- }
-
- p->flow->set_application_ids(serviceAppId, pickClientAppId(session),
- payloadAppId, pickMiscAppId(session));
-
- /* Set the field that the Firewall queries to see if we have a search engine. */
- if (session->search_support_type == SEARCH_SUPPORT_TYPE_UNKNOWN && payloadAppId > APP_ID_NONE)
- {
- uint flags = appInfoEntryFlagGet(payloadAppId, APPINFO_FLAG_SEARCH_ENGINE |
- APPINFO_FLAG_SUPPORTED_SEARCH, pConfig);
- session->search_support_type =
- (flags & APPINFO_FLAG_SEARCH_ENGINE) ?
- ((flags & APPINFO_FLAG_SUPPORTED_SEARCH) ? SUPPORTED_SEARCH_ENGINE :
- UNSUPPORTED_SEARCH_ENGINE )
- : NOT_A_SEARCH_ENGINE;
- if (app_id_debug_session_flag)
- {
- const char* typeString;
- switch ( session->search_support_type )
- {
- case NOT_A_SEARCH_ENGINE: typeString = "NOT_A_SEARCH_ENGINE"; break;
- case SUPPORTED_SEARCH_ENGINE: typeString = "SUPPORTED_SEARCH_ENGINE"; break;
- case UNSUPPORTED_SEARCH_ENGINE: typeString = "UNSUPPORTED_SEARCH_ENGINE"; break;
- default: typeString = "unknown"; break;
- }
-
- LogMessage("AppIdDbg %s appId: %u (safe)search_support_type=%s\n",
- app_id_debug_session, payloadAppId, typeString);
- }
- }
-
- if ( serviceAppId != APP_ID_NONE )
- {
- if ( payloadAppId != APP_ID_NONE && payloadAppId != session->pastIndicator)
- {
- session->pastIndicator = payloadAppId;
- checkSessionForAFIndicator(p, direction, pConfig, (ApplicationId)payloadAppId);
- }
-
- if (session->payloadAppId == APP_ID_NONE && session->pastForecast != serviceAppId &&
- session->pastForecast != APP_ID_UNKNOWN)
- {
- session->pastForecast = checkSessionForAFForecast(session, p, direction, pConfig,
- (ApplicationId)serviceAppId);
- }
- }
-}
-
-static inline void pickHttpXffAddress(Packet*, AppIdData* appIdSession,
- ThirdPartyAppIDAttributeData* attribute_data)
-{
- int i;
- static const char* defaultXffPrecedence[] =
- {
- HTTP_XFF_FIELD_X_FORWARDED_FOR,
- HTTP_XFF_FIELD_TRUE_CLIENT_IP
- };
-
- // XFF precedence configuration cannot change for a session. Do not get it again if we already
- // got it.
-// FIXIT-M:
-#ifdef REMOVED_WHILE_NOT_IN_USE
- if (!appIdSession->hsession->xffPrecedence)
- appIdSession->hsession->xffPrecedence = _dpd.sessionAPI->get_http_xff_precedence(
- p->flow, p->packet_flags, &appIdSession->hsession->numXffFields);
-#endif
-
- if (!appIdSession->hsession->xffPrecedence)
- {
- appIdSession->hsession->xffPrecedence = defaultXffPrecedence;
- appIdSession->hsession->numXffFields = sizeof(defaultXffPrecedence) /
- sizeof(defaultXffPrecedence[0]);
- }
-
- if (app_id_debug_session_flag)
- {
- for (i = 0; i < attribute_data->numXffFields; i++)
- LogMessage("AppIdDbg %s %s : %s\n", app_id_debug_session,
- attribute_data->xffFieldValue[i].field, attribute_data->xffFieldValue[i].value);
- }
-
- // xffPrecedence array is sorted based on precedence
- for (i = 0; (i < appIdSession->hsession->numXffFields) &&
- appIdSession->hsession->xffPrecedence[i]; i++)
- {
- int j;
- for (j = 0; j < attribute_data->numXffFields; j++)
- {
- if (appIdSession->hsession->xffAddr)
- sfip_free(appIdSession->hsession->xffAddr);
-
- if (strncasecmp(attribute_data->xffFieldValue[j].field,
- appIdSession->hsession->xffPrecedence[i], UINT8_MAX) == 0)
- {
- char* tmp = strchr(attribute_data->xffFieldValue[j].value, ',');
- SFIP_RET status;
-
- if (!tmp)
- {
- appIdSession->hsession->xffAddr = sfip_alloc(
- attribute_data->xffFieldValue[j].value, &status);
- }
- // For a comma-separated list of addresses, pick the first address
- else
- {
- attribute_data->xffFieldValue[j].value[tmp -
- attribute_data->xffFieldValue[j].value] = '\0';
- appIdSession->hsession->xffAddr = sfip_alloc(
- attribute_data->xffFieldValue[j].value, &status);
- }
- break;
- }
- }
- if (appIdSession->hsession->xffAddr)
- break;
- }
-}
-
-static inline void ProcessThirdPartyResults(Packet* p, AppIdData* appIdSession, int
- confidence, AppId* proto_list, ThirdPartyAppIDAttributeData* attribute_data)
-{
- int size;
- AppId serviceAppId = 0;
- AppId ClientAppId = 0;
- AppId payloadAppId = 0;
- AppId referredPayloadAppId = 0;
- AppIdConfig* pConfig = pAppidActiveConfig;
-
- if (ThirdPartyAppIDFoundProto(APP_ID_EXCHANGE, proto_list))
- {
- if (!appIdSession->payloadAppId)
- appIdSession->payloadAppId = APP_ID_EXCHANGE;
- }
-
- if (ThirdPartyAppIDFoundProto(APP_ID_HTTP, proto_list))
- {
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s flow is HTTP\n", app_id_debug_session);
- setAppIdFlag(appIdSession, APPID_SESSION_HTTP_SESSION);
- }
- if (ThirdPartyAppIDFoundProto(APP_ID_SPDY, proto_list))
- {
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s flow is SPDY\n", app_id_debug_session);
-
- setAppIdFlag(appIdSession, APPID_SESSION_HTTP_SESSION | APPID_SESSION_SPDY_SESSION);
- }
-
- if (getAppIdFlag(appIdSession, APPID_SESSION_HTTP_SESSION))
- {
- if (!appIdSession->hsession)
- {
- appIdSession->hsession = (httpSession*)snort_calloc(sizeof(httpSession));
- memset(ptype_scan_counts, 0, 7 * sizeof(ptype_scan_counts[0]));
- }
-
- if (getAppIdFlag(appIdSession, APPID_SESSION_SPDY_SESSION))
- {
- if (attribute_data->spdyRequesHost)
- {
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s SPDY host is %s\n", app_id_debug_session,
- attribute_data->spdyRequesHost);
- if (appIdSession->hsession->host)
- {
- snort_free(appIdSession->hsession->host);
- appIdSession->hsession->chp_finished = 0;
- }
- appIdSession->hsession->host = snort_strdup(attribute_data->spdyRequesHost);
- appIdSession->scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
- }
- if (attribute_data->spdyRequestPath)
- {
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s SPDY URI is %s\n", app_id_debug_session,
- attribute_data->spdyRequestPath);
- if (appIdSession->hsession->uri)
- {
- snort_free(appIdSession->hsession->uri);
- appIdSession->hsession->chp_finished = 0;
- }
- appIdSession->hsession->uri = snort_strdup(attribute_data->spdyRequestPath);
- }
- if (attribute_data->spdyRequestScheme &&
- attribute_data->spdyRequesHost &&
- attribute_data->spdyRequestPath)
- {
- static const char httpsScheme[] = "https";
- static const char httpScheme[] = "http";
- const char* scheme;
-
- if (appIdSession->hsession->url)
- {
- snort_free(appIdSession->hsession->url);
- appIdSession->hsession->chp_finished = 0;
- }
- if (getAppIdFlag(appIdSession, APPID_SESSION_DECRYPTED)
- && memcmp(attribute_data->spdyRequestScheme, httpScheme, sizeof(httpScheme)-
- 1) == 0)
- {
- scheme = httpsScheme;
- }
- else
- {
- scheme = attribute_data->spdyRequestScheme;
- }
-
- size = strlen(scheme) +
- strlen(attribute_data->spdyRequesHost) +
- strlen(attribute_data->spdyRequestPath) +
- sizeof("://"); // see sprintf() format
- appIdSession->hsession->url = (char*)snort_calloc(size);
- sprintf(appIdSession->hsession->url, "%s://%s%s",
- scheme, attribute_data->spdyRequesHost, attribute_data->spdyRequestPath);
- appIdSession->scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
- }
- if (attribute_data->spdyRequestScheme)
- {
- snort_free(attribute_data->spdyRequestScheme);
- attribute_data->spdyRequestScheme = nullptr;
- }
- if (attribute_data->spdyRequesHost)
- {
- snort_free(attribute_data->spdyRequesHost);
- attribute_data->spdyRequesHost = nullptr;
- }
- if (attribute_data->spdyRequestPath)
- {
- snort_free(attribute_data->spdyRequestPath);
- attribute_data->spdyRequestPath = nullptr;
- }
- }
- else
- {
- if (attribute_data->httpRequesHost)
- {
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s HTTP host is %s\n", app_id_debug_session,
- attribute_data->httpRequesHost);
- if (appIdSession->hsession->host)
- {
- snort_free(appIdSession->hsession->host);
- if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
- appIdSession->hsession->chp_finished = 0;
- }
- appIdSession->hsession->host = attribute_data->httpRequesHost;
- attribute_data->httpRequesHost = nullptr;
- appIdSession->scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
- }
- if (attribute_data->httpRequesUrl)
- {
- static const char httpScheme[] = "http://";
-
- if (appIdSession->hsession->url)
- {
- snort_free(appIdSession->hsession->url);
- if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
- appIdSession->hsession->chp_finished = 0;
- }
-
- //change http to https if session was decrypted.
- if (getAppIdFlag(appIdSession, APPID_SESSION_DECRYPTED)
- &&
- memcmp(attribute_data->httpRequesUrl, httpScheme, sizeof(httpScheme)-1) == 0)
- {
- appIdSession->hsession->url =
- (char*)snort_calloc(strlen(attribute_data->httpRequesUrl) + 2);
-
- if (appIdSession->hsession->url)
- sprintf(appIdSession->hsession->url, "https://%s",
- attribute_data->httpRequesUrl + sizeof(httpScheme)-1);
-
- snort_free(attribute_data->httpRequesUrl);
- attribute_data->httpRequesUrl = nullptr;
- }
- else
- {
- appIdSession->hsession->url = attribute_data->httpRequesUrl;
- attribute_data->httpRequesUrl = nullptr;
- }
-
- appIdSession->scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
- }
- if (attribute_data->httpRequestUri)
- {
- if (appIdSession->hsession->uri)
- {
- snort_free(appIdSession->hsession->uri);
- if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
- appIdSession->hsession->chp_finished = 0;
- }
- appIdSession->hsession->uri = attribute_data->httpRequestUri;
- appIdSession->hsession->uriOffset = attribute_data->httpRequestUriOffset;
- appIdSession->hsession->uriEndOffset = attribute_data->httpRequestUriEndOffset;
- attribute_data->httpRequestUri = nullptr;
- attribute_data->httpRequestUriOffset = 0;
- attribute_data->httpRequestUriEndOffset = 0;
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s uri (%u-%u) is %s\n", app_id_debug_session,
- appIdSession->hsession->uriOffset, appIdSession->hsession->uriEndOffset,
- appIdSession->hsession->uri);
- }
- }
- if (attribute_data->httpRequestVia)
- {
- if (appIdSession->hsession->via)
- {
- snort_free(appIdSession->hsession->via);
- if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
- appIdSession->hsession->chp_finished = 0;
- }
- appIdSession->hsession->via = attribute_data->httpRequestVia;
- attribute_data->httpRequestVia = nullptr;
- appIdSession->scan_flags |= SCAN_HTTP_VIA_FLAG;
- }
- else if (attribute_data->httpResponseVia)
- {
- if (appIdSession->hsession->via)
- {
- snort_free(appIdSession->hsession->via);
- if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
- appIdSession->hsession->chp_finished = 0;
- }
- appIdSession->hsession->via = attribute_data->httpResponseVia;
- attribute_data->httpResponseVia = nullptr;
- appIdSession->scan_flags |= SCAN_HTTP_VIA_FLAG;
- }
- if (attribute_data->httpRequestUserAgent)
- {
- if (appIdSession->hsession->useragent)
- {
- snort_free(appIdSession->hsession->useragent);
- if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
- appIdSession->hsession->chp_finished = 0;
- }
- appIdSession->hsession->useragent = attribute_data->httpRequestUserAgent;
- attribute_data->httpRequestUserAgent = nullptr;
- appIdSession->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 (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s HTTP response version is %s\n", app_id_debug_session,
- attribute_data->httpResponseVersion);
- if (strncmp(attribute_data->httpResponseVersion, "HTTP/2", 6) == 0)
- {
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s 3rd party detected and parsed HTTP/2\n",
- app_id_debug_session);
- appIdSession->is_http2 = true;
- }
- snort_free(attribute_data->httpResponseVersion);
- attribute_data->httpResponseVersion = nullptr;
- }
- if (attribute_data->httpResponseCode)
- {
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s HTTP response code is %s\n", app_id_debug_session,
- attribute_data->httpResponseCode);
- if (appIdSession->hsession->response_code)
- {
- snort_free(appIdSession->hsession->response_code);
- if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
- appIdSession->hsession->chp_finished = 0;
- }
- appIdSession->hsession->response_code = 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 (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s HTTP response upgrade is %s\n", app_id_debug_session,
- attribute_data->httpResponseUpgrade);
- if (pAppidActiveConfig->mod_config->http2_detection_enabled)
- if (appIdSession->hsession->response_code && (strncmp(
- appIdSession->hsession->response_code, "101", 3) == 0))
- if (strncmp(attribute_data->httpResponseUpgrade, "h2c", 3) == 0)
- {
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s Got an upgrade to HTTP/2\n",
- app_id_debug_session);
- appIdSession->is_http2 = true;
- }
- snort_free(attribute_data->httpResponseUpgrade);
- attribute_data->httpResponseUpgrade = nullptr;
- }
- if (!pAppidActiveConfig->mod_config->referred_appId_disabled &&
- attribute_data->httpRequestReferer)
- {
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s referrer is %s\n", app_id_debug_session,
- attribute_data->httpRequestReferer);
- if (appIdSession->hsession->referer)
- {
- snort_free(appIdSession->hsession->referer);
- if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
- appIdSession->hsession->chp_finished = 0;
- }
- appIdSession->hsession->referer = attribute_data->httpRequestReferer;
- attribute_data->httpRequestReferer = nullptr;
- }
- if (attribute_data->httpRequestCookie)
- {
- if (appIdSession->hsession->cookie)
- {
- snort_free(appIdSession->hsession->cookie);
- if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
- appIdSession->hsession->chp_finished = 0;
- }
- appIdSession->hsession->cookie = attribute_data->httpRequestCookie;
- appIdSession->hsession->cookieOffset = attribute_data->httpRequestCookieOffset;
- appIdSession->hsession->cookieEndOffset = attribute_data->httpRequestCookieEndOffset;
- attribute_data->httpRequestCookie = nullptr;
- attribute_data->httpRequestCookieOffset = 0;
- attribute_data->httpRequestCookieEndOffset = 0;
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s cookie (%u-%u) is %s\n", app_id_debug_session,
- appIdSession->hsession->cookieOffset, appIdSession->hsession->cookieEndOffset,
- appIdSession->hsession->cookie);
- }
- if (attribute_data->httpResponseContent)
- {
- if (appIdSession->hsession->content_type)
- {
- snort_free(appIdSession->hsession->content_type);
- if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
- appIdSession->hsession->chp_finished = 0;
- }
- appIdSession->hsession->content_type = attribute_data->httpResponseContent;
- attribute_data->httpResponseContent = nullptr;
- appIdSession->scan_flags |= SCAN_HTTP_CONTENT_TYPE_FLAG;
- }
- if (ptype_scan_counts[LOCATION_PT] && attribute_data->httpResponseLocation)
- {
- if (appIdSession->hsession->location)
- {
- snort_free(appIdSession->hsession->location);
- if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
- appIdSession->hsession->chp_finished = 0;
- }
- appIdSession->hsession->location = attribute_data->httpResponseLocation;
- attribute_data->httpResponseLocation = nullptr;
- }
- if (attribute_data->httpRequestBody)
- {
- if (app_id_debug_session_flag)
- LogMessage("AppIdDbg %s got a request body %s\n", app_id_debug_session,
- attribute_data->httpRequestBody);
- if (appIdSession->hsession->req_body)
- {
- snort_free(appIdSession->hsession->req_body);
- if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
- appIdSession->hsession->chp_finished = 0;
- }
- appIdSession->hsession->req_body = attribute_data->httpRequestBody;
- attribute_data->httpRequestBody = nullptr;
- }
- if (ptype_scan_counts[BODY_PT] && attribute_data->httpResponseBody)
- {
- if (appIdSession->hsession->body)
- {
- snort_free(appIdSession->hsession->body);
- if (!getAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT))
- appIdSession->hsession->chp_finished = 0;
- }
- appIdSession->hsession->body = attribute_data->httpResponseBody;
- attribute_data->httpResponseBody = nullptr;
- }
- if (attribute_data->numXffFields)
- {
- pickHttpXffAddress(p, appIdSession, attribute_data);
- }
- if (!appIdSession->hsession->chp_finished || appIdSession->hsession->chp_hold_flow)
- {
- setAppIdFlag(appIdSession, APPID_SESSION_CHP_INSPECTING);
- if (thirdparty_appid_module)
- thirdparty_appid_module->session_attr_set(appIdSession->tpsession,
- TP_ATTR_CONTINUE_MONITORING);
- }
- if (attribute_data->httpResponseServer)
- {
- if (appIdSession->hsession->server)
- snort_free(appIdSession->hsession->server);
- appIdSession->hsession->server = attribute_data->httpResponseServer;
- attribute_data->httpResponseServer = nullptr;
- appIdSession->scan_flags |= SCAN_HTTP_VENDOR_FLAG;
- }
- if (attribute_data->httpRequestXWorkingWith)
- {
- if (appIdSession->hsession->x_working_with)
- snort_free(appIdSession->hsession->x_working_with);
- appIdSession->hsession->x_working_with = attribute_data->httpRequestXWorkingWith;
- attribute_data->httpRequestXWorkingWith = nullptr;
- appIdSession->scan_flags |= SCAN_HTTP_XWORKINGWITH_FLAG;
- }
- }
- else if (ThirdPartyAppIDFoundProto(APP_ID_RTMP, proto_list) ||
- ThirdPartyAppIDFoundProto(APP_ID_RTSP, proto_list))
- {
- if (!appIdSession->hsession)
- appIdSession->hsession = (httpSession*)snort_calloc(sizeof(httpSession));
-
- if (!appIdSession->hsession->url)
- {
- if (attribute_data->httpRequesUrl)
- {
- appIdSession->hsession->url = attribute_data->httpRequesUrl;
- attribute_data->httpRequesUrl = nullptr;
- appIdSession->scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
- }
- }
-
- if (!pAppidActiveConfig->mod_config->referred_appId_disabled &&
- !appIdSession->hsession->referer)
- {
- if (attribute_data->httpRequestReferer)
- {
- appIdSession->hsession->referer = attribute_data->httpRequestReferer;
- attribute_data->httpRequestReferer = nullptr;
- }
- }
-
- if (appIdSession->hsession->url || (confidence == 100 &&
- appIdSession->session_packet_count > pAppidActiveConfig->mod_config->rtmp_max_packets))
- {
- if (appIdSession->hsession->url)
- {
- if (((getAppIdFromUrl(nullptr, appIdSession->hsession->url, nullptr,
- appIdSession->hsession->referer, &ClientAppId, &serviceAppId,
- &payloadAppId, &referredPayloadAppId, 1, &pConfig->detectorHttpConfig)) ||
- (getAppIdFromUrl(nullptr, appIdSession->hsession->url, nullptr,
- appIdSession->hsession->referer, &ClientAppId, &serviceAppId,
- &payloadAppId, &referredPayloadAppId, 0, &pConfig->detectorHttpConfig))) == 1)
- {
- // do not overwrite a previously-set client or service
- if (appIdSession->ClientAppId <= APP_ID_NONE)
- setClientAppIdData(appIdSession, ClientAppId, nullptr);
- if (appIdSession->serviceAppId <= APP_ID_NONE)
- seServiceAppIdData(appIdSession, serviceAppId, nullptr, nullptr);
-
- // DO overwrite a previously-set data
- setPayloadAppIdData(appIdSession, (ApplicationId)payloadAppId, nullptr);
- setReferredPayloadAppIdData(appIdSession, referredPayloadAppId);
- }
- }
-
- if (thirdparty_appid_module)
- {
- thirdparty_appid_module->disable_flags(appIdSession->tpsession,
- TP_SESSION_FLAG_ATTRIBUTE | TP_SESSION_FLAG_TUNNELING |
- TP_SESSION_FLAG_FUTUREFLOW);
- thirdparty_appid_module->session_delete(appIdSession->tpsession, 1);
- }
- appIdSession->tpsession = nullptr;
- clearAppIdFlag(appIdSession, APPID_SESSION_APP_REINSPECT);
- }
- }
- else if (ThirdPartyAppIDFoundProto(APP_ID_SSL, proto_list))
- {
- AppId tmpAppId = APP_ID_NONE;
-
- if (thirdparty_appid_module && appIdSession->tpsession)
- tmpAppId = thirdparty_appid_module->session_appid_get(appIdSession->tpsession);
-
- setAppIdFlag(appIdSession, APPID_SESSION_SSL_SESSION);
-
- if (!appIdSession->tsession)
- appIdSession->tsession = (tlsSession*)snort_calloc(sizeof(tlsSession));
-
- if (!appIdSession->ClientAppId)
- setClientAppIdData(appIdSession, APP_ID_SSL_CLIENT, nullptr);
-
- if (attribute_data->tlsHost)
- {
- if (appIdSession->tsession->tls_host)
- snort_free(appIdSession->tsession->tls_host);
- appIdSession->tsession->tls_host = attribute_data->tlsHost;
- attribute_data->tlsHost = nullptr;
- if (testSSLAppIdForReinspect(tmpAppId))
- appIdSession->scan_flags |= SCAN_SSL_HOST_FLAG;
- }
- if (testSSLAppIdForReinspect(tmpAppId))
- {
- if (attribute_data->tlsCname)
- {
- if (appIdSession->tsession->tls_cname)
- snort_free(appIdSession->tsession->tls_cname);
- appIdSession->tsession->tls_cname = attribute_data->tlsCname;
- attribute_data->tlsCname = nullptr;
- }
- if (attribute_data->tlsOrgUnit)
- {
- if (appIdSession->tsession->tls_orgUnit)
- snort_free(appIdSession->tsession->tls_orgUnit);
- appIdSession->tsession->tls_orgUnit = attribute_data->tlsOrgUnit;
- attribute_data->tlsOrgUnit = nullptr;
- }
- }
- }
- else if (ThirdPartyAppIDFoundProto(APP_ID_FTP_CONTROL, proto_list))
- {
- if (!pAppidActiveConfig->mod_config->ftp_userid_disabled && attribute_data->ftpCommandUser)
- {
- if (appIdSession->username)
- snort_free(appIdSession->username);
- appIdSession->username = attribute_data->ftpCommandUser;
- attribute_data->ftpCommandUser = nullptr;
- appIdSession->usernameService = APP_ID_FTP_CONTROL;
- setAppIdFlag(appIdSession, APPID_SESSION_LOGIN_SUCCEEDED);
- }
- }
-}
-
-void appSetServiceValidator(RNAServiceValidationFCN fcn, AppId appId, unsigned extractsInfo,
- AppIdConfig* pConfig)
-{
- AppInfoTableEntry* pEntry = appInfoEntryGet(appId, pConfig);
- if (!pEntry)
- {
- ErrorMessage("AppId: invalid direct service AppId, %d", appId);
- return;
- }
- extractsInfo &= (APPINFO_FLAG_SERVICE_ADDITIONAL | APPINFO_FLAG_SERVICE_UDP_REVERSED);
- if (!extractsInfo)
- {
- DebugFormat(DEBUG_APPID, "Ignoring direct service without info for AppId %d", appId);
- return;
- }
- pEntry->svrValidator = ServiceGetServiceElement(fcn, nullptr, pConfig);
- if (pEntry->svrValidator)
- pEntry->flags |= extractsInfo;
- else
- ErrorMessage("AppId: failed to find a service element for AppId %d", appId);
-}
-
-void appSetLuaServiceValidator(RNAServiceValidationFCN fcn, AppId appId, unsigned extractsInfo,
- struct Detector* data)
-{
- AppInfoTableEntry* entry;
- AppIdConfig* pConfig = pAppidActiveConfig;
-
- // FIXIT-L: what type of error would cause this lookup to fail? is this programming error
- // or user error due to misconfig or something like that... if change in handling needed
- // apply to all instances where this lookup is done
- if ((entry = appInfoEntryGet(appId, pConfig)))
- {
- entry->flags |= APPINFO_FLAG_ACTIVE;
-
- extractsInfo &= (APPINFO_FLAG_SERVICE_ADDITIONAL | APPINFO_FLAG_SERVICE_UDP_REVERSED);
- if (!extractsInfo)
- {
- DebugFormat(DEBUG_LOG, "Ignoring direct service without info for AppId: %d - %p\n",
- appId, (void*)data);
- return;
- }
-
- entry->svrValidator = ServiceGetServiceElement(fcn, data, pConfig);
- if (entry->svrValidator)
- entry->flags |= extractsInfo;
- else
- ErrorMessage("AppId: Failed to find a service element for AppId: %d - %p\n",
- appId, (void*)data);
- }
- else
- {
- ErrorMessage("Invalid direct service for AppId: %d - %p\n", appId, (void*)data);
- }
-}
-
-void appSetClientValidator(RNAClientAppFCN fcn, AppId appId, unsigned extractsInfo,
- AppIdConfig* pConfig)
-{
- AppInfoTableEntry* pEntry = appInfoEntryGet(appId, pConfig);
- if (!pEntry)
- {
- ErrorMessage("AppId: invalid direct client application AppId: %d\n", appId);
- return;
- }
- extractsInfo &= (APPINFO_FLAG_CLIENT_ADDITIONAL | APPINFO_FLAG_CLIENT_USER);
- if (!extractsInfo)
- {
- DebugFormat(DEBUG_LOG,
- "Ignoring direct client application without info for AppId: %d", appId);
- return;
- }
- pEntry->clntValidator = ClientAppGetClientAppModule(fcn, nullptr, &pConfig->clientAppConfig);
- if (pEntry->clntValidator)
- pEntry->flags |= extractsInfo;
- else
- ErrorMessage("Appid: Failed to find a client application module for AppId: %d\n", appId);
-}
-
-void appSetLuaClientValidator(RNAClientAppFCN fcn, AppId appId, unsigned extractsInfo, struct
- Detector* data)
-{
- AppInfoTableEntry* entry;
- AppIdConfig* pConfig = pAppidActiveConfig;
-
- if ((entry = appInfoEntryGet(appId, pConfig)))
- {
- entry->flags |= APPINFO_FLAG_ACTIVE;
- extractsInfo &= (APPINFO_FLAG_CLIENT_ADDITIONAL | APPINFO_FLAG_CLIENT_USER);
- if (!extractsInfo)
- {
- DebugFormat(DEBUG_LOG,
- "Ignoring direct client application without info forAppId %d - %p\n",
- appId, (void*)data);
- return;
- }
-
- entry->clntValidator = ClientAppGetClientAppModule(fcn, data, &pConfig->clientAppConfig);
- if (entry->clntValidator)
- entry->flags |= extractsInfo;
- else
- ErrorMessage(
- "AppId: Failed to find a client application module for AppId: %d - %p\n",
- appId, (void*)data);
- }
- else
- {
- ErrorMessage("Invalid direct client application for AppId: %d - %p\n",
- appId, (void*)data);
- return;
- }
-}
-
-void AppIdAddUser(AppIdData* flowp, const char* username, AppId appId, int success)
-{
- if (flowp->username)
- snort_free(flowp->username);
- flowp->username = snort_strdup(username);
- flowp->usernameService = appId;
- if (success)
- setAppIdFlag(flowp, APPID_SESSION_LOGIN_SUCCEEDED);
- else
- clearAppIdFlag(flowp, APPID_SESSION_LOGIN_SUCCEEDED);
-}
-
-void AppIdAddDnsQueryInfo(AppIdData* flow,
- uint16_t id,
- const uint8_t* host, uint8_t host_len, uint16_t host_offset,
- uint16_t record_type)
-{
- if ( flow->dsession )
- {
- if ( ( flow->dsession->state != 0 ) && ( flow->dsession->id != id ) )
- AppIdResetDnsInfo(flow);
- }
- else
- flow->dsession = (dnsSession*)snort_calloc(sizeof(dnsSession));
-
- if (flow->dsession->state & DNS_GOT_QUERY)
- return;
- flow->dsession->state |= DNS_GOT_QUERY;
-
- flow->dsession->id = id;
- flow->dsession->record_type = record_type;
-
- if (!flow->dsession->host)
- {
- if ((host != nullptr) && (host_len > 0) && (host_offset > 0))
- {
- flow->dsession->host_len = host_len;
- flow->dsession->host_offset = host_offset;
- flow->dsession->host = dns_parse_host(host, host_len);
- }
- }
-}
-
-void AppIdAddDnsResponseInfo(AppIdData* flow,
- uint16_t id,
- const uint8_t* host, uint8_t host_len, uint16_t host_offset,
- uint8_t response_type, uint32_t ttl)
-{
- if ( flow->dsession )
- {
- if ( ( flow->dsession->state != 0 ) && ( flow->dsession->id != id ) )
- AppIdResetDnsInfo(flow);
- }
- else
- flow->dsession = (dnsSession*)snort_calloc(sizeof(*flow->dsession));
-
- if (flow->dsession->state & DNS_GOT_RESPONSE)
- return;
- flow->dsession->state |= DNS_GOT_RESPONSE;
-
- flow->dsession->id = id;
- flow->dsession->response_type = response_type;
- flow->dsession->ttl = ttl;
-
- if (!flow->dsession->host)
- {
- if ((host != nullptr) && (host_len > 0) && (host_offset > 0))
- {
- flow->dsession->host_len = host_len;
- flow->dsession->host_offset = host_offset;
- flow->dsession->host = dns_parse_host(host, host_len);
- }
- }
-}
-
-void AppIdResetDnsInfo(AppIdData* flow)
-{
- if (flow->dsession)
- {
- snort_free(flow->dsession->host);
- memset(flow->dsession, 0, sizeof(*(flow->dsession)));
- }
-}
-
-void AppIdAddPayload(AppIdData* flow, AppId payload_id)
-{
- if (pAppidActiveConfig->mod_config->instance_id)
- checkSandboxDetection(payload_id);
- flow->payloadAppId = payload_id;
-}
-
-AppId getOpenAppId(void* ssnptr)
-{
- AppIdData* session;
- AppId payloadAppId = APP_ID_NONE;
- if (ssnptr && (session = getAppIdData(ssnptr)))
- {
- payloadAppId = session->payloadAppId;
- }
-
- return payloadAppId;
-}
-
-/**
- * @returns 1 if some appid is found, 0 otherwise.
- */
-//int sslAppGroupIdLookup(void* ssnptr, const char* serverName, const char* commonName,
-// AppId* serviceAppId, AppId* ClientAppId, AppId* payloadAppId)
-int sslAppGroupIdLookup(void*, const char*, const char*, AppId*, AppId*, AppId*)
-{
-#ifdef REMOVED_WHILE_NOT_IN_USE
- AppIdData* session;
- *serviceAppId = *ClientAppId = *payloadAppId = APP_ID_NONE;
-
- if (commonName)
- {
- ssl_scan_cname((const uint8_t*)commonName, strlen(commonName), ClientAppId, payloadAppId,
- &pAppidActiveConfig->serviceSslConfig);
- }
- if (serverName)
- {
- ssl_scan_hostname((const uint8_t*)serverName, strlen(serverName), ClientAppId,
- payloadAppId, &pAppidActiveConfig->serviceSslConfig);
- }
-
- if (ssnptr && (session = getAppIdData(ssnptr)))
- {
- *serviceAppId = pickServiceAppId(session);
- if (*ClientAppId == APP_ID_NONE)
- {
- *ClientAppId = pickClientAppId(session);
- }
- if (*payloadAppId == APP_ID_NONE)
- {
- *payloadAppId = pickPayloadId(session);
- }
- }
- if (*serviceAppId != APP_ID_NONE ||
- *ClientAppId != APP_ID_NONE ||
- *payloadAppId != APP_ID_NONE)
- {
- return 1;
- }
-#endif
-
- return 0;
-}
-
-void httpHeaderCallback(Packet* p, HttpParsedHeaders* const headers)
-{
- AppIdData* session;
- int direction;
- AppIdConfig* pConfig = pAppidActiveConfig;
-
- if (thirdparty_appid_module)
- return;
- if (!p || !(session = getAppIdData(p->flow)))
- return;
-
- direction = p->is_from_client() ? APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
-
- if (!session->hsession)
- session->hsession = (decltype(session->hsession))snort_calloc(sizeof(httpSession));
-
- if (direction == APP_ID_FROM_INITIATOR)
- {
- if (headers->host.start)
- {
- snort_free(session->hsession->host);
- session->hsession->host = snort_strndup((char*)headers->host.start, headers->host.len);
- session->scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
-
- if (headers->url.start)
- {
- snort_free(session->hsession->url);
- session->hsession->url = (char*)snort_calloc(sizeof(HTTP_PREFIX) +
- headers->host.len + headers->url.len);
- strcpy(session->hsession->url, HTTP_PREFIX);
- strncat(session->hsession->url, (char*)headers->host.start, headers->host.len);
- strncat(session->hsession->url, (char*)headers->url.start, headers->url.len);
- session->scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
- }
- }
- if (headers->userAgent.start)
- {
- snort_free(session->hsession->useragent);
- session->hsession->useragent = snort_strndup((char*)headers->userAgent.start,
- headers->userAgent.len);
- session->scan_flags |= SCAN_HTTP_USER_AGENT_FLAG;
- }
- if (headers->referer.start)
- {
- snort_free(session->hsession->referer);
- session->hsession->referer = snort_strndup((char*)headers->referer.start,
- headers->referer.len);
- }
- if (headers->via.start)
- {
- snort_free(session->hsession->via);
- session->hsession->via = snort_strndup((char*)headers->via.start, headers->via.len);
- session->scan_flags |= SCAN_HTTP_VIA_FLAG;
- }
- }
- else
- {
- if (headers->via.start)
- {
- snort_free(session->hsession->via);
- session->hsession->via = snort_strndup((char*)headers->via.start, headers->via.len);
- session->scan_flags |= SCAN_HTTP_VIA_FLAG;
- }
- if (headers->contentType.start)
- {
- snort_free(session->hsession->content_type);
- session->hsession->content_type = snort_strndup((char*)headers->contentType.start,
- headers->contentType.len);
- }
- if (headers->responseCode.start)
- {
- long responseCodeNum;
- responseCodeNum = strtoul((char*)headers->responseCode.start, nullptr, 10);
- if (responseCodeNum > 0 && responseCodeNum < 700)
- {
- snort_free(session->hsession->response_code);
- session->hsession->response_code = snort_strndup((char*)headers->responseCode.start,
- headers->responseCode.len);
- }
- }
- }
- processHTTPPacket(p, session, direction, headers, pConfig);
-
- setAppIdFlag(session, APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_HTTP_SESSION);
-
-// FIXIT-M:
-#ifdef REMOVED_WHILE_NOT_IN_USE
- _dpd.streamAPI->set_application_id(p->flow, pickServiceAppId(session),
- pickClientAppId(session), pickPayloadId(session), pickMiscAppId(session));
-#endif
-}
-
-static inline void ExamineRtmpMetadata(AppIdData* appIdSession)
-{
- AppId serviceAppId = 0;
- AppId ClientAppId = 0;
- AppId payloadAppId = 0;
- AppId referredPayloadAppId = 0;
- char* version = nullptr;
- httpSession* hsession;
- AppIdConfig* pConfig = pAppidActiveConfig;
-
- if (!appIdSession->hsession)
- appIdSession->hsession = (httpSession*)snort_calloc(sizeof(httpSession));
-
- hsession = appIdSession->hsession;
-
- if (hsession->url)
- {
- if (((getAppIdFromUrl(nullptr, hsession->url, &version,
- hsession->referer, &ClientAppId, &serviceAppId,
- &payloadAppId, &referredPayloadAppId, 1, &pConfig->detectorHttpConfig)) ||
- (getAppIdFromUrl(nullptr, hsession->url, &version,
- hsession->referer, &ClientAppId, &serviceAppId,
- &payloadAppId, &referredPayloadAppId, 0, &pConfig->detectorHttpConfig))) == 1)
- {
- /* do not overwrite a previously-set client or service */
- if (appIdSession->ClientAppId <= APP_ID_NONE)
- setClientAppIdData(appIdSession, ClientAppId, nullptr);
- if (appIdSession->serviceAppId <= APP_ID_NONE)
- seServiceAppIdData(appIdSession, serviceAppId, nullptr, nullptr);
-
- /* DO overwrite a previously-set data */
- setPayloadAppIdData(appIdSession, (ApplicationId)payloadAppId, nullptr);
- setReferredPayloadAppIdData(appIdSession, referredPayloadAppId);
- }
- }
-}
-
-void checkSandboxDetection(AppId appId)
-{
- AppInfoTableEntry* entry;
- AppIdConfig* pConfig = pAppidActiveConfig;
-
- if (pAppidActiveConfig->mod_config->instance_id && pConfig)
- {
- entry = appInfoEntryGet(appId, pConfig);
- if ( entry && ( entry->flags & APPINFO_FLAG_ACTIVE ) )
- fprintf(SF_DEBUG_FILE, "Detected AppId %d\n", entry->appId);
- }
-}
-
#define FW_APPID_H
#include "client_plugins/client_app_api.h"
-#include "util/common_util.h"
+#include "appid_utils/common_util.h"
#include "appid.h"
#include "appid_api.h"
#include "appid_config.h"
-#include "appid_flow_data.h"
+#include "appid_session.h"
#include "application_ids.h"
#include "app_info_table.h"
#include "service_plugins/service_api.h"
#include "thirdparty_appid_utils.h"
-#define PP_APP_ID 1
-
#define MIN_SFTP_PACKET_COUNT 30
#define MAX_SFTP_PACKET_COUNT 55
-struct HttpParsedHeaders;
-struct Packet;
-class AppIdConfig;
-
-extern uint8_t appIdPriorityArray[SF_APPID_MAX+1];
-
-enum ServiceEventType {};
+extern uint8_t appIdPriorityArray[SF_APPID_MAX + 1];
-AppIdData* getAppIdData(void* lwssn);
+AppIdSession* getAppIdData(void* lwssn);
-void fwAppIdInit();
void fwAppIdFini(AppIdConfig*);
-void fwAppIdSearch(Packet*);
-void httpHeaderCallback(Packet*, HttpParsedHeaders* const);
-void SipSessionSnortCallback(void* ssnptr, ServiceEventType, void* eventData);
-
-void readRnaAppMappingTable(const char* path, AppIdConfig*);
-AppId appGetAppFromServiceId(uint32_t serviceId, AppIdConfig*);
-AppId appGetAppFromClientId(uint32_t clientId, AppIdConfig*);
-AppId appGetAppFromPayloadId(uint32_t payloadId, AppIdConfig*);
-void appSharedDataDelete(AppIdData*);
-void AppIdAddUser(AppIdData*, const char* username, AppId, int success);
-void AppIdAddDnsQueryInfo(AppIdData*, uint16_t id, const uint8_t* host, uint8_t host_len,
+void AppIdAddUser(AppIdSession*, const char* username, AppId, int success);
+void AppIdAddDnsQueryInfo(AppIdSession*, uint16_t id, const uint8_t* host, uint8_t host_len,
uint16_t host_offset, uint16_t record_type);
-void AppIdAddDnsResponseInfo(AppIdData*, uint16_t id, const uint8_t* host, uint8_t host_len,
+void AppIdAddDnsResponseInfo(AppIdSession*, uint16_t id, const uint8_t* host, uint8_t host_len,
uint16_t host_offset, uint8_t response_type, uint32_t ttl);
-void AppIdResetDnsInfo(AppIdData*);
-void AppIdAddPayload(AppIdData*, AppId);
-AppIdData* appSharedDataAlloc(IpProtocol proto, const sfip_t*);
-AppId getOpenAppId(void* ssnptr);
-
-void appSetServiceValidator(
- RNAServiceValidationFCN, AppId, unsigned extractsInfo, AppIdConfig*);
-
-void appSetLuaServiceValidator(
- RNAServiceValidationFCN, AppId, unsigned extractsInfo, Detector* dat);
-
-void appSetClientValidator(
- RNAClientAppFCN, AppId, unsigned extractsInfo, AppIdConfig*);
-
-void appSetLuaClientValidator(
- RNAClientAppFCN, AppId, unsigned extractsInfo, Detector* data);
-
-int sslAppGroupIdLookup(
- void* ssnptr,
- const char* serverName,
- const char* commonName,
- AppId* serviceAppId,
- AppId* ClientAppId,
- AppId* payloadAppId
-);
-
-AppId getAppId(void* ssnptr);
+void AppIdResetDnsInfo(AppIdSession*);
+void AppIdAddPayload(AppIdSession*, AppId);
void dump_appid_stats();
-#ifdef FW_TRACKER_DEBUG
-void logAppIdInfo(SFSnortPacket* p, char* message, AppId id);
-#endif
-int AppIdDebug(
- uint16_t type,
- const uint8_t* data,
- uint32_t length,
- void** new_context,
- char* statusBuf,
- int statusBuf_len
-);
-
-extern char app_id_debug_session[FW_DEBUG_SESSION_ID_SIZE];
-extern bool app_id_debug_session_flag;
+extern unsigned dhcp_fp_table_size;
-extern ProfileStats httpPerfStats;
-extern ProfileStats clientMatchPerfStats;
-extern ProfileStats serviceMatchPerfStats;
-extern ProfileStats luaDetectorsPerfStats;
-extern ProfileStats tpPerfStats;
-extern ProfileStats tpLibPerfStats;
+unsigned isIPv4HostMonitored(uint32_t ip4, int32_t zone);
+void checkSandboxDetection(AppId appId);
-extern unsigned dhcp_fp_table_size;
-extern unsigned long app_id_raw_packet_count;
-extern unsigned long app_id_processed_packet_count;
-extern unsigned long app_id_ignored_packet_count;
-extern int app_id_debug;
-extern unsigned isIPv4HostMonitored(uint32_t ip4, int32_t zone);
-extern void checkSandboxDetection(AppId appId);
inline void initializePriorityArray()
{
return true;
}
-inline AppId isAppDetectionDone(AppIdData* flow)
-{ return getAppIdFlag(flow, APPID_SESSION_SERVICE_DETECTED); }
-
-inline AppId pickServiceAppId(AppIdData* flow)
-{
- AppId rval;
-
- if (!flow || flow->common.fsf_type.flow_type != APPID_SESSION_TYPE_NORMAL)
- return APP_ID_NONE;
-
- if (getAppIdFlag(flow, APPID_SESSION_SERVICE_DETECTED))
- {
- bool deferred = appInfoEntryFlagGet(flow->serviceAppId, APPINFO_FLAG_DEFER, pAppidActiveConfig)
- || appInfoEntryFlagGet(flow->tpAppId, APPINFO_FLAG_DEFER, pAppidActiveConfig);
-
- if (flow->serviceAppId > APP_ID_NONE && !deferred)
- return flow->serviceAppId;
- if (TPIsAppIdAvailable(flow->tpsession))
- {
- if (flow->tpAppId > APP_ID_NONE)
- return flow->tpAppId;
- else if (deferred)
- return flow->serviceAppId;
- else
- rval = APP_ID_UNKNOWN_UI;
- }
- else
- rval = flow->tpAppId;
- }
- else if (flow->tpAppId > APP_ID_NONE)
- return flow->tpAppId;
- else
- rval = APP_ID_NONE;
-
- if (flow->ClientServiceAppId > APP_ID_NONE)
- return flow->ClientServiceAppId;
-
- if (flow->portServiceAppId > APP_ID_NONE)
- return flow->portServiceAppId;
-
- return rval;
-}
-
-inline AppId pickOnlyServiceAppId(AppIdData* flow)
-{
- if (!flow || flow->common.fsf_type.flow_type != APPID_SESSION_TYPE_NORMAL)
- return APP_ID_NONE;
-
- bool deferred = appInfoEntryFlagGet(flow->serviceAppId, APPINFO_FLAG_DEFER, pAppidActiveConfig)
- || appInfoEntryFlagGet(flow->tpAppId, APPINFO_FLAG_DEFER, pAppidActiveConfig);
-
- if (flow->serviceAppId > APP_ID_NONE && !deferred)
- return flow->serviceAppId;
-
- if (TPIsAppIdAvailable(flow->tpsession) && flow->tpAppId > APP_ID_NONE)
- return flow->tpAppId;
- else if (deferred)
- return flow->serviceAppId;
-
- if (flow->serviceAppId < APP_ID_NONE)
- return APP_ID_UNKNOWN_UI;
-
- return APP_ID_NONE;
-}
-
-inline AppId pickMiscAppId(AppIdData* flow)
-{
- if (!flow || flow->common.fsf_type.flow_type != APPID_SESSION_TYPE_NORMAL)
- return APP_ID_NONE;
- if (flow->miscAppId > APP_ID_NONE)
- return flow->miscAppId;
- return APP_ID_NONE;
-}
-
-inline AppId pickClientAppId(AppIdData* flow)
-{
- if (!flow || flow->common.fsf_type.flow_type != APPID_SESSION_TYPE_NORMAL)
- return APP_ID_NONE;
- if (flow->ClientAppId > APP_ID_NONE)
- return flow->ClientAppId;
- return APP_ID_NONE;
-}
-
-inline AppId pickPayloadId(AppIdData* flow)
-{
- if (!flow || flow->common.fsf_type.flow_type != APPID_SESSION_TYPE_NORMAL)
- return APP_ID_NONE;
-
- // if we have a deferred payload, just use it.
- // we are not worried about the APP_ID_UNKNOWN case here
- if (appInfoEntryFlagGet(flow->tpPayloadAppId, APPINFO_FLAG_DEFER_PAYLOAD, pAppidActiveConfig))
- return flow->tpPayloadAppId;
- else if (flow->payloadAppId > APP_ID_NONE)
- return flow->payloadAppId;
- else if (flow->tpPayloadAppId > APP_ID_NONE)
- return flow->tpPayloadAppId;
-
- return APP_ID_NONE;
-}
-
-inline AppId pickReferredPayloadId(AppIdData* flow)
-{
- if (!flow || flow->common.fsf_type.flow_type != APPID_SESSION_TYPE_NORMAL)
- return APP_ID_NONE;
- if (flow->referredPayloadAppId > APP_ID_NONE)
- return flow->referredPayloadAppId;
- return APP_ID_NONE;
-}
-
-inline AppId fwPickServiceAppId(AppIdData* session)
-{
- AppId appId;
- appId = pickServiceAppId(session);
- if (appId == APP_ID_NONE)
- appId = session->encrypted.serviceAppId;
- return appId;
-}
-
-inline AppId fwPickMiscAppId(AppIdData* session)
-{
- AppId appId;
- appId = pickMiscAppId(session);
- if (appId == APP_ID_NONE)
- appId = session->encrypted.miscAppId;
- return appId;
-}
-
-inline AppId fwPickClientAppId(AppIdData* session)
-{
- AppId appId;
- appId = pickClientAppId(session);
- return appId;
-}
-
-inline AppId fwPickPayloadAppId(AppIdData* session)
-{
- AppId appId;
- appId = pickPayloadId(session);
- if (appId == APP_ID_NONE)
- appId = session->encrypted.payloadAppId;
- return appId;
-}
-
-inline AppId fwPickReferredPayloadAppId(AppIdData* session)
-{
- AppId appId;
- appId = pickReferredPayloadId(session);
- if (appId == APP_ID_NONE)
- appId = session->encrypted.referredAppId;
- return appId;
-}
-
-inline AppIdData* appSharedGetData(const Packet* p)
-{
- if ( p && p->flow )
- return (AppIdData*)p->flow->get_application_data(AppIdData::flow_id);
-
- return nullptr;
-}
-
-inline unsigned int isFwSessionSslDecrypted(AppIdData* session)
-{
- return getAppIdFlag(session, APPID_SESSION_DECRYPTED);
-}
-
inline int testSSLAppIdForReinspect(AppId app_id)
{
if (app_id <= SF_APPID_MAX &&
#include "appid.h"
#include "appid_api.h"
-#include "utils/sflsq.h"
+#include "appid_utils/sf_multi_mpse.h"
-// FIXIT-H rename util/ so we don't confuse it with src/utils
-#include "util/sf_multi_mpse.h"
+#include "utils/sflsq.h"
#define MAX_USERNAME_SIZE 64
#define MAX_URL_SIZE 65535
class SearchTool;
struct tMlmpTree;
+// FIXIT-M hack to get initial port to build, define these properly
+#if 1
+struct HttpParsedHeaders
+{
+ struct HttpBuf
+ {
+ char* start;
+ int len;
+ };
+
+ HttpBuf host;
+ HttpBuf url;
+ HttpBuf userAgent;
+ HttpBuf referer;
+ HttpBuf via;
+ HttpBuf contentType;
+ HttpBuf responseCode;
+};
+
+#define HTTP_XFF_FIELD_X_FORWARDED_FOR ""
+#define HTTP_XFF_FIELD_TRUE_CLIENT_IP ""
+
+#endif
+
// These values are used in Lua code as raw numbers. Do NOT reassign new values.
enum DHPSequence
{
CHPListElement* next;
};
+struct MatchedCHPAction
+{
+ CHPAction* mpattern;
+ int index;
+ MatchedCHPAction* next;
+};
+
+// This is an array element for the dynamically growing tally below
+struct CHPMatchCandidate
+{
+ CHPApp* chpapp;
+ int key_pattern_length_sum;
+ int key_pattern_countdown;
+};
+
+// FIXIT-M: make the 'item' field a std:vector and refactor code to eliminate realloc calls
+struct CHPMatchTally
+{
+ int allocated_elements;
+ int in_use_elements;
+ CHPMatchCandidate item[1];
+};
+
struct HttpPatternLists
{
HTTPListElement* hostPayloadPatternList;
#include "sfip/sf_ip.h"
#include "utils/util.h"
+#include "appid_module.h"
#include "app_forecast.h"
#include "app_info_table.h"
#include "fw_appid.h"
// must be called only when RNA is exitting.
static void freeDetector(Detector* detector)
-{ delete detector; }
+{
+ delete detector;
+}
// check service element, Allocate if necessary
int checkServiceElement(Detector* detector)
return 1;
}
+void appSetLuaClientValidator(RNAClientAppFCN fcn, AppId appId, unsigned extractsInfo,
+ struct Detector* data)
+{
+ AppInfoTableEntry* entry;
+ AppIdConfig* pConfig = pAppidActiveConfig;
+
+ if ((entry = appInfoEntryGet(appId, pConfig)))
+ {
+ entry->flags |= APPINFO_FLAG_ACTIVE;
+ extractsInfo &= (APPINFO_FLAG_CLIENT_ADDITIONAL | APPINFO_FLAG_CLIENT_USER);
+ if (!extractsInfo)
+ {
+ DebugFormat(DEBUG_LOG,
+ "Ignoring direct client application without info forAppId %d - %p\n",
+ appId, (void*)data);
+ return;
+ }
+
+ entry->clntValidator = ClientAppGetClientAppModule(fcn, data, &pConfig->clientAppConfig);
+ if (entry->clntValidator)
+ entry->flags |= extractsInfo;
+ else
+ ErrorMessage(
+ "AppId: Failed to find a client application module for AppId: %d - %p\n",
+ appId, (void*)data);
+ }
+ else
+ {
+ ErrorMessage("Invalid direct client application for AppId: %d - %p\n",
+ appId, (void*)data);
+ return;
+ }
+}
+
+void appSetLuaServiceValidator(RNAServiceValidationFCN fcn, AppId appId, unsigned extractsInfo,
+ struct Detector* data)
+{
+ AppInfoTableEntry* entry;
+ AppIdConfig* pConfig = pAppidActiveConfig;
+
+ // FIXIT-L: what type of error would cause this lookup to fail? is this programming error
+ // or user error due to misconfig or something like that... if change in handling needed
+ // apply to all instances where this lookup is done
+ if ((entry = appInfoEntryGet(appId, pConfig)))
+ {
+ entry->flags |= APPINFO_FLAG_ACTIVE;
+
+ extractsInfo &= (APPINFO_FLAG_SERVICE_ADDITIONAL | APPINFO_FLAG_SERVICE_UDP_REVERSED);
+ if (!extractsInfo)
+ {
+ DebugFormat(DEBUG_LOG, "Ignoring direct service without info for AppId: %d - %p\n",
+ appId, (void*)data);
+ return;
+ }
+
+ entry->svrValidator = ServiceGetServiceElement(fcn, data, pConfig);
+ if (entry->svrValidator)
+ entry->flags |= extractsInfo;
+ else
+ ErrorMessage("AppId: Failed to find a service element for AppId: %d - %p\n",
+ appId, (void*)data);
+ }
+ else
+ {
+ ErrorMessage("Invalid direct service for AppId: %d - %p\n", appId, (void*)data);
+ }
+}
+
static int common_registerAppId(lua_State* L)
{
unsigned int appId;
appId = lua_tonumber(L, index++);
if ( !ud->packageInfo.server.initFunctionName.empty() )
- appSetLuaServiceValidator(
- validateAnyService, appId, APPINFO_FLAG_SERVICE_ADDITIONAL, ud.ptr);
+ appSetLuaServiceValidator(validateAnyService, appId, APPINFO_FLAG_SERVICE_ADDITIONAL,
+ ud.ptr);
if ( !ud->packageInfo.client.initFunctionName.empty() )
appSetLuaClientValidator(
assert(ud->validateParams.pkt);
- ud->validateParams.flowp->payloadAppId = payloadId;
+ ud->validateParams.flowp->payload_app_id = payloadId;
return 0;
}
return 1;
}
- AppIdFlowdataAddId(ud->validateParams.flowp, sport, ud->server.pServiceElement);
+ ud->validateParams.flowp->add_flow_data_id(sport, ud->server.pServiceElement);
lua_pushnumber(L, 0);
return 1;
static int Detector_getPktCount(lua_State* L)
{
lua_checkstack (L, 1);
- lua_pushnumber(L, app_id_processed_packet_count);
+ lua_pushnumber(L, appid_stats.processed_packets);
return 1;
}
const uint8_t* data,
uint16_t size,
const int dir,
- AppIdData* flowp,
+ AppIdSession* flowp,
Packet* pkt,
Detector* detector,
const AppIdConfig*
return 1; /*number of results */
}
- AppInfoTableEntry* entry = appInfoEntryCreate(tmpString,
- ud->pAppidNewConfig);
+ AppInfoTableEntry* entry = appInfoEntryCreate(tmpString, ud->pAppidNewConfig);
if (entry)
{
char* pattern;
AppId service_app_id, client_app_id, payload_app_id, app_id_to_snort;
int16_t snort_app_id;
- AppIdData* fp;
+ AppIdSession* fp;
auto& ud = *UserData<Detector>::check(L, DETECTOR, 1);
else
snort_app_id = 0;
- fp = AppIdEarlySessionCreate(ud->validateParams.flowp,
- ud->validateParams.pkt,
- &client_addr, client_port, &server_addr, server_port, proto,
- snort_app_id,
- APPID_EARLY_SESSION_FLAG_FW_RULE);
+ fp = AppIdSession::create_future_session(ud->validateParams.pkt, &client_addr,
+ client_port, &server_addr, server_port, proto, snort_app_id,
+ APPID_EARLY_SESSION_FLAG_FW_RULE);
if (fp)
{
fp->serviceAppId = service_app_id;
- fp->ClientAppId = client_app_id;
- fp->payloadAppId = payload_app_id;
- setAppIdFlag(fp, APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_NOT_A_SERVICE |
+ fp->client_app_id = client_app_id;
+ fp->payload_app_id = payload_app_id;
+ fp->setAppIdFlag(APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_NOT_A_SERVICE |
APPID_SESSION_PORT_SERVICE_DONE);
fp->rnaServiceState = RNA_STATE_FINISHED;
- fp->rnaClientState = RNA_STATE_FINISHED;
+ fp->rna_client_state = RNA_STATE_FINISHED;
return 1;
}
//HTTP Multi Pattern engine
{ "CHPCreateApp", Detector_CHPCreateApp },
{ "CHPAddAction", Detector_CHPAddAction },
- { "CHPMultiCreateApp", Detector_CHPMultiCreateApp },// allows multiple detectors, same
- // appId
+ { "CHPMultiCreateApp", Detector_CHPMultiCreateApp }, // multiple detectors, same appId
{ "CHPMultiAddAction", Detector_CHPMultiAddAction },
//App Forecasting engine
struct ServiceValidationArgs;
struct lua_State;
class AppIdConfig;
-class AppIdData;
+class AppIdSession;
struct RNAServiceElement;
#define DETECTOR "Detector"
const uint8_t* data;
uint16_t size;
int dir;
- AppIdData* flowp;
+ AppIdSession* flowp;
Packet* pkt;
uint8_t macAddress[6];
} validateParams;
/**Pointer to flow created by a validator.
*/
- AppIdData* pFlow;
+ AppIdSession* pFlow;
struct
{
const uint8_t* data,
uint16_t size,
const int dir,
- AppIdData*,
+ AppIdSession*,
Packet*,
Detector*,
const AppIdConfig*
#include "lua_detector_module.h"
#include "main/snort_debug.h"
#include "sfip/sf_ip.h"
-#include "util/common_util.h"
+#include "appid_utils/common_util.h"
/*static const char * LuaLogLabel = "luaDetectorFlowApi"; */
char* pattern;
size_t patternLen;
- auto& detector_ud = *UserData<Detector>::check(L, DETECTOR, 1);
+ auto& detector_data = *UserData<Detector>::check(L, DETECTOR, 1);
/*check inputs and whether this function is called in context of a packet */
- if ( !detector_ud->validateParams.pkt )
+ if ( !detector_data->validateParams.pkt )
return 0; /*number of results */
pattern = (char*)lua_tostring(L, 2);
sflist_add_tail(&allocatedFlowList, detector_flow);
- detector_flow->pFlow = AppIdEarlySessionCreate((AppIdData*)detector_flow,
- detector_ud->validateParams.pkt,
- &saddr, sport, &daddr, dport, proto, 0, 0);
+ detector_flow->pFlow = AppIdSession::create_future_session(detector_data->validateParams.pkt, &saddr,
+ sport, &daddr, dport, proto, 0, 0);
if (!detector_flow->pFlow)
{
*/
void freeDetectorFlow(void* userdata)
{
- DetectorFlow* pDetectorFlow = (DetectorFlow*)userdata;
+ DetectorFlow* detector_flow = (DetectorFlow*)userdata;
/*The detectorUserData itself is a userdata and therefore be freed by Lua side. */
- if (pDetectorFlow->userDataRef != LUA_REFNIL)
+ if (detector_flow->userDataRef != LUA_REFNIL)
{
- auto L = pDetectorFlow->myLuaState;
- luaL_unref(L, LUA_REGISTRYINDEX, pDetectorFlow->userDataRef);
- pDetectorFlow->userDataRef = LUA_REFNIL;
+ auto L = detector_flow->myLuaState;
+ luaL_unref(L, LUA_REGISTRYINDEX, detector_flow->userDataRef);
+ detector_flow->userDataRef = LUA_REFNIL;
}
- delete pDetectorFlow;
+ delete detector_flow;
}
/**Sets a flow flag.
* @param flags/stack - flags to be set.
* @return int - Number of elements on stack, which is 0
*/
-static int DetectorFlow_setFlowFlag(
- lua_State* L
- )
+static int DetectorFlow_setFlowFlag(lua_State* L)
{
uint64_t flags;
flags = lua_tonumber(L, 2);
flags = ConvertFlagsLuaToC(flags);
- setAppIdFlag(pLuaData->pFlow, flags);
+ pLuaData->pFlow->setAppIdFlag(flags);
return 0;
}
* @return int - Number of elements on stack, which is 1 if successful, 0 otherwise.
* @return flagValue/stack - value of a given flag.
*/
-static int DetectorFlow_getFlowFlag(
- lua_State* L
- )
+static int DetectorFlow_getFlowFlag(lua_State* L)
{
uint64_t flags;
uint64_t ret;
flags = lua_tonumber(L, 2);
flags = ConvertFlagsLuaToC(flags);
- ret = getAppIdFlag(pLuaData->pFlow, flags);
+ ret = pLuaData->pFlow->getAppIdFlag(flags);
ret = ConvertFlagsCToLua(ret);
lua_pushnumber(L, ret);
* @param flags/stack - flags to be cleared.
* @return int - Number of elements on stack, which is 0.
*/
-static int DetectorFlow_clearFlowFlag(
- lua_State* L
- )
+static int DetectorFlow_clearFlowFlag(lua_State* L)
{
uint64_t flags;
flags = lua_tonumber(L, 2);
flags = ConvertFlagsLuaToC(flags);
- clearAppIdFlag(pLuaData->pFlow, flags);
+ pLuaData->pFlow->clearAppIdFlag(flags);
return 0;
}
* @param applId/stack - client application Id to be set on a flow.
* @return int - Number of elements on stack, which is 0.
*/
-static int DetectorFlow_setFlowClnAppId(
- lua_State*
- )
+static int DetectorFlow_setFlowClnAppId(lua_State* )
{
return 0;
}
* @param applTypeId/stack - client application type id to be set on a flow.
* @return int - Number of elements on stack, which is 0.
*/
-static int DetectorFlow_setFlowClnAppType(
- lua_State*
- )
+static int DetectorFlow_setFlowClnAppType(lua_State*)
{
return 0;
}
* @return int - Number of elements on stack, which is 1 if successful, 0 otherwise.
* @return flowKey/stack - A 20 byte flow key
*/
-static int DetectorFlow_getFlowKey(
- lua_State* L
- )
+static int DetectorFlow_getFlowKey(lua_State* L)
{
auto& pLuaData = *UserData<DetectorFlow>::check(L, DETECTORFLOW, 1);
assert(pLuaData.ptr);
* compatibility and will eventually be removed. */
/* - "new" is now "createFlow" (below) */
{ "new", DetectorFlow_new },
-
{ "createFlow", DetectorFlow_new },
{ "setFlowFlag", DetectorFlow_setFlowFlag },
{ "getFlowFlag", DetectorFlow_getFlowFlag },
/**
* lua_close will ensure that all detectors and flows get _gc called.
*/
-static int DetectorFlow_gc(
- lua_State*
- )
+static int DetectorFlow_gc(lua_State*)
{
return 0;
}
-static int DetectorFlow_tostring(
- lua_State* L
- )
+static int DetectorFlow_tostring(lua_State* L)
{
char buff[32];
snprintf(buff, sizeof(buff), "%p", (void*)UserData<DetectorFlow>::check(L, DETECTORFLOW, 1));
* @return int - Number of elements on stack, which is 1 if successful, 0 otherwise.
* @return methodArray/stack - array of newly created methods
*/
-int DetectorFlow_register(
- lua_State* L
- )
+int DetectorFlow_register(lua_State* L)
{
/* populates a new table with Detector_methods (method_table), add the table to the globals and
stack*/
// The flow object on Lua side is a userData.
struct lua_State;
-class AppIdData;
+class AppIdSession;
struct DetectorFlow
{
// FIXIT-M why is the lua state and user data ref on this object?
lua_State* myLuaState;
- AppIdData* pFlow;
+ AppIdSession* pFlow;
int userDataRef;
};
static UserData<T>* push(lua_State* L, const char* const meta, T* ptr = nullptr)
{
- auto ud = static_cast<UserData<T>*>(lua_newuserdata(L, sizeof(UserData<T>)));
+ int type_size = sizeof(UserData<T>);
+ auto ud = static_cast<UserData<T>*>(lua_newuserdata(L, type_size));
assert(ud);
ud->ptr = ptr;
luaL_getmetatable(L, meta);
#ifndef SERVICE_API_H
#define SERVICE_API_H
-#include "appid_flow_data.h"
+#include "appid_session.h"
class AppIdConfig;
-class AppIdData;
+class AppIdSession;
struct Detector;
struct RNAServiceSubtype;
struct Packet;
const uint8_t* data;
uint16_t size;
int dir;
- AppIdData* flowp;
+ AppIdSession* flowp;
Packet* pkt;
struct Detector* userdata;
const AppIdConfig* pConfig;
struct RNAServiceValidationModule;
struct IniServiceAPI
{
- void (* RegisterPattern)(
- RNAServiceValidationFCN, IpProtocol proto, const uint8_t* pattern,
+ void (* RegisterPattern)( RNAServiceValidationFCN, IpProtocol proto, const uint8_t* pattern,
unsigned size, int position, const char* name, AppIdConfig*);
-
- int (* AddPort)(
- RNAServiceValidationPort*, RNAServiceValidationModule*, AppIdConfig*);
-
+ int (* AddPort)( const RNAServiceValidationPort*, RNAServiceValidationModule*, AppIdConfig*);
void (* RemovePorts)(RNAServiceValidationFCN, AppIdConfig*);
- void (* RegisterPatternUser)(
- RNAServiceValidationFCN, IpProtocol proto, const uint8_t* pattern,
- unsigned size, int position, const char* name, AppIdConfig*);
-
- void (* RegisterAppId)(
- RNAServiceValidationFCN, AppId, uint32_t additionalInfo, AppIdConfig*);
-
+ void (* RegisterPatternUser)(RNAServiceValidationFCN, IpProtocol proto,
+ const uint8_t* pattern, unsigned size, int position, const char* name, AppIdConfig*);
+ void (* RegisterAppId)( RNAServiceValidationFCN, AppId, uint32_t additionalInfo,
+ AppIdConfig*);
int debug;
uint32_t instance_id;
AppIdConfig* pAppidConfig; ///< AppId context for which this API should be used
const char* name;
};
-typedef void*(* ServiceFlowdataGet)(AppIdData*, unsigned);
-typedef int (* ServiceFlowdataAdd)(AppIdData*, void*, unsigned, AppIdFreeFCN);
-typedef int (* ServiceFlowdataAddId)(AppIdData*, uint16_t, const RNAServiceElement* const);
-typedef int (* ServiceFlowdataAddDHCP)(AppIdData*, unsigned, const uint8_t*, unsigned, const
+typedef void*(* ServiceFlowdataGet)(AppIdSession*, unsigned);
+typedef int (* ServiceFlowdataAdd)(AppIdSession*, void*, unsigned, AppIdFreeFCN);
+typedef int (* ServiceFlowdataAddDHCP)(AppIdSession*, unsigned, const uint8_t*, unsigned, const
uint8_t*, const uint8_t*);
#define APPID_EARLY_SESSION_FLAG_FW_RULE 1
-typedef AppIdData*(* ServiceCreateNewFlow)(AppIdData* flowp, const Packet*, const sfip_t*, uint16_t,
- const sfip_t*, uint16_t, IpProtocol, int16_t, int flags);
-typedef void (* ServiceDhcpNewLease)(AppIdData* flow, const uint8_t* mac, uint32_t ip, int32_t
+typedef void (* ServiceDhcpNewLease)(AppIdSession* flow, const uint8_t* mac, uint32_t ip, int32_t
zone, uint32_t subnetmask, uint32_t leaseSecs, uint32_t router);
-typedef void (* ServiceAnalyzeFP)(AppIdData*, unsigned, unsigned, uint32_t);
+typedef void (* ServiceAnalyzeFP)(AppIdSession*, unsigned, unsigned, uint32_t);
-typedef int (* AddService)(AppIdData* flow, const Packet* pkt, int dir,
+typedef int (* AddService)(AppIdSession* flow, const Packet* pkt, int dir,
const RNAServiceElement* svc_element, AppId service, const char* vendor,
const char* version, const RNAServiceSubtype* subtype);
-typedef int (* AddServiceConsumeSubtype)(AppIdData* flow, const Packet* pkt, int dir,
+typedef int (* AddServiceConsumeSubtype)(AppIdSession* flow, const Packet* pkt, int dir,
const RNAServiceElement* svc_element, AppId service, const char* vendor, const char* version,
RNAServiceSubtype* subtype);
-typedef int (* ServiceInProcess)(AppIdData* flow, const Packet* pkt, int dir,
+typedef int (* ServiceInProcess)(AppIdSession* flow, const Packet* pkt, int dir,
const RNAServiceElement* svc_element);
-typedef int (* FailService)(AppIdData* flow, const Packet* pkt, int dir,
+typedef int (* FailService)(AppIdSession* flow, const Packet* pkt, int dir,
const RNAServiceElement* svc_element, unsigned flow_data_index, const AppIdConfig* pConfig);
-typedef int (* IncompatibleData)(AppIdData* flow, const Packet* pkt, int dir,
+typedef int (* IncompatibleData)(AppIdSession* flow, const Packet* pkt, int dir,
const RNAServiceElement* svc_element, unsigned flow_data_index, const AppIdConfig*);
-typedef void (* AddHostInfo)(AppIdData* flow, SERVICE_HOST_INFO_CODE code, const void* info);
-typedef void (* AddPayload)(AppIdData*, AppId);
-typedef void (* AddUser)(AppIdData*, const char*, AppId, int);
-typedef void (* AddMisc)(AppIdData*, AppId);
-typedef void (* AddDnsQueryInfo)(AppIdData* flow, uint16_t id, const uint8_t* host,
+typedef void (* AddHostInfo)(AppIdSession* flow, SERVICE_HOST_INFO_CODE code, const void* info);
+typedef void (* AddPayload)(AppIdSession*, AppId);
+typedef void (* AddUser)(AppIdSession*, const char*, AppId, int);
+typedef void (* AddMisc)(AppIdSession*, AppId);
+typedef void (* AddDnsQueryInfo)(AppIdSession* flow, uint16_t id, const uint8_t* host,
uint8_t host_len, uint16_t host_offset, uint16_t record_type);
-typedef void (* AddDnsResponseInfo)(AppIdData* flow, uint16_t id, const uint8_t* host,
+typedef void (* AddDnsResponseInfo)(AppIdSession* flow, uint16_t id, const uint8_t* host,
uint8_t host_len, uint16_t host_offset, uint8_t response_type, uint32_t ttl);
-typedef void (* ResetDnsInfo)(AppIdData* flow);
+typedef void (* ResetDnsInfo)(AppIdSession* flow);
struct ServiceApi
{
ServiceFlowdataGet data_get;
ServiceFlowdataAdd data_add;
- ServiceCreateNewFlow flow_new;
- ServiceFlowdataAddId data_add_id;
ServiceFlowdataAddDHCP data_add_dhcp;
ServiceDhcpNewLease dhcpNewLease;
ServiceAnalyzeFP analyzefp;
{
const char* name;
RNAServiceValidationInitFCN init;
- RNAServiceValidationPort* pp;
+ const RNAServiceValidationPort* pp;
const ServiceApi* api;
RNAServiceValidationModule* next;
int provides_user;
#include "service_ssl.h"
#include "service_telnet.h"
#include "service_tftp.h"
-#include "appid_flow_data.h"
+#include "appid_session.h"
#include "appid_config.h"
#include "fw_appid.h"
#include "lua_detector_api.h"
#include "lua_detector_module.h"
-#include "util/ip_funcs.h"
+#include "appid_utils/ip_funcs.h"
#include "detector_plugins/detector_dns.h"
#include "detector_plugins/detector_pattern.h"
#include "detector_plugins/detector_sip.h"
* already exist). */
#define MAX_CANDIDATE_SERVICES 10
-static void* service_flowdata_get(AppIdData* flow, unsigned service_id);
-static int service_flowdata_add(AppIdData* flow, void* data, unsigned service_id, AppIdFreeFCN
+static void* service_flowdata_get(AppIdSession* flow, unsigned service_id);
+static int service_flowdata_add(AppIdSession* flow, void* data, unsigned service_id, AppIdFreeFCN
fcn);
-static void AppIdAddHostInfo(AppIdData* flow, SERVICE_HOST_INFO_CODE code, const void* info);
-static int AppIdAddDHCP(AppIdData* flowp, unsigned op55_len, const uint8_t* op55, unsigned
+static void AppIdAddHostInfo(AppIdSession* flow, SERVICE_HOST_INFO_CODE code, const void* info);
+static int AppIdAddDHCP(AppIdSession* flowp, unsigned op55_len, const uint8_t* op55, unsigned
op60_len, const uint8_t* op60, const uint8_t* mac);
-static void AppIdAddHostIP(AppIdData* flow, const uint8_t* mac, uint32_t ip4,
+static void AppIdAddHostIP(AppIdSession* flow, const uint8_t* mac, uint32_t ip4,
int32_t zone, uint32_t subnetmask, uint32_t leaseSecs, uint32_t router);
-static void AppIdAddSMBData(AppIdData* flow, unsigned major, unsigned minor, uint32_t flags);
-static void AppIdServiceAddMisc(AppIdData* flow, AppId miscId);
+static void AppIdAddSMBData(AppIdSession* flow, unsigned major, unsigned minor, uint32_t flags);
+static void AppIdServiceAddMisc(AppIdSession* flow, AppId miscId);
const ServiceApi serviceapi =
{
&service_flowdata_get,
&service_flowdata_add,
- &AppIdEarlySessionCreate,
- &AppIdFlowdataAddId,
&AppIdAddDHCP,
&AppIdAddHostIP,
&AppIdAddSMBData,
static ServicePatternData* free_pattern_data;
/*C service API */
-static void ServiceRegisterPattern(RNAServiceValidationFCN fcn,
- IpProtocol proto, const uint8_t* pattern, unsigned size,
- int position, struct Detector* userdata, int provides_user,
- const char* name, ServiceConfig* pServiceConfig);
-static void CServiceRegisterPattern(RNAServiceValidationFCN fcn, IpProtocol proto,
- const uint8_t* pattern, unsigned size,
- int position, const char* name, AppIdConfig* pConfig);
-static void ServiceRegisterPatternUser(RNAServiceValidationFCN fcn, IpProtocol proto,
- const uint8_t* pattern, unsigned size,
- int position, const char* name, AppIdConfig* pConfig);
-static int CServiceAddPort(RNAServiceValidationPort* pp, RNAServiceValidationModule* svm,
- AppIdConfig* pConfig);
+static void ServiceRegisterPattern(RNAServiceValidationFCN, IpProtocol, const uint8_t*, unsigned,
+ int, struct Detector*, int, const char*, ServiceConfig*);
+static void CServiceRegisterPattern(RNAServiceValidationFCN, IpProtocol, const uint8_t* ,
+ unsigned, int , const char*, AppIdConfig*);
+static void ServiceRegisterPatternUser(RNAServiceValidationFCN, IpProtocol, const uint8_t*,
+ unsigned, int, const char*, AppIdConfig*);
+void appSetServiceValidator( RNAServiceValidationFCN, AppId, unsigned extractsInfo, AppIdConfig*);
+static int CServiceAddPort(const RNAServiceValidationPort*, RNAServiceValidationModule*, AppIdConfig*);
static void CServiceRemovePorts(RNAServiceValidationFCN validate, AppIdConfig* pConfig);
static IniServiceAPI svc_init_api =
static ServiceMatch* free_service_match;
static const uint8_t zeromac[6] = { 0, 0, 0, 0, 0, 0 };
+
+void appSetServiceValidator(RNAServiceValidationFCN fcn, AppId appId, unsigned extractsInfo,
+ AppIdConfig* pConfig)
+{
+ AppInfoTableEntry* pEntry = appInfoEntryGet(appId, pConfig);
+ if (!pEntry)
+ {
+ ErrorMessage("AppId: invalid direct service AppId, %d", appId);
+ return;
+ }
+ extractsInfo &= (APPINFO_FLAG_SERVICE_ADDITIONAL | APPINFO_FLAG_SERVICE_UDP_REVERSED);
+ if (!extractsInfo)
+ {
+ DebugFormat(DEBUG_APPID, "Ignoring direct service without info for AppId %d", appId);
+ return;
+ }
+ pEntry->svrValidator = ServiceGetServiceElement(fcn, nullptr, pConfig);
+ if (pEntry->svrValidator)
+ pEntry->flags |= extractsInfo;
+ else
+ ErrorMessage("AppId: failed to find a service element for AppId %d", appId);
+}
+
/**free ServiceMatch List.
*/
void AppIdFreeServiceMatchList(ServiceMatch* sm)
}
}
-int AddFTPServiceState(AppIdData* fp)
+int AddFTPServiceState(AppIdSession* fp)
{
if (!ftp_service)
return -1;
- return AppIdFlowdataAddId(fp, 21, ftp_service);
+ return fp->add_flow_data_id(21, ftp_service);
}
/**allocate one ServiceMatch element.
IpProtocol protocol,
uint16_t port,
const RNAServiceElement* const lasService,
- AppIdData* rnaData,
+ AppIdSession* rnaData,
const AppIdConfig* pConfig
)
{
{
li->ref_count--;
sflist_remove_node(listTmp, iter);
- // FIXIT - M Revisit this for better solution to calling sflist_first after
+ // FIXIT-M: Revisit this for better solution to calling sflist_first after
// deleting a node... ultimate solution for use of sflist would be move
// to STL
liTmp = (RNAServiceElement*)sflist_first(listTmp, &iter);
ServiceRemovePorts(validate, nullptr, pConfig);
}
-int ServiceAddPort(RNAServiceValidationPort* pp, RNAServiceValidationModule* svm,
+int ServiceAddPort(const RNAServiceValidationPort* pp, RNAServiceValidationModule* svm,
struct Detector* userdata, AppIdConfig* pConfig)
{
SF_LIST** services;
return 0;
}
-static int CServiceAddPort(RNAServiceValidationPort* pp, RNAServiceValidationModule* svm,
+static int CServiceAddPort(const RNAServiceValidationPort* pp, RNAServiceValidationModule* svm,
AppIdConfig* pConfig)
{
{
static unsigned service_module_index = 0;
RNAServiceValidationModule* svm = (RNAServiceValidationModule*)symbol;
- RNAServiceValidationPort* pp;
+ const RNAServiceValidationPort* pp;
if (service_module_index >= 65536)
{
}
svm->api = &serviceapi;
- for (pp=svm->pp; pp && pp->validate; pp++)
+ for (pp = svm->pp; pp && pp->validate; pp++)
if (CServiceAddPort(pp, svm, pConfig))
return -1;
int ReloadServiceModules(AppIdConfig* pConfig)
{
RNAServiceValidationModule* svm;
- RNAServiceValidationPort* pp;
+ const RNAServiceValidationPort* pp;
- svc_init_api.debug = app_id_debug;
+ svc_init_api.debug = pAppidActiveConfig->mod_config->debug;
svc_init_api.pAppidConfig = pConfig;
// active_service_list contains both service modules and services associated with
// processing only non-lua service detectors.
if (svm->init)
{
- for (pp=svm->pp; pp && pp->validate; pp++)
+ for (pp = svm->pp; pp && pp->validate; pp++)
if (CServiceAddPort(pp, svm, pConfig))
return -1;
}
cleanupFreeServiceMatch();
if (smOrderedList)
{
- // FIXIT - M - still allocated with calloc/realloc - vector coming soon...
+ // FIXIT-M: still allocated with calloc/realloc - vector coming soon...
free(smOrderedList);
smOrderedListSize = 32;
}
if (!smOrderedList)
{
- // FIXIT - H - using calloc because this may be realloc'ed later, change to vector asap
+ // FIXIT-M: - using calloc because this may be realloc'ed later, change to vector asap
smOrderedList = (ServiceMatch**)calloc(smOrderedListSize, sizeof(ServiceMatch*));
if (!smOrderedList)
{
return service;
}
-static void AppIdAddHostInfo(AppIdData*, SERVICE_HOST_INFO_CODE, const void*)
+static void AppIdAddHostInfo(AppIdSession*, SERVICE_HOST_INFO_CODE, const void*)
{
}
snort_free(dd);
}
-static int AppIdAddDHCP(AppIdData* flowp, unsigned op55_len, const uint8_t* op55, unsigned
+static int AppIdAddDHCP(AppIdSession* flowp, unsigned op55_len, const uint8_t* op55, unsigned
op60_len, const uint8_t* op60, const uint8_t* mac)
{
- if (op55_len && op55_len <= DHCP_OPTION55_LEN_MAX && !getAppIdFlag(flowp,
- APPID_SESSION_HAS_DHCP_FP))
+ if (op55_len && op55_len <= DHCP_OPTION55_LEN_MAX
+ && !flowp->getAppIdFlag(APPID_SESSION_HAS_DHCP_FP))
{
DhcpFPData* rdd;
rdd = (DhcpFPData*)snort_calloc(sizeof(*rdd));
- if (AppIdFlowdataAdd(flowp, rdd, APPID_SESSION_DATA_DHCP_FP_DATA,
+ if (flowp->add_flow_data(rdd, APPID_SESSION_DATA_DHCP_FP_DATA,
(AppIdFreeFCN)AppIdFreeDhcpData))
{
AppIdFreeDhcpData(rdd);
return -1;
}
- setAppIdFlag(flowp, APPID_SESSION_HAS_DHCP_FP);
+ flowp->setAppIdFlag(APPID_SESSION_HAS_DHCP_FP);
rdd->op55_len = (op55_len > DHCP_OP55_MAX_SIZE) ? DHCP_OP55_MAX_SIZE : op55_len;
memcpy(rdd->op55, op55, rdd->op55_len);
rdd->op60_len = (op60_len > DHCP_OP60_MAX_SIZE) ? DHCP_OP60_MAX_SIZE : op60_len;
}
}
-static void AppIdAddHostIP(AppIdData* flow, const uint8_t* mac, uint32_t ip, int32_t zone,
+static void AppIdAddHostIP(AppIdSession* flow, const uint8_t* mac, uint32_t ip, int32_t zone,
uint32_t subnetmask, uint32_t leaseSecs, uint32_t router)
{
DHCPInfo* info;
if (memcmp(mac, zeromac, 6) == 0 || ip == 0)
return;
- if (!getAppIdFlag(flow, APPID_SESSION_DO_RNA) || getAppIdFlag(flow,
- APPID_SESSION_HAS_DHCP_INFO))
+ if (!flow->getAppIdFlag(APPID_SESSION_DO_RNA)
+ || flow->getAppIdFlag(APPID_SESSION_HAS_DHCP_INFO))
return;
flags = isIPv4HostMonitored(ntohl(ip), zone);
else
info = (DHCPInfo*)snort_calloc(sizeof(DHCPInfo));
- if (AppIdFlowdataAdd(flow, info, APPID_SESSION_DATA_DHCP_INFO,
+ if (flow->add_flow_data(info, APPID_SESSION_DATA_DHCP_INFO,
(AppIdFreeFCN)AppIdFreeDhcpInfo))
{
AppIdFreeDhcpInfo(info);
return;
}
- setAppIdFlag(flow, APPID_SESSION_HAS_DHCP_INFO);
+ flow->setAppIdFlag(APPID_SESSION_HAS_DHCP_INFO);
info->ipAddr = ip;
memcpy(info->macAddr, mac, sizeof(info->macAddr));
info->subnetmask = subnetmask;
}
}
-static void AppIdAddSMBData(AppIdData* flow, unsigned major, unsigned minor, uint32_t flags)
+static void AppIdAddSMBData(AppIdSession* flow, unsigned major, unsigned minor, uint32_t flags)
{
FpSMBData* sd;
else
sd = (FpSMBData*)snort_calloc(sizeof(FpSMBData));
- if (AppIdFlowdataAdd(flow, sd, APPID_SESSION_DATA_SMB_DATA, (AppIdFreeFCN)AppIdFreeSMBData))
+ if (flow->add_flow_data(sd, APPID_SESSION_DATA_SMB_DATA, (AppIdFreeFCN)AppIdFreeSMBData))
{
AppIdFreeSMBData(sd);
return;
}
- setAppIdFlag(flow, APPID_SESSION_HAS_SMB_INFO);
+ flow->setAppIdFlag(APPID_SESSION_HAS_SMB_INFO);
sd->major = major;
sd->minor = minor;
sd->flags = flags & FINGERPRINT_UDP_FLAGS_MASK;
}
-static int AppIdServiceAddServiceEx(AppIdData* flow, const Packet* pkt, int dir,
+static int AppIdServiceAddServiceEx(AppIdSession* flow, const Packet* pkt, int dir,
const RNAServiceElement* svc_element,
AppId appId, const char* vendor, const char* version)
{
snort_free(flow->serviceVersion);
flow->serviceVersion = snort_strdup(version);
}
- setAppIdFlag(flow, APPID_SESSION_SERVICE_DETECTED);
+ flow->setAppIdFlag(APPID_SESSION_SERVICE_DETECTED);
flow->serviceAppId = appId;
checkSandboxDetection(appId);
- if (getAppIdFlag(flow, APPID_SESSION_IGNORE_HOST))
+ if (flow->getAppIdFlag(APPID_SESSION_IGNORE_HOST))
return SERVICE_SUCCESS;
- if (!getAppIdFlag(flow, APPID_SESSION_UDP_REVERSED))
+ if (!flow->getAppIdFlag(APPID_SESSION_UDP_REVERSED))
{
if (dir == APP_ID_FROM_INITIATOR)
{
/* If we ended up with UDP reversed, make sure we're pointing to the
* correct host tracker entry. */
- if (getAppIdFlag(flow, APPID_SESSION_UDP_REVERSED))
+ if (flow->getAppIdFlag(APPID_SESSION_UDP_REVERSED))
{
- flow->id_state = AppIdGetServiceIDState(ip, flow->proto, port,
+ flow->id_state = AppIdGetServiceIDState(ip, flow->protocol, port,
AppIdServiceDetectionLevel(flow));
}
if (!(id_state = flow->id_state))
{
- if (!(id_state = AppIdAddServiceIDState(ip, flow->proto, port, AppIdServiceDetectionLevel(
+ if (!(id_state = AppIdAddServiceIDState(ip, flow->protocol, port, AppIdServiceDetectionLevel(
flow))))
{
ErrorMessage("Add service failed to create state");
return SERVICE_SUCCESS;
}
-int AppIdServiceAddServiceSubtype(AppIdData* flow, const Packet* pkt, int dir,
+int AppIdServiceAddServiceSubtype(AppIdSession* flow, const Packet* pkt, int dir,
const RNAServiceElement* svc_element,
AppId appId, const char* vendor, const char* version,
RNAServiceSubtype* subtype)
return AppIdServiceAddServiceEx(flow, pkt, dir, svc_element, appId, vendor, version);
}
-int AppIdServiceAddService(AppIdData* flow, const Packet* pkt, int dir,
+int AppIdServiceAddService(AppIdSession* flow, const Packet* pkt, int dir,
const RNAServiceElement* svc_element,
AppId appId, const char* vendor, const char* version,
const RNAServiceSubtype* subtype)
return AppIdServiceAddServiceEx(flow, pkt, dir, svc_element, appId, vendor, version);
}
-int AppIdServiceInProcess(AppIdData* flow, const Packet* pkt, int dir,
+int AppIdServiceInProcess(AppIdSession* flow, const Packet* pkt, int dir,
const RNAServiceElement* svc_element)
{
AppIdServiceIDState* id_state;
return SERVICE_EINVALID;
}
- if (dir == APP_ID_FROM_INITIATOR || getAppIdFlag(flow, APPID_SESSION_IGNORE_HOST|
+ if (dir == APP_ID_FROM_INITIATOR || flow->getAppIdFlag(APPID_SESSION_IGNORE_HOST|
APPID_SESSION_UDP_REVERSED))
return SERVICE_SUCCESS;
ip = pkt->ptrs.ip_api.get_src();
port = flow->service_port ? flow->service_port : pkt->ptrs.sp;
- if (!(id_state = AppIdAddServiceIDState(ip, flow->proto, port, AppIdServiceDetectionLevel(
+ if (!(id_state = AppIdAddServiceIDState(ip, flow->protocol, port, AppIdServiceDetectionLevel(
flow))))
{
ErrorMessage("In-process service failed to create state");
* 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 AppIdServiceIncompatibleData(AppIdData* flow, const Packet* pkt, int dir,
+int AppIdServiceIncompatibleData(AppIdSession* flow, const Packet* pkt, int dir,
const RNAServiceElement* svc_element, unsigned flow_data_index, const AppIdConfig*)
{
AppIdServiceIDState* id_state;
}
if (flow_data_index != APPID_SESSION_DATA_NONE)
- AppIdFlowdataDelete(flow, flow_data_index);
+ flow->free_flow_data_by_id(flow_data_index);
/* If we're still working on a port/pattern list of detectors, then ignore
* individual fails until we're done looking at everything. */
}
}
- setAppIdFlag(flow, APPID_SESSION_SERVICE_DETECTED);
- clearAppIdFlag(flow, APPID_SESSION_CONTINUE);
+ flow->setAppIdFlag(APPID_SESSION_SERVICE_DETECTED);
+ flow->clearAppIdFlag(APPID_SESSION_CONTINUE);
flow->serviceAppId = APP_ID_NONE;
- if (getAppIdFlag(flow, APPID_SESSION_IGNORE_HOST|APPID_SESSION_UDP_REVERSED) || (svc_element &&
+ if (flow->getAppIdFlag(APPID_SESSION_IGNORE_HOST|APPID_SESSION_UDP_REVERSED) || (svc_element &&
!svc_element->current_ref_count))
return SERVICE_SUCCESS;
if (dir == APP_ID_FROM_INITIATOR)
{
- setAppIdFlag(flow, APPID_SESSION_INCOMPATIBLE);
+ flow->setAppIdFlag(APPID_SESSION_INCOMPATIBLE);
return SERVICE_SUCCESS;
}
ip = pkt->ptrs.ip_api.get_src();
port = flow->service_port ? flow->service_port : pkt->ptrs.sp;
- if (!(id_state = AppIdAddServiceIDState(ip, flow->proto, port, AppIdServiceDetectionLevel(
+ if (!(id_state = AppIdAddServiceIDState(ip, flow->protocol, port, AppIdServiceDetectionLevel(
flow))))
{
ErrorMessage("Incompatible service failed to create state");
return SERVICE_SUCCESS;
}
-int AppIdServiceFailService(AppIdData* flow, const Packet* pkt, int dir,
+int AppIdServiceFailService(AppIdSession* flow, const Packet* pkt, int dir,
const RNAServiceElement* svc_element, unsigned flow_data_index, const AppIdConfig*)
{
AppIdServiceIDState* id_state;
if (flow_data_index != APPID_SESSION_DATA_NONE)
- AppIdFlowdataDelete(flow, flow_data_index);
+ flow->free_flow_data_by_id(flow_data_index);
/* If we're still working on a port/pattern list of detectors, then ignore
* individual fails until we're done looking at everything. */
flow->serviceAppId = APP_ID_NONE;
- setAppIdFlag(flow, APPID_SESSION_SERVICE_DETECTED);
- clearAppIdFlag(flow, APPID_SESSION_CONTINUE);
+ flow->setAppIdFlag(APPID_SESSION_SERVICE_DETECTED);
+ flow->clearAppIdFlag(APPID_SESSION_CONTINUE);
/* detectors should be careful in marking flow UDP_REVERSED otherwise the same detector
* gets all future flows. UDP_REVERSE should be marked only when detector positively
* matches opposite direction patterns. */
- if (getAppIdFlag(flow, APPID_SESSION_IGNORE_HOST | APPID_SESSION_UDP_REVERSED)
+ if (flow->getAppIdFlag(APPID_SESSION_IGNORE_HOST | APPID_SESSION_UDP_REVERSED)
|| (svc_element && !svc_element->current_ref_count))
return SERVICE_SUCCESS;
* otherwise the service will show up on client side. */
if (dir == APP_ID_FROM_INITIATOR)
{
- setAppIdFlag(flow, APPID_SESSION_INCOMPATIBLE);
+ flow->setAppIdFlag(APPID_SESSION_INCOMPATIBLE);
return SERVICE_SUCCESS;
}
ip = pkt->ptrs.ip_api.get_src();
port = flow->service_port ? flow->service_port : pkt->ptrs.sp;
- if (!(id_state = AppIdAddServiceIDState(ip, flow->proto, port, AppIdServiceDetectionLevel(
+ if (!(id_state = AppIdAddServiceIDState(ip, flow->protocol, port, AppIdServiceDetectionLevel(
flow))))
{
ErrorMessage("Fail service failed to create state");
* - invalid_client_count: If our service detector search had trouble
* simply because of unrecognized client data, then consider retrying
* the search again. */
-static void HandleFailure(AppIdData* flowp,
+static void HandleFailure(AppIdSession* flowp,
AppIdServiceIDState* id_state,
const sfip_t* client_ip,
unsigned timeout)
*
* @note Packet may be nullptr when this function is called upon session timeout.
*/
-void FailInProcessService(AppIdData* flowp, const AppIdConfig*)
+void FailInProcessService(AppIdSession* flowp, const AppIdConfig*)
{
AppIdServiceIDState* id_state;
- if (getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED|APPID_SESSION_UDP_REVERSED))
+ if (flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED|APPID_SESSION_UDP_REVERSED))
return;
- id_state = AppIdGetServiceIDState(&flowp->service_ip, flowp->proto, flowp->service_port,
+ id_state = AppIdGetServiceIDState(&flowp->service_ip, flowp->protocol, flowp->service_port,
AppIdServiceDetectionLevel(flowp));
#ifdef SERVICE_DEBUG
id_state->invalid_client_count += STATE_ID_INCONCLUSIVE_SERVICE_WEIGHT;
- // FIXIT - we need a Flow to get the ip address of client/server...
+ // FIXIT-M: we need a Flow to get the ip address of client/server...
#ifdef REMOVED_WHILE_NOT_IN_USE
sfip_t* tmp_ip = _dpd.sessionAPI->get_session_ip_address(flowp->ssn, SSN_DIR_FROM_SERVER);
if (sfip_fast_eq6(tmp_ip, &flowp->service_ip))
* through the main port/pattern search (and returning which detector to add
* next to the list of detectors to try (even if only 1)). */
static const RNAServiceElement* AppIdGetNexService(const Packet* p, const int dir,
- AppIdData* rnaData, const AppIdConfig* pConfig, AppIdServiceIDState* id_state)
+ AppIdSession* rnaData, const AppIdConfig* pConfig, AppIdServiceIDState* id_state)
{
- auto proto = rnaData->proto;
+ auto proto = rnaData->protocol;
/* If NEW, just advance onto trying ports. */
if (id_state->state == SERVICE_ID_NEW)
* first with UDP reversed services before moving onto pattern matches. */
if (dir == APP_ID_FROM_INITIATOR)
{
- if (!getAppIdFlag(rnaData, APPID_SESSION_ADDITIONAL_PACKET) && (proto ==
- IpProtocol::UDP)
- && !rnaData->tried_reverse_service )
+ if (!rnaData->getAppIdFlag(APPID_SESSION_ADDITIONAL_PACKET)
+ && (proto == IpProtocol::UDP) && !rnaData->tried_reverse_service )
{
SF_LNODE* iter;
AppIdServiceIDState* reverse_id_state;
return nullptr;
}
-int AppIdDiscoverService(Packet* p, const int dir, AppIdData* rnaData,
+int AppIdDiscoverService(Packet* p, const int dir, AppIdSession* rnaData,
const AppIdConfig* pConfig)
{
const sfip_t* ip;
ServiceValidationArgs args;
/* Get packet info. */
- auto proto = rnaData->proto;
+ auto proto = rnaData->protocol;
if (sfip_is_set(&rnaData->service_ip))
{
ip = &rnaData->service_ip;
return ret;
}
-static void* service_flowdata_get(AppIdData* flow, unsigned service_id)
+static void* service_flowdata_get(AppIdSession* flow, unsigned service_id)
{
- return AppIdFlowdataGet(flow, service_id);
+ return flow->get_flow_data(service_id);
}
-static int service_flowdata_add(AppIdData* flow, void* data, unsigned service_id, AppIdFreeFCN
+static int service_flowdata_add(AppIdSession* flow, void* data, unsigned service_id, AppIdFreeFCN
fcn)
{
- return AppIdFlowdataAdd(flow, data, service_id, fcn);
+ return flow->add_flow_data(data, service_id, fcn);
}
/** GUS: 2006 09 28 10:10:54
fprintf(stream,") \n");
}
-static void AppIdServiceAddMisc(AppIdData* flow, AppId miscId)
+static void AppIdServiceAddMisc(AppIdSession* flow, AppId miscId)
{
if (flow != nullptr)
- flow->miscAppId = miscId;
+ flow->misc_app_id = miscId;
}
#include <cstdint>
#include "appid_api.h"
-#include "appid_flow_data.h"
+#include "appid_session.h"
#include "service_api.h"
#include "sfip/sf_ip.h"
class AppIdConfig;
-class AppIdData;
+class AppIdSession;
struct RNAServiceElement;
struct DhcpFPData;
struct FpSMBData;
void UnconfigureServices(AppIdConfig*);
void ServiceInit(AppIdConfig*);
void ServiceFinalize(AppIdConfig*);
-void FailInProcessService(AppIdData*, const AppIdConfig*);
+void FailInProcessService(AppIdSession*, const AppIdConfig*);
int LoadServiceModules(const char** dir_list, uint32_t instance_id, AppIdConfig*);
// This function is called during reload/reconfiguration. It registers service ports in the given
int ReloadServiceModules(AppIdConfig*);
int serviceLoadCallback(void* symbol);
int serviceLoadForConfigCallback(void* symbol, AppIdConfig*);
-int ServiceAddPort(RNAServiceValidationPort*, RNAServiceValidationModule*, Detector*,
+int ServiceAddPort(const RNAServiceValidationPort*, RNAServiceValidationModule*, Detector*,
AppIdConfig*);
void ServiceRemovePorts(RNAServiceValidationFCN, Detector*, AppIdConfig*);
void ServiceRegisterPatternDetector(RNAServiceValidationFCN, IpProtocol proto,
const uint8_t* pattern, unsigned size, int position, Detector*, const char* name);
-int AppIdDiscoverService(Packet*, int direction, AppIdData*, const AppIdConfig*);
+int AppIdDiscoverService(Packet*, int direction, AppIdSession*, const AppIdConfig*);
AppId getPortServiceId(IpProtocol proto, uint16_t port, const AppIdConfig*);
void AppIdFreeServiceIDState(AppIdServiceIDState*);
-int AppIdServiceAddService(AppIdData*, const Packet*, int dir, const RNAServiceElement*,
+int AppIdServiceAddService(AppIdSession*, const Packet*, int dir, const RNAServiceElement*,
AppId appId, const char* vendor, const char* version, const RNAServiceSubtype*);
-int AppIdServiceAddServiceSubtype(AppIdData*, const Packet*, int dir, const RNAServiceElement*,
+int AppIdServiceAddServiceSubtype(AppIdSession*, const Packet*, int dir, const RNAServiceElement*,
AppId, const char* vendor, const char* version, RNAServiceSubtype*);
-int AppIdServiceInProcess(AppIdData*, const Packet*, int dir, const RNAServiceElement*);
-int AppIdServiceIncompatibleData(AppIdData*, const Packet*, int dir, const RNAServiceElement*,
+int AppIdServiceInProcess(AppIdSession*, const Packet*, int dir, const RNAServiceElement*);
+int AppIdServiceIncompatibleData(AppIdSession*, const Packet*, int dir, const RNAServiceElement*,
unsigned flow_data_index, const AppIdConfig*);
-int AppIdServiceFailService(AppIdData*, const Packet*, int dir, const RNAServiceElement*,
+int AppIdServiceFailService(AppIdSession*, const Packet*, int dir, const RNAServiceElement*,
unsigned flow_data_index, const AppIdConfig*);
-int AddFTPServiceState(AppIdData*);
+int AddFTPServiceState(AppIdSession*);
void AppIdFreeDhcpInfo(DHCPInfo*);
void AppIdFreeSMBData(FpSMBData*);
void AppIdFreeDhcpData(DhcpFPData*);
return (first->validate != second->validate || first->userdata != second->userdata);
}
-inline uint32_t AppIdServiceDetectionLevel(AppIdData* session)
+inline uint32_t AppIdServiceDetectionLevel(AppIdSession* session)
{
- if (getAppIdFlag(session, APPID_SESSION_DECRYPTED))
+ if (session->getAppIdFlag(APPID_SESSION_DECRYPTED))
return 1;
return 0;
}
-inline void PopulateExpectedFlow(AppIdData* parent, AppIdData* expected, uint64_t flags)
+inline void PopulateExpectedFlow(AppIdSession* parent, AppIdSession* expected, uint64_t flags)
{
- setAppIdFlag(expected, flags |
- getAppIdFlag(parent,
- APPID_SESSION_RESPONDER_MONITORED |
- APPID_SESSION_INITIATOR_MONITORED |
- APPID_SESSION_SPECIAL_MONITORED |
- APPID_SESSION_RESPONDER_CHECKED |
- APPID_SESSION_INITIATOR_CHECKED |
- APPID_SESSION_DISCOVER_APP |
- APPID_SESSION_DISCOVER_USER));
+ expected->setAppIdFlag(flags |
+ parent->getAppIdFlag(APPID_SESSION_RESPONDER_MONITORED |
+ APPID_SESSION_INITIATOR_MONITORED |
+ APPID_SESSION_SPECIAL_MONITORED |
+ APPID_SESSION_RESPONDER_CHECKED |
+ APPID_SESSION_INITIATOR_CHECKED |
+ APPID_SESSION_DISCOVER_APP |
+ APPID_SESSION_DISCOVER_USER));
expected->rnaServiceState = RNA_STATE_FINISHED;
- expected->rnaClientState = RNA_STATE_FINISHED;
+ expected->rna_client_state = RNA_STATE_FINISHED;
}
#endif
static int battle_field_validate(ServiceValidationArgs* args)
{
ServiceData* fd;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
Packet* pkt = args->pkt;
uint16_t size = args->size;
{
ServiceBGPData* bd;
const ServiceBGPHeader* bh;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
uint16_t size = args->size;
uint16_t len;
static int bit_validate(ServiceValidationArgs* args)
{
ServiceBITData* ss;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
uint16_t size = args->size;
uint16_t offset;
unsigned op60_len=0;
const uint8_t* op55=nullptr;
const uint8_t* op60=nullptr;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
Packet* pkt = args->pkt;
const int dir = args->dir;
if (dir == APP_ID_FROM_INITIATOR)
{
- setAppIdFlag(flowp, APPID_SESSION_UDP_REVERSED);
+ flowp->setAppIdFlag(APPID_SESSION_UDP_REVERSED);
}
else
{
- clearAppIdFlag(flowp, APPID_SESSION_UDP_REVERSED);
+ flowp->clearAppIdFlag(APPID_SESSION_UDP_REVERSED);
}
if (size > sizeof(ServiceBOOTPHeader) + 4)
}
success:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
- setAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->setAppIdFlag(APPID_SESSION_CONTINUE);
bootp_service_mod.api->add_service(flowp, args->pkt, args->dir, &svc_element,
APP_ID_DHCP, nullptr, nullptr, nullptr);
}
return SERVICE_SUCCESS;
inprocess:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
bootp_service_mod.api->service_inprocess(flowp, args->pkt, args->dir, &svc_element);
}
return SERVICE_INPROCESS;
fail:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
bootp_service_mod.api->fail_service(flowp, args->pkt, args->dir, &svc_element,
bootp_service_mod.flow_data_index, args->pConfig);
}
- clearAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->clearAppIdFlag(APPID_SESSION_CONTINUE);
return SERVICE_NOMATCH;
not_compatible:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
bootp_service_mod.api->incompatible_data(flowp, args->pkt, args->dir, &svc_element,
bootp_service_mod.flow_data_index, args->pConfig);
ServiceDCERPCData* dd;
int retval = SERVICE_INPROCESS;
int length;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
uint16_t size = args->size;
ServiceDCERPCData* dd;
int retval = SERVICE_NOMATCH;
int length;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
uint16_t size = args->size;
static int direct_connect_init(const IniServiceAPI* const init_api);
static int direct_connect_validate(ServiceValidationArgs* args);
static int validateDirectConnectTcp(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, const Packet* pkt, ServiceData* serviceData,
+ AppIdSession* flowp, const Packet* pkt, ServiceData* serviceData,
const AppIdConfig* pConfig);
static int validateDirectConnectUdp(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, const Packet* pkt, ServiceData* serviceData,
+ AppIdSession* flowp, const Packet* pkt, ServiceData* serviceData,
const AppIdConfig* pConfig);
static RNAServiceElement svc_element =
static int direct_connect_validate(ServiceValidationArgs* args)
{
ServiceData* fd;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
uint16_t size = args->size;
directconnect_service_mod.flow_data_index, &snort_free);
}
- if (flowp->proto == IpProtocol::TCP)
+ if (flowp->protocol == IpProtocol::TCP)
return validateDirectConnectTcp(data, size, args->dir, flowp, args->pkt, fd,
args->pConfig);
else
}
static int validateDirectConnectTcp(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, const Packet* pkt, ServiceData* serviceData,
+ AppIdSession* flowp, const Packet* pkt, ServiceData* serviceData,
const AppIdConfig* pConfig)
{
switch (serviceData->state)
}
static int validateDirectConnectUdp(const uint8_t* data, uint16_t size, const int dir,
- AppIdData* flowp, const Packet* pkt, ServiceData* serviceData,
+ AppIdSession* flowp, const Packet* pkt, ServiceData* serviceData,
const AppIdConfig* pConfig)
{
if (dir == APP_ID_FROM_RESPONDER && serviceData->state == CONN_STATE_SERVICE_DETECTED)
const FLAPHeader* hdr = (const FLAPHeader*)args->data;
const FLAPFNAC* ff;
const FLAPTLV* tlv;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
uint16_t size = args->size;
uint16_t len;
#include "app_info_table.h"
#include "appid_api.h"
-#include "appid_flow_data.h"
+#include "appid_session.h"
#include "application_ids.h"
#include "service_base.h"
#include "service_util.h"
return 0;
}
-static inline void WatchForCommandResult(ServiceFTPData* fd, AppIdData* flowp, FTPCmd command)
+static inline void WatchForCommandResult(ServiceFTPData* fd, AppIdSession* flowp, FTPCmd command)
{
if (fd->state != FTP_STATE_MONITOR)
{
- setAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_CONTINUE);
+ flowp->setAppIdFlag(APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_CONTINUE);
fd->state = FTP_STATE_MONITOR;
}
fd->cmd = command;
}
-static inline void InitializeDataSession(AppIdData* flowp,AppIdData* fp)
+static inline void InitializeDataSession(AppIdSession* flowp,AppIdSession* fp)
{
- unsigned encryptedFlag = getAppIdFlag(flowp, APPID_SESSION_ENCRYPTED |
+ unsigned encryptedFlag = flowp->getAppIdFlag(APPID_SESSION_ENCRYPTED |
APPID_SESSION_DECRYPTED);
if (encryptedFlag == APPID_SESSION_ENCRYPTED)
{
int code_index;
uint32_t address;
uint16_t port;
- AppIdData* fp;
+ AppIdSession* fp;
int retval = SERVICE_INPROCESS;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
Packet* pkt = args->pkt;
const int dir = args->dir;
//to direct traffic to SSL detector to extract payload from certs. This will require
// manintaining
//two detector states at the same time.
- if (getAppIdFlag(flowp, APPID_SESSION_ENCRYPTED))
+ if (flowp->getAppIdFlag(APPID_SESSION_ENCRYPTED))
{
- if (!getAppIdFlag(flowp, APPID_SESSION_DECRYPTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_DECRYPTED))
{
goto inprocess;
}
case 551: /*requested action aborted :page type unknown */
case 552: /*requested action aborted */
case 553: /*requested action not taken file name is not allowed */
- setAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_CONTINUE);
+ flowp->setAppIdFlag(APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_CONTINUE);
fd->state = FTP_STATE_MONITOR;
break;
case 221: /*good bye */
fd->state = FTP_STATE_CONNECTION_ERROR;
break;
case 230:
- setAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->setAppIdFlag(APPID_SESSION_CONTINUE);
fd->state = FTP_STATE_MONITOR;
retval = SERVICE_SUCCESS;
break;
case 234:
{
- setAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->setAppIdFlag(APPID_SESSION_CONTINUE);
retval = SERVICE_SUCCESS;
/*
// we do not set the state to FTP_STATE_MONITOR here because we don't know
// if there will be SSL decryption to allow us to see what we are interested in.
// Let the WatchForCommandResult() usage elsewhere take care of it.
*/
- setAppIdFlag(flowp,
- APPID_SESSION_CONTINUE |
- APPID_SESSION_ENCRYPTED |
+ flowp->setAppIdFlag(APPID_SESSION_CONTINUE | APPID_SESSION_ENCRYPTED |
APPID_SESSION_STICKY_SERVICE);
}
break;
break;
case 202:
case 230:
- setAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->setAppIdFlag(APPID_SESSION_CONTINUE);
fd->state = FTP_STATE_MONITOR;
retval = SERVICE_SUCCESS;
default:
{
case 202:
case 230:
- setAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->setAppIdFlag(APPID_SESSION_CONTINUE);
fd->state = FTP_STATE_MONITOR;
retval = SERVICE_SUCCESS;
default:
sip = pkt->ptrs.ip_api.get_src();
addr = htonl(address);
sfip_set_raw(&ip, &addr, AF_INET);
- fp = ftp_service_mod.api->flow_new(flowp, pkt, dip, 0, &ip, port, flowp->proto,
- ftp_data_app_id,
+ fp = AppIdSession::create_future_session(pkt, dip, 0, &ip, port, flowp->protocol, ftp_data_app_id,
APPID_EARLY_SESSION_FLAG_FW_RULE);
if (fp)
- {
InitializeDataSession(flowp,fp);
- }
+
if (!sfip_fast_eq6(&ip, sip))
{
- fp = ftp_service_mod.api->flow_new(flowp, pkt, dip, 0, sip, port,
- flowp->proto, ftp_data_app_id,
+ fp = flowp->create_future_session(pkt, dip, 0, sip, port, flowp->protocol, ftp_data_app_id,
APPID_EARLY_SESSION_FLAG_FW_RULE);
if (fp)
- {
InitializeDataSession(flowp,fp);
- }
}
- ftp_service_mod.api->add_payload(flowp, APP_ID_FTP_PASSIVE); // Passive
- // mode FTP is
- // reported as
- // a payload
- // id
+ ftp_service_mod.api->add_payload(flowp, APP_ID_FTP_PASSIVE);
}
else if (code < 0)
- {
goto fail;
- }
}
break;
case 229:
const sfip_t* dip;
dip = pkt->ptrs.ip_api.get_dst();
sip = pkt->ptrs.ip_api.get_src();
- fp = ftp_service_mod.api->flow_new(flowp, pkt, dip, 0, sip, port, flowp->proto,
+ fp = flowp->create_future_session(pkt, dip, 0, sip, port, flowp->protocol,
ftp_data_app_id,
APPID_EARLY_SESSION_FLAG_FW_RULE);
if (fp)
- {
InitializeDataSession(flowp,fp);
- }
- ftp_service_mod.api->add_payload(flowp, APP_ID_FTP_PASSIVE); // Passive
- // mode FTP is
- // reported as
- // a payload
- // id
+ ftp_service_mod.api->add_payload(flowp, APP_ID_FTP_PASSIVE);
}
else if (code < 0)
- {
goto fail;
- }
}
break;
case 200:
{
const sfip_t* sip;
sip = pkt->ptrs.ip_api.get_src();
- fp = ftp_service_mod.api->flow_new(flowp, pkt, sip, 0, &fd->address, fd->port,
- flowp->proto, ftp_data_app_id,
+ fp = flowp->create_future_session(pkt, sip, 0, &fd->address, fd->port, flowp->protocol, ftp_data_app_id,
APPID_EARLY_SESSION_FLAG_FW_RULE);
if (fp)
- {
InitializeDataSession(flowp,fp);
- }
ftp_service_mod.api->add_payload(flowp, APP_ID_FTP_ACTIVE); // Active mode FTP
// is reported as a
// payload id
default:
case SERVICE_INPROCESS:
inprocess:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
ftp_service_mod.api->service_inprocess(flowp, pkt, dir, &svc_element);
}
return SERVICE_INPROCESS;
case SERVICE_SUCCESS:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
- uint64_t encryptedFlag = getAppIdFlag(flowp,
+ uint64_t encryptedFlag = flowp->getAppIdFlag(
APPID_SESSION_ENCRYPTED | APPID_SESSION_DECRYPTED);
// FTPS only when encrypted==1 decrypted==0
case SERVICE_NOMATCH:
fail:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
ftp_service_mod.api->fail_service(flowp, pkt, dir, &svc_element,
ftp_service_mod.flow_data_index, args->pConfig);
}
- clearAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->clearAppIdFlag(APPID_SESSION_CONTINUE);
return SERVICE_NOMATCH;
}
}
#include "main/snort_debug.h"
#include "utils/util.h"
-#include "appid_flow_data.h"
+#include "appid_session.h"
#include "application_ids.h"
#include "appid_module.h"
IRCState* state;
unsigned* pos;
const char** command;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
const int dir = args->dir;
uint16_t size = args->size;
#include "appid_module.h"
#include "application_ids.h"
-#include "appid_flow_data.h"
+#include "appid_session.h"
#include "app_info_table.h"
#include "service_api.h"
{
ServiceLPRData* ld;
int i;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
const int dir = args->dir;
uint16_t size = args->size;
#include "client_plugins/client_app_base.h"
#include "detector_plugins/http_url_patterns.h"
#include "detector_plugins/detector_http.h"
-#include "util/common_util.h"
+#include "appid_utils/common_util.h"
#include "appid_config.h"
-#include "appid_flow_data.h"
+#include "appid_session.h"
#include "fw_appid.h"
#include "http_common.h"
#include "lua_detector_api.h"
2. Calls the function which scans for pattern to identify the user
3. Calls the function which does the Username reporting along with the host
MDNS User Analysis*/
-static int MDNSUserAnalyser(AppIdData* flowp, const Packet* pkt, uint16_t size, const
+static int MDNSUserAnalyser(AppIdSession* flowp, const Packet* pkt, uint16_t size, const
AppIdConfig* pConfig)
{
const char* query_val;
{
ServiceMDNSData* fd;
int ret_val;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
Packet* pkt = args->pkt;
uint16_t size = args->size;
#include "application_ids.h"
#include "app_info_table.h"
-#include "appid_flow_data.h"
+#include "appid_session.h"
#include "service_api.h"
#include "appid_module.h"
uint32_t len;
const uint8_t* end;
const uint8_t* p = nullptr;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
uint16_t size = args->size;
if (!size)
#include "appid_module.h"
#include "app_info_table.h"
#include "appid_api.h"
-#include "appid_flow_data.h"
+#include "appid_session.h"
#include "application_ids.h"
#include "dcerpc.h"
#include "service_api.h"
const NBNSHeader* hdr;
const uint8_t* begin;
const uint8_t* end;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
const int dir = args->dir;
uint16_t size = args->size;
{
if (dir == APP_ID_FROM_RESPONDER)
{
- if (getAppIdFlag(flowp, APPID_SESSION_UDP_REVERSED))
+ if (flowp->getAppIdFlag(APPID_SESSION_UDP_REVERSED))
goto success;
goto fail;
}
if (dir == APP_ID_FROM_INITIATOR)
{
- setAppIdFlag(flowp, APPID_SESSION_UDP_REVERSED);
+ flowp->setAppIdFlag(APPID_SESSION_UDP_REVERSED);
goto inprocess;
}
}
static inline void smb_find_domain(const uint8_t* data, uint16_t size, const int,
- AppIdData* flowp, const Packet* pkt)
+ AppIdSession* flowp, const Packet* pkt)
{
const ServiceSMBHeader* smb;
const ServiceSMBAndXResponse* resp;
domain, smb->command, pkt->src_ip.s_addr, pkt->src_port, pkt->dst_ip.s_addr,
pkt->dst_port);
#endif
- if (!flowp->netbiosDomain)
- flowp->netbiosDomain = snort_strdup(domain);
+ if (!flowp->netbios_domain)
+ flowp->netbios_domain = snort_strdup(domain);
}
}
const uint8_t* end;
uint32_t tmp;
int retval = -1;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
Packet* pkt = args->pkt;
const uint8_t* data = args->data;
const int dir = args->dir;
if (retval == -1)
goto inprocess;
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
if (netbios_service_mod.api->add_service(flowp, pkt, dir, &nbss_svc_element,
nd->serviceAppId, nullptr, nullptr, nullptr) == SERVICE_SUCCESS)
return SERVICE_SUCCESS;
inprocess:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
netbios_service_mod.api->service_inprocess(flowp, pkt, dir, &nbss_svc_element);
}
return SERVICE_INPROCESS;
fail:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
netbios_service_mod.api->fail_service(flowp, pkt, dir, &nbss_svc_element,
netbios_service_mod.flow_data_index, args->pConfig);
uint32_t server_type;
AppId serviceAppId = APP_ID_NETBIOS_DGM;
AppId miscAppId = APP_ID_NONE;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
Packet* pkt = args->pkt;
const int dir = args->dir;
if (end-data >= (int)sizeof(NB_SMB_BANNER) &&
!memcmp(data, NB_SMB_BANNER, sizeof(NB_SMB_BANNER)))
{
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
serviceAppId = APP_ID_NETBIOS_DGM;
}
if (source_name[0])
netbios_service_mod.api->add_host_info(flowp, SERVICE_HOST_INFO_NETBIOS_NAME,
source_name);
- setAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->setAppIdFlag(APPID_SESSION_CONTINUE);
goto success;
case NBDGM_TYPE_ERROR:
if (end-data < (int)sizeof(NBDgmError))
}
fail:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
netbios_service_mod.api->fail_service(flowp, pkt, dir, &nbdgm_svc_element,
netbios_service_mod.flow_data_index,
args->pConfig);
}
- clearAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->clearAppIdFlag(APPID_SESSION_CONTINUE);
return SERVICE_NOMATCH;
success:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
if (dir == APP_ID_FROM_RESPONDER)
{
return SERVICE_SUCCESS;
inprocess:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
netbios_service_mod.api->service_inprocess(flowp, pkt, dir, &nbdgm_svc_element);
}
#include "main/snort_debug.h"
#include "utils/util.h"
-#include "appid_flow_data.h"
+#include "appid_session.h"
#include "application_ids.h"
#include "service_api.h"
ServiceNNTPData* nd;
uint16_t offset;
int code;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
uint16_t size = args->size;
#include "main/snort_debug.h"
-#include "appid_flow_data.h"
+#include "appid_session.h"
#include "application_ids.h"
#include "service_api.h"
const ServiceNTPHeader* nh;
uint8_t ver;
uint8_t mode;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
uint16_t size = args->size;
#include "utils/util.h"
#include "app_info_table.h"
-#include "appid_flow_data.h"
+#include "appid_session.h"
#include "application_ids.h"
#include "service_api.h"
const RADIUSHeader* hdr = (const RADIUSHeader*)args->data;
uint16_t len;
int new_dir;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const int dir = args->dir;
uint16_t size = args->size;
hdr->code == RADIUS_CODE_ACCESS_REJECT ||
hdr->code == RADIUS_CODE_ACCESS_CHALLENGE)
{
- setAppIdFlag(flowp, APPID_SESSION_UDP_REVERSED);
+ flowp->setAppIdFlag(APPID_SESSION_UDP_REVERSED);
rd->state = RADIUS_STATE_RESPONSE;
new_dir = APP_ID_FROM_RESPONDER;
}
}
- else if (getAppIdFlag(flowp, APPID_SESSION_UDP_REVERSED))
+ else if (flowp->getAppIdFlag(APPID_SESSION_UDP_REVERSED))
{
new_dir = (dir == APP_ID_FROM_RESPONDER) ? APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
}
const RADIUSHeader* hdr = (const RADIUSHeader*)args->data;
uint16_t len;
int new_dir;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const int dir = args->dir;
uint16_t size = args->size;
{
if (hdr->code == RADIUS_CODE_ACCOUNTING_RESPONSE)
{
- setAppIdFlag(flowp, APPID_SESSION_UDP_REVERSED);
+ flowp->setAppIdFlag(APPID_SESSION_UDP_REVERSED);
rd->state = RADIUS_STATE_RESPONSE;
new_dir = APP_ID_FROM_RESPONDER;
}
}
- else if (getAppIdFlag(flowp, APPID_SESSION_UDP_REVERSED))
+ else if (flowp->getAppIdFlag(APPID_SESSION_UDP_REVERSED))
{
new_dir = (dir == APP_ID_FROM_RESPONDER) ? APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
}
#include "appid_api.h"
#include "app_info_table.h"
-#include "appid_flow_data.h"
+#include "appid_session.h"
#include "application_ids.h"
#include "service_api.h"
#include "service_base.h"
{
int i;
uint32_t port;
- AppIdData* pf;
- AppIdData* flowp = args->flowp;
+ AppIdSession* pf;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
Packet* pkt = args->pkt;
const int dir = args->dir;
dip = pkt->ptrs.ip_api.get_dst();
sip = pkt->ptrs.ip_api.get_src();
- pf = rexec_service_mod.api->flow_new(flowp, pkt, dip, 0, sip, (uint16_t)port,
- IpProtocol::TCP, app_id,
+ pf = AppIdSession::create_future_session(pkt, dip, 0, sip, (uint16_t)port, IpProtocol::TCP, app_id,
APPID_EARLY_SESSION_FLAG_FW_RULE);
if (pf)
{
rexec_service_mod.api->data_add(pf, tmp_rd,
rexec_service_mod.flow_data_index, &rexec_free_state);
- if (rexec_service_mod.api->data_add_id(pf, (uint16_t)port, &svc_element))
+ if (pf->add_flow_data_id((uint16_t)port, &svc_element))
{
pf->rnaServiceState = RNA_STATE_FINISHED;
tmp_rd->state = REXEC_STATE_DONE;
if (rd->parent && rd->parent->state == REXEC_STATE_SERVER_CONNECT)
{
rd->parent->state = REXEC_STATE_USERNAME;
- clearAppIdFlag(flowp, APPID_SESSION_REXEC_STDERR);
+ flowp->clearAppIdFlag(APPID_SESSION_REXEC_STDERR);
}
goto bail;
default:
}
inprocess:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
rexec_service_mod.api->service_inprocess(flowp, pkt, dir, &svc_element);
}
return SERVICE_INPROCESS;
success:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
rexec_service_mod.api->add_service(flowp, pkt, dir, &svc_element,
APP_ID_EXEC, nullptr, nullptr, nullptr);
return SERVICE_SUCCESS;
bail:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
rexec_service_mod.api->incompatible_data(flowp, pkt, dir, &svc_element,
rexec_service_mod.flow_data_index,
args->pConfig);
}
- clearAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->clearAppIdFlag(APPID_SESSION_CONTINUE);
return SERVICE_NOT_COMPATIBLE;
fail:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
rexec_service_mod.api->fail_service(flowp, pkt, dir, &svc_element,
rexec_service_mod.flow_data_index,
args->pConfig);
}
- clearAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->clearAppIdFlag(APPID_SESSION_CONTINUE);
return SERVICE_NOMATCH;
}
unsigned i;
char* v;
const unsigned char* p;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
uint16_t size = args->size;
static int rlogin_validate(ServiceValidationArgs* args)
{
ServiceRLOGINData* rd;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
Packet* pkt = args->pkt;
const uint8_t* data = args->data;
uint16_t size = args->size;
}
static int validate_packet(const uint8_t* data, uint16_t size, int dir,
- AppIdData* flowp, Packet* pkt, ServiceRPCData* rd,
+ AppIdSession* flowp, Packet* pkt, ServiceRPCData* rd,
const char** pname, uint32_t* program)
{
const ServiceRPCCall* call;
uint32_t tmp;
uint32_t val;
const uint8_t* end;
- AppIdData* pf;
+ AppIdSession* pf;
const RPCProgram* rprog;
if (!size)
end = data + size;
- if (flowp->proto == IpProtocol::UDP)
+ if (flowp->protocol == IpProtocol::UDP)
{
if (!rd->once)
{
rpc = (ServiceRPC*)data;
if (ntohl(rpc->type) == RPC_TYPE_REPLY)
{
- setAppIdFlag(flowp, APPID_SESSION_UDP_REVERSED);
+ flowp->setAppIdFlag(APPID_SESSION_UDP_REVERSED);
rd->state = RPC_STATE_REPLY;
dir = APP_ID_FROM_RESPONDER;
}
}
- else if (getAppIdFlag(flowp, APPID_SESSION_UDP_REVERSED))
+ else if (flowp->getAppIdFlag(APPID_SESSION_UDP_REVERSED))
{
dir = (dir == APP_ID_FROM_RESPONDER) ? APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
}
dip = pkt->ptrs.ip_api.get_dst();
sip = pkt->ptrs.ip_api.get_src();
tmp = ntohl(pmr->port);
- pf = rpc_service_mod.api->flow_new(flowp, pkt, dip, 0, sip, (uint16_t)tmp,
+ pf = AppIdSession::create_future_session(pkt, dip, 0, sip, (uint16_t)tmp,
// FIXIT-H: Change rd->proto to be IpProtocol
(IpProtocol)ntohl(rd->proto), app_id, 0);
if (pf)
{
- rpc_service_mod.api->data_add_id(pf, (uint16_t)tmp,
- flowp->proto==IpProtocol::TCP ? &tcp_svc_element : &svc_element);
+ pf->add_flow_data_id((uint16_t)tmp,
+ flowp->protocol == IpProtocol::TCP ? &tcp_svc_element : &svc_element);
pf->rnaServiceState = RNA_STATE_STATEFUL;
- setAppIdFlag(pf,
- getAppIdFlag(flowp,
- APPID_SESSION_RESPONDER_MONITORED |
+ pf->setAppIdFlag(flowp->getAppIdFlag(APPID_SESSION_RESPONDER_MONITORED |
APPID_SESSION_INITIATOR_MONITORED |
APPID_SESSION_SPECIAL_MONITORED |
APPID_SESSION_RESPONDER_CHECKED |
uint32_t program = 0;
const char* pname = nullptr;
int rval;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
Packet* pkt = args->pkt;
const int dir = args->dir;
switch (rval)
{
case SERVICE_INPROCESS:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
rpc_service_mod.api->service_inprocess(flowp, pkt, dir, &svc_element);
}
return SERVICE_INPROCESS;
case SERVICE_SUCCESS:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
if (pname && *pname)
{
rpc_service_mod.api->add_service(flowp, pkt, dir, &svc_element,
APP_ID_SUN_RPC, nullptr, nullptr, subtype);
}
- setAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->setAppIdFlag(APPID_SESSION_CONTINUE);
return SERVICE_SUCCESS;
case SERVICE_NOT_COMPATIBLE:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
rpc_service_mod.api->incompatible_data(flowp, pkt, dir, &svc_element,
rpc_service_mod.flow_data_index,
args->pConfig);
}
- clearAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->clearAppIdFlag(APPID_SESSION_CONTINUE);
return SERVICE_NOT_COMPATIBLE;
case SERVICE_NOMATCH:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
rpc_service_mod.api->fail_service(flowp, pkt, dir, &svc_element,
rpc_service_mod.flow_data_index,
args->pConfig);
}
- clearAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->clearAppIdFlag(APPID_SESSION_CONTINUE);
return SERVICE_NOMATCH;
default:
return rval;
uint32_t program = 0;
const char* pname = nullptr;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
Packet* pkt = args->pkt;
const int dir = args->dir;
goto fail;
else
{
- clearAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->clearAppIdFlag(APPID_SESSION_CONTINUE);
goto done;
}
}
{
case SERVICE_INPROCESS:
inprocess:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
rpc_service_mod.api->service_inprocess(flowp, pkt, dir, &tcp_svc_element);
}
return SERVICE_INPROCESS;
case SERVICE_SUCCESS:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
if (pname && *pname)
{
rpc_service_mod.api->add_service(flowp, pkt, dir, &tcp_svc_element,
APP_ID_SUN_RPC, nullptr, nullptr, subtype);
}
- setAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->setAppIdFlag(APPID_SESSION_CONTINUE);
return SERVICE_SUCCESS;
case SERVICE_NOT_COMPATIBLE:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
rpc_service_mod.api->incompatible_data(flowp, pkt, dir, &tcp_svc_element,
rpc_service_mod.flow_data_index,
args->pConfig);
}
- clearAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->clearAppIdFlag(APPID_SESSION_CONTINUE);
return SERVICE_NOT_COMPATIBLE;
case SERVICE_NOMATCH:
fail:
- if (!getAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED))
+ if (!flowp->getAppIdFlag(APPID_SESSION_SERVICE_DETECTED))
{
rpc_service_mod.api->fail_service(flowp, pkt, dir, &tcp_svc_element,
rpc_service_mod.flow_data_index,
args->pConfig);
}
- clearAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->clearAppIdFlag(APPID_SESSION_CONTINUE);
return SERVICE_NOMATCH;
default:
return retval;
}
bail:
- clearAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->clearAppIdFlag(APPID_SESSION_CONTINUE);
rd->tcpstate[APP_ID_FROM_INITIATOR] = RPC_TCP_STATE_DONE;
rd->tcpstate[APP_ID_FROM_RESPONDER] = RPC_TCP_STATE_DONE;
if (dir == APP_ID_FROM_INITIATOR)
ServiceRSHELLData* tmp_rd;
int i;
uint32_t port;
- AppIdData* pf;
- AppIdData* flowp = args->flowp;
+ AppIdSession* pf;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
Packet* pkt = args->pkt;
const int dir = args->dir;
dip = pkt->ptrs.ip_api.get_dst();
sip = pkt->ptrs.ip_api.get_src();
// FIXIT-M can flow_new return null?
- pf = rshell_service_mod.api->flow_new(flowp, pkt, dip, 0, sip, (uint16_t)port,
- IpProtocol::TCP, app_id, APPID_EARLY_SESSION_FLAG_FW_RULE);
+ pf = AppIdSession::create_future_session(pkt, dip, 0, sip, (uint16_t)port, IpProtocol::TCP, app_id,
+ APPID_EARLY_SESSION_FLAG_FW_RULE);
if (pf)
{
- pf->rnaClientState = RNA_STATE_FINISHED;
+ pf->rna_client_state = RNA_STATE_FINISHED;
rshell_service_mod.api->data_add(pf, tmp_rd,
rshell_service_mod.flow_data_index, &rshell_free_state);
- if (rshell_service_mod.api->data_add_id(pf, (uint16_t)port, &svc_element))
+ if (pf->add_flow_data_id((uint16_t)port, &svc_element))
{
pf->rnaServiceState = RNA_STATE_FINISHED;
tmp_rd->state = RSHELL_STATE_DONE;
case RSHELL_STATE_STDERR_CONNECT_SYN_ACK:
if (rd->parent && rd->parent->state == RSHELL_STATE_SERVER_CONNECT)
rd->parent->state = RSHELL_STATE_USERNAME;
- setAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED);
+ flowp->setAppIdFlag(APPID_SESSION_SERVICE_DETECTED);
return SERVICE_SUCCESS;
default:
goto bail;
if (!args)
return SERVICE_NOMATCH;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
uint16_t size = args->size;
static int rtmp_validate(ServiceValidationArgs* args)
{
ServiceRTMPData* ss;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
const int dir = args->dir;
uint16_t size = args->size;
static int smtp_validate(ServiceValidationArgs* args)
{
ServiceSMTPData* fd;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
uint16_t size = args->size;
uint16_t offset;
}
else
{
- if (getAppIdFlag(flowp, APPID_SESSION_ENCRYPTED) && fd->state == SMTP_STATE_TRANSFER)
+ if (flowp->getAppIdFlag(APPID_SESSION_ENCRYPTED) && fd->state == SMTP_STATE_TRANSFER)
{
fd->state = SMTP_STATE_STARTTLS;
}
if (!fd->set_flags)
{
fd->set_flags = 1;
- setAppIdFlag(flowp, APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
+ flowp->setAppIdFlag(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
}
offset = 0;
if (fd->code == 220)
goto success;
/* STARTTLS failed. */
- clearAppIdFlag(flowp, APPID_SESSION_ENCRYPTED); // not encrypted after all
+ flowp->clearAppIdFlag(APPID_SESSION_ENCRYPTED); // not encrypted after all
fd->state = SMTP_STATE_HELO; // revert the state
break;
case SMTP_STATE_TRANSFER:
{
ServiceSNMPData* sd;
ServiceSNMPData* tmp_sd;
- AppIdData* pf;
+ AppIdSession* pf;
uint8_t pdu;
const sfip_t* sip;
const sfip_t* dip;
uint8_t version;
const char* version_str = nullptr;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
Packet* pkt = args->pkt;
const int dir = args->dir;
{
if (app_id_debug_session_flag)
LogMessage("AppIdDbg %s snmp payload verify failed\n", app_id_debug_session);
- if (getAppIdFlag(flowp, APPID_SESSION_UDP_REVERSED))
+ if (flowp->getAppIdFlag(APPID_SESSION_UDP_REVERSED))
{
if (dir == APP_ID_FROM_RESPONDER)
goto bail;
if (pdu != SNMP_PDU_GET_RESPONSE && dir == APP_ID_FROM_RESPONDER)
{
sd->state = SNMP_STATE_R_RESPONSE;
- setAppIdFlag(flowp, APPID_SESSION_UDP_REVERSED);
+ flowp->setAppIdFlag(APPID_SESSION_UDP_REVERSED);
break;
}
if (pdu == SNMP_PDU_GET_RESPONSE && dir == APP_ID_FROM_INITIATOR)
{
sd->state = SNMP_STATE_R_REQUEST;
- setAppIdFlag(flowp, APPID_SESSION_UDP_REVERSED);
+ flowp->setAppIdFlag(APPID_SESSION_UDP_REVERSED);
break;
}
if (pdu == SNMP_PDU_TRAP || pdu == SNMP_PDU_TRAPV2)
{
- setAppIdFlag(flowp, APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_NOT_A_SERVICE);
- clearAppIdFlag(flowp, APPID_SESSION_CONTINUE);
+ flowp->setAppIdFlag(APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_NOT_A_SERVICE);
+ flowp->clearAppIdFlag(APPID_SESSION_CONTINUE);
flowp->serviceAppId = APP_ID_SNMP;
break;
}
/*adding expected connection in case the server doesn't send from 161*/
dip = pkt->ptrs.ip_api.get_dst();
sip = pkt->ptrs.ip_api.get_src();
- pf = snmp_service_mod.api->flow_new(flowp, pkt, dip, 0, sip, pkt->ptrs.sp, flowp->proto,
- app_id, 0);
+ pf = AppIdSession::create_future_session(pkt, dip, 0, sip, pkt->ptrs.sp, flowp->protocol, app_id, 0);
if (pf)
{
tmp_sd = (ServiceSNMPData*)snort_calloc(sizeof(ServiceSNMPData));
tmp_sd->state = SNMP_STATE_RESPONSE;
snmp_service_mod.api->data_add(pf, tmp_sd,
snmp_service_mod.flow_data_index, &snort_free);
- if (snmp_service_mod.api->data_add_id(pf, pkt->ptrs.dp, &svc_element))
+ if (pf->add_flow_data_id(pkt->ptrs.dp, &svc_element))
{
- setAppIdFlag(pf, APPID_SESSION_SERVICE_DETECTED);
- clearAppIdFlag(pf, APPID_SESSION_CONTINUE);
+ pf->setAppIdFlag(APPID_SESSION_SERVICE_DETECTED);
+ pf->clearAppIdFlag(APPID_SESSION_CONTINUE);
tmp_sd->state = SNMP_STATE_ERROR;
return SERVICE_ENULL;
}
const char* end;
unsigned len;
int client_major;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
uint16_t size = args->size;
#include <netinet/in.h>
#include <openssl/x509.h>
-#include "appid_flow_data.h"
+#include "appid_session.h"
#include "service_config.h"
#include "service_base.h"
#include "service_ssl.h"
"ssl",
};
-// FIXIT thread safety, can this be const?
-static RNAServiceValidationPort pp[] =
+static const RNAServiceValidationPort pp[] =
{
{ &ssl_validate, 261, IpProtocol::TCP, 0 },
{ &ssl_validate, 261, IpProtocol::UDP, 0 },
{ nullptr, 0, IpProtocol::PROTO_NOT_SET, 0 }
};
-// FIXIT thread safety, can this be const?
RNAServiceValidationModule ssl_service_mod =
{
"ssl",
const ServiceSSLV3Record* rec;
const ServiceSSLV3CertsRecord* certs_rec;
uint16_t ver;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
const int dir = args->dir;
uint16_t size = args->size;
goto fail;
}
}
- setAppIdFlag(flowp, APPID_SESSION_SSL_SESSION);
+ flowp->setAppIdFlag(APPID_SESSION_SSL_SESSION);
if (ss->host_name || ss->common_name || ss->org_name)
{
if (!flowp->tsession)
ssl_patterns_free(&pSslConfig->DetectorSSLCnamePatternList);
}
-int setSSLSquelch(Packet* p, int type, AppId appId)
+bool setSSLSquelch(Packet* p, int type, AppId appId)
{
const sfip_t* sip;
const sfip_t* dip;
- AppIdData* f;
+ AppIdSession* f;
if (!appInfoEntryFlagGet(appId, APPINFO_FLAG_SSL_SQUELCH, pAppidActiveConfig))
- return 0;
+ return false;
dip = p->ptrs.ip_api.get_dst();
sip = p->ptrs.ip_api.get_src();
- if (!(f = AppIdEarlySessionCreate(nullptr, p, sip, 0, dip, p->ptrs.dp,
- IpProtocol::TCP, appId, 0)))
- return 0;
+ if (!(f = AppIdSession::create_future_session(p, sip, 0, dip, p->ptrs.dp, IpProtocol::TCP,
+ appId, 0)))
+ return false;
switch (type)
{
case 1:
- f->payloadAppId = appId;
+ f->payload_app_id = appId;
break;
case 2:
- f->ClientAppId = appId;
- f->rnaClientState = RNA_STATE_FINISHED;
+ f->client_app_id = appId;
+ f->rna_client_state = RNA_STATE_FINISHED;
break;
default:
- return 0;
+ return false;
}
- return 1;
+ return true;
}
extern struct RNAServiceValidationModule ssl_service_mod;
AppId getSslServiceAppId(short srcPort);
-bool isSslServiceAppId(AppId appId);
+bool isSslServiceAppId(AppId);
void service_ssl_clean(ServiceSslConfig*);
int ssl_detector_process_patterns(ServiceSslConfig*);
int ssl_scan_hostname(const u_int8_t*, size_t, AppId*, AppId*, ServiceSslConfig*);
int ssl_add_cert_pattern(uint8_t*, size_t, uint8_t, AppId, ServiceSslConfig*);
int ssl_add_cname_pattern(uint8_t*, size_t, uint8_t, AppId, ServiceSslConfig*);
void ssl_detector_free_patterns(ServiceSslConfig*);
-int setSSLSquelch(Packet* p, int type, AppId appId);
+bool setSSLSquelch(Packet*, int type, AppId);
#endif
#include "main/snort_debug.h"
#include "utils/util.h"
-#include "appid_flow_data.h"
+#include "appid_session.h"
#include "application_ids.h"
#include "service_api.h"
#include "appid_module.h"
{
ServiceTelnetData* td;
const uint8_t* end;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
uint16_t size = args->size;
#include "app_info_table.h"
#include "appid_api.h"
-#include "appid_flow_data.h"
+#include "appid_session.h"
#include "application_ids.h"
#include "service_api.h"
#include "service_base.h"
int mode;
uint16_t block = 0;
uint16_t tmp;
- AppIdData* pf;
+ AppIdSession* pf;
const sfip_t* sip;
const sfip_t* dip;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
Packet* pkt = args->pkt;
const int dir = args->dir;
tmp_td->state = TFTP_STATE_TRANSFER;
dip = pkt->ptrs.ip_api.get_dst();
sip = pkt->ptrs.ip_api.get_src();
- pf = tftp_service_mod.api->flow_new(flowp, pkt, dip, 0, sip, pkt->ptrs.sp, flowp->proto,
- app_id, APPID_EARLY_SESSION_FLAG_FW_RULE);
+ pf = AppIdSession::create_future_session(pkt, dip, 0, sip, pkt->ptrs.sp, flowp->protocol, app_id,
+ APPID_EARLY_SESSION_FLAG_FW_RULE);
if (pf)
{
tftp_service_mod.api->data_add(pf, tmp_td,
tftp_service_mod.flow_data_index, &snort_free);
- if (tftp_service_mod.api->data_add_id(pf, pkt->ptrs.dp, &svc_element))
+ if (pf->add_flow_data_id(pkt->ptrs.dp, &svc_element))
{
- setAppIdFlag(pf, APPID_SESSION_SERVICE_DETECTED);
- clearAppIdFlag(pf, APPID_SESSION_CONTINUE);
+ pf->setAppIdFlag(APPID_SESSION_SERVICE_DETECTED);
+ pf->clearAppIdFlag(APPID_SESSION_CONTINUE);
tmp_td->state = TFTP_STATE_ERROR;
return SERVICE_ENOMEM;
}
// service_timbuktu.cc author Sourcefire Inc.
#include "appid_module.h"
-#include "appid_flow_data.h"
+#include "appid_session.h"
#include "application_ids.h"
#include "service_api.h"
static int timbuktu_validate(ServiceValidationArgs* args)
{
ServiceTIMBUKTUData* ss;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
uint16_t size = args->size;
uint16_t offset=0;
// service_tns.cc author Sourcefire Inc.
#include "app_info_table.h"
-#include "appid_flow_data.h"
+#include "appid_session.h"
#include "application_ids.h"
#include "service_api.h"
{
ServiceTNSData* ss;
uint16_t offset;
- AppIdData* flowp = args->flowp;
+ AppIdSession* flowp = args->flowp;
const uint8_t* data = args->data;
uint16_t size = args->size;
extern int rsync_validate(ServiceValidationArgs*);
-int fake_service_inprocess(AppIdData*, const Packet*, int, const RNAServiceElement*)
+int fake_service_inprocess(AppIdSession*, const Packet*, int, const RNAServiceElement*)
{
mock().actualCall("service_inprocess");
return -1;
ServiceRSYNCData* fake_rsync_data = NULL;
-void* fake_service_flowdata_get(AppIdData*, unsigned)
+void* fake_service_flowdata_get(AppIdSession*, unsigned)
{
mock().actualCall("data_get");
return fake_rsync_data;
}
-int fake_data_add(AppIdData*, void* data, unsigned, AppIdFreeFCN)
+int fake_data_add(AppIdSession*, void* data, unsigned, AppIdFreeFCN)
{
mock().actualCall("data_add");
fake_rsync_data = (ServiceRSYNCData*)data;
return -1;
}
-int fake_fail_service(AppIdData*, const Packet*, int, const RNAServiceElement*, unsigned, const AppIdConfig*)
+int fake_fail_service(AppIdSession*, const Packet*, int, const RNAServiceElement*, unsigned, const AppIdConfig*)
{
mock().actualCall("fail_service");
return -1;
}
-int fake_add_service(AppIdData*, const Packet*, int,
+int fake_add_service(AppIdSession*, const Packet*, int,
const RNAServiceElement*, AppId, const char*, const char *,
const RNAServiceSubtype*)
{
nullptr,
nullptr,
nullptr,
- nullptr,
- nullptr,
&fake_add_service,
&fake_fail_service,
&fake_service_inprocess,
#if 0
#include <stdio.h>
-#include "util/fw_avltree.h"
+#include "appid_utils/fw_avltree.h"
#include "protocols/protocol_ids.h"
#include "sfip/sfip_t.h"
#include "sfip/sf_ip.h"
extern void AppIdReconfigureFree(uint16_t type, void* old_context, struct _THREAD_ELEMENT* te,
ControlDataSendFunc f);
-extern int processHTTPPacket(Packet* p, AppIdData* session, int direction,
+extern int processHTTPPacket(Packet* p, AppIdSession* session, int direction,
HttpParsedHeaders* const headers, const AppIdConfig* pConfig);
extern void appIdApiInit(struct AppIdApi*);
extern void sfiph_build(Packet* p, const void* hdr, int family);
-extern void pickHttpXffAddress(Packet* p, AppIdData* appIdSession,
+extern void pickHttpXffAddress(Packet* p, AppIdSession* appIdSession,
ThirdPartyAppIDAttributeData* attribute_data);
AppIdApi appIdApi;
// FIXIT: use APIs instead of using global
-extern AppIdData* pAppIdData;
+extern AppIdSession* pAppIdData;
static char* testFilesPath = nullptr;
static char rnaConfPath[PATH_MAX] = { 0 };
{
// FIXIT-M J these need to be cleared, probably
Packet p;
- AppIdData session;
+ AppIdSession session;
char buf[1024];
int bufLen;
"4faa8b240a5fef0aa5147448c8005347; ugs=1; tnr:usrvtstg01=1336576805411%7C0%7C0%7C1%7C0%7C0%7C0%7C0%7C0%7C0%7C0%7C0%7C0%7C0%7C0%7C0%7C0%7C0%7C0%7C0%7C0%7C0%7C0%7C0%7C0%7C0%7C0%7C0%7C0%7C0%7C0%7C1%7Cf%7C"
"1%7C4%7C1336576805411; tnr:sesctmp01=1336576805411; s_cc=true; s_sq=%5B%5BB%5D%5D; adDEmas=R08&broadband&gblx.net&73&gbr&826027&0&10198&-&-&-&15275&; adDEon=true; s_ppv=13");
session.serviceAppId = APP_ID_NONE;
- session.payloadAppId = APP_ID_NONE;
- session.tpPayloadAppId = 1190;
+ session.payload_app_id = APP_ID_NONE;
+ session.tp_payload_app_id = 1190;
session.scan_flags = 0x26;
- session.ClientAppId = 0;
+ session.client_app_id = 0;
strcpy(buf, "GET / HTTP/1.1\r\n");
strcat(buf, "Host: ");
if (httpHeader)
{
- httpHeaderCallback(&pkt, httpHeader);
+ //httpHeaderCallback(&pkt, httpHeader);
}
else
{
- fwAppIdSearch(&pkt);
+ do_application_discovery(&pkt);
}
if (pkt.data)
LogMessage("App name = %s\n", appGeAppName(appIdApi.geServiceAppId(pAppIdData)));
LogMessage("AppId = %d\n", appGeAppId(appGeAppName(appIdApi.geServiceAppId(pAppIdData))));
LogMessage("Service AppId = %d\n", appIdApi.geServiceAppId(pAppIdData));
- LogMessage("Only Service AppId = %d\n", appIdApi.getOnlyServiceAppId(pAppIdData));
- LogMessage("Misc AppId = %d\n", appIdApi.getMiscAppId(pAppIdData));
- LogMessage("Client AppId = %d\n", appIdApi.getClientAppId(pAppIdData));
- LogMessage("Payload AppId = %d\n", appIdApi.getPayloadAppId(pAppIdData));
- LogMessage("Referred AppId = %d\n", appIdApi.getReferredAppId(pAppIdData));
- LogMessage("Fw Service AppId = %d\n", appIdApi.getFwServiceAppId(pAppIdData));
- LogMessage("Fw Misc AppId = %d\n", appIdApi.getFwMiscAppId(pAppIdData));
- LogMessage("Fw Client AppId = %d\n", appIdApi.getFwClientAppId(pAppIdData));
- LogMessage("Fw Payload AppId = %d\n", appIdApi.getFwPayloadAppId(pAppIdData));
- LogMessage("Fw Referred AppId = %d\n", appIdApi.getFwReferredAppId(pAppIdData));
- LogMessage("Is Session SSL Decrypted = %d\n", appIdApi.isSessionSslDecrypted(pAppIdData));
- LogMessage("Is AppId Inspecting Session = %d\n", appIdApi.isAppIdInspectingSession(
+ LogMessage("Only Service AppId = %d\n", appIdApi.get_only_service_app_id(pAppIdData));
+ LogMessage("Misc AppId = %d\n", appIdApi.get_misc_app_id(pAppIdData));
+ LogMessage("Client AppId = %d\n", appIdApi.get_client_app_id(pAppIdData));
+ LogMessage("Payload AppId = %d\n", appIdApi.get_payload_app_id(pAppIdData));
+ LogMessage("Referred AppId = %d\n", appIdApi.get_referred_app_id(pAppIdData));
+ LogMessage("Fw Service AppId = %d\n", appIdApi.get_fw_service_app_id(pAppIdData));
+ LogMessage("Fw Misc AppId = %d\n", appIdApi.get_fw_misc_app_id(pAppIdData));
+ LogMessage("Fw Client AppId = %d\n", appIdApi.get_fw_client_app_id(pAppIdData));
+ LogMessage("Fw Payload AppId = %d\n", appIdApi.get_fw_payload_app_id(pAppIdData));
+ LogMessage("Fw Referred AppId = %d\n", appIdApi.get_fw_feferred_app_id(pAppIdData));
+ LogMessage("Is Session SSL Decrypted = %d\n", appIdApi.is_ssl_session_decrypted(pAppIdData));
+ LogMessage("Is AppId Inspecting Session = %d\n", appIdApi.is_appid_inspecting_session(
pAppIdData));
- LogMessage("Is AppId Available = %d\n", appIdApi.isAppIdAvailable(pAppIdData));
- userName = appIdApi.getUserName(pAppIdData, &service, &isLoginSuccessful);
+ LogMessage("Is AppId Available = %d\n", appIdApi.is_appid_available(pAppIdData));
+ userName = appIdApi.get_user_name(pAppIdData, &service, &isLoginSuccessful);
LogMessage("User name = %s, service = %d, isLoginSuccessful = %d\n",
userName, service, isLoginSuccessful);
LogMessage("Client version = %s\n", appIdApi.geClientVersion(pAppIdData));
// TODO: Is the flag argument correct?
- LogMessage("Session attribute = %" PRIx64 "\n", appIdApi.getAppIdSessionAttribute(pAppIdData,
+ LogMessage("Session attribute = %" PRIx64 "\n", appIdApi.get_appid_session_attribute(pAppIdData,
0));
- LogMessage("Flow type = %08X\n", appIdApi.getFlowType(pAppIdData));
+ LogMessage("Flow type = %08X\n", appIdApi.get_flow_type(pAppIdData));
appIdApi.geServiceInfo(pAppIdData, &serviceVendor, &serviceVersion, &serviceSubtype);
LogMessage("Service vendor = %s, version = %s\n",
serviceVendor, serviceVersion);
LogMessage("Service port = %d\n", appIdApi.geServicePort(pAppIdData));
LogMessage("Service IP = %s\n", inet_ntoa(appIdApi.geServiceIp(pAppIdData)));
- LogMessage("HTTP user agent = %s\n", appIdApi.getHttpUserAgent(pAppIdData));
+ LogMessage("HTTP user agent = %s\n", appIdApi.get_http_user_agent(pAppIdData));
LogMessage("HTTP host = %s\n", appIdApi.getHttpHost(pAppIdData));
- LogMessage("HTTP URL = %s\n", appIdApi.getHttpUrl(pAppIdData));
- LogMessage("HTTP referer = %s\n", appIdApi.getHttpReferer(pAppIdData));
+ LogMessage("HTTP URL = %s\n", appIdApi.get_http_url(pAppIdData));
+ LogMessage("HTTP referer = %s\n", appIdApi.get_http_referer(pAppIdData));
LogMessage("TLS host = %s\n", appIdApi.getTlsHost(pAppIdData));
- LogMessage("NetBIOS name = %s\n", appIdApi.getNetbiosName(pAppIdData));
+ LogMessage("NetBIOS name = %s\n", appIdApi.get_netbios_name(pAppIdData));
fclose(file);
}
END_TEST START_TEST(HttpXffTest)
{
Packet p = { 0 };
- AppIdData session = { 0 };
+ AppIdSession session = { 0 };
httpSession hsession = { 0 };
ThirdPartyAppIDAttributeData tpData = { 0 };
SFIP_RET status;
ck_assert_str_eq(appGeAppName(appIdApi.geServiceAppId(pAppIdData)), "AOL Instant Messenger");
ck_assert_uint_eq(appIdApi.geServiceAppId(pAppIdData), APP_ID_AOL_INSTANT_MESSENGER);
- ck_assert_uint_eq(appIdApi.getClientAppId(pAppIdData), APP_ID_AOL_INSTANT_MESSENGER);
+ ck_assert_uint_eq(appIdApi.get_client_app_id(pAppIdData), APP_ID_AOL_INSTANT_MESSENGER);
appSharedDataDelete(pAppIdData);
pAppIdData = nullptr;
ck_assert_str_eq(appGeAppName(appIdApi.geServiceAppId(pAppIdData)), "HTTP");
ck_assert_uint_eq(appIdApi.geServiceAppId(pAppIdData), APP_ID_HTTP);
- ck_assert_uint_eq(appIdApi.getClientAppId(pAppIdData), APP_ID_FIREFOX);
- ck_assert_uint_eq(appIdApi.getPayloadAppId(pAppIdData), 1190); // CNN app
+ ck_assert_uint_eq(appIdApi.get_client_app_id(pAppIdData), APP_ID_FIREFOX);
+ ck_assert_uint_eq(appIdApi.get_payload_app_id(pAppIdData), 1190); // CNN app
ck_assert_str_eq(appIdApi.getHttpHost(pAppIdData), "www.cnn.com");
appSharedDataDelete(pAppIdData);
ck_assert_str_eq(appGeAppName(appIdApi.geServiceAppId(pAppIdData)), "DNS");
ck_assert_uint_eq(appIdApi.geServiceAppId(pAppIdData), APP_ID_DNS);
- ck_assert_uint_eq(appIdApi.getClientAppId(pAppIdData), APP_ID_DNS);
+ ck_assert_uint_eq(appIdApi.get_client_app_id(pAppIdData), APP_ID_DNS);
ck_assert_uint_eq(appIdApi.geServicePort(pAppIdData), 53);
appSharedDataDelete(pAppIdData);
ck_assert_str_eq(appGeAppName(appIdApi.geServiceAppId(pAppIdData)), "3Com AMP3");
ck_assert_uint_eq(appIdApi.geServiceAppId(pAppIdData), 3000);
- ck_assert_uint_eq(appIdApi.getClientAppId(pAppIdData), 3000);
+ ck_assert_uint_eq(appIdApi.get_client_app_id(pAppIdData), 3000);
appSharedDataDelete(pAppIdData);
pAppIdData = nullptr;
ck_assert_str_eq(appGeAppName(appIdApi.geServiceAppId(pAppIdData)), "RFB");
ck_assert_uint_eq(appIdApi.geServiceAppId(pAppIdData), APP_ID_VNC_RFB);
- ck_assert_uint_eq(appIdApi.getClientAppId(pAppIdData), APP_ID_VNC);
+ ck_assert_uint_eq(appIdApi.get_client_app_id(pAppIdData), APP_ID_VNC);
ck_assert_uint_eq(appIdApi.geServicePort(pAppIdData), 5900);
appSharedDataDelete(pAppIdData);
ck_assert_str_eq(appGeAppName(appIdApi.geServiceAppId(pAppIdData)), "HTTP");
ck_assert_uint_eq(appIdApi.geServiceAppId(pAppIdData), APP_ID_HTTP);
- ck_assert_uint_eq(appIdApi.getClientAppId(pAppIdData), 2932); // WebEx
- ck_assert_uint_eq(appIdApi.getPayloadAppId(pAppIdData), 2932); // WebEx
+ ck_assert_uint_eq(appIdApi.get_client_app_id(pAppIdData), 2932); // WebEx
+ ck_assert_uint_eq(appIdApi.get_payload_app_id(pAppIdData), 2932); // WebEx
appSharedDataDelete(pAppIdData);
pAppIdData = nullptr;
static void appIdTestSetup(void)
{
- static SessionAPI sessionAPI = { 0 };
- static StreamAPI streamAPI = { 0 };
-
testFilesPath = getenv("APPID_TESTS_PATH");
if (testFilesPath == nullptr)
strcpy(rnaConfPath, testFilesPath);
strcat(rnaConfPath, "/rna.conf");
-
- _dpd.tokenSplit = mSplit;
- _dpd.tokenFree = mSplitFree;
- LogMessage = logMsg;
- _dpd.errMsg = errMsg;
- _dpd.debugMsg = debugMsg;
- _dpd.addProtocolReference = addProtocolReference;
- _dpd.addPreproc = addPreproc;
- _dpd.getParserPolicy = getParserPolicy;
- _dpd.getDefaultPolicy = getDefaultPolicy;
- _dpd.isAppIdRequired = isAppIdRequired;
- _dpd.getSnortInstance = getSnortInstance;
- _dpd.findProtocolReference = findProtocolReference;
-
- sessionAPI.enable_preproc_all_ports = enable_preproc_all_ports;
- sessionAPI.get_application_data = get_application_data;
- sessionAPI.set_application_data = set_application_data;
- sessionAPI.get_packet_direction = get_packet_direction;
- sessionAPI.get_session_flags = get_session_flags;
- sessionAPI.get_session_ip_address = get_session_ip_address;
- sessionAPI.get_application_protocol_id = get_application_protocol_id;
- sessionAPI.get_http_xff_precedence = get_http_xff_precedence;
- _dpd.sessionAPI = &sessionAPI;
-
- streamAPI.is_session_decrypted = is_session_decrypted;
- streamAPI.set_application_id = set_application_id;
- streamAPI.is_session_http2 = is_session_http2;
- _dpd.streamAPI = &streamAPI;
-
- _dpd.searchAPI = &searchAPI;
}
static void sessionTcaseSetup(void)
//#include <stdarg.h>
#include "external_apis.h"
#include "session_file.h"
-#include "appid_flow_data.h"
+#include "appid_session.h"
#include "protocols/packet.h"
#include "protocols/tcp.h"
#include "protocols/udp.h"
-AppIdData* pAppIdData = nullptr;
+AppIdSession* pAppIdData = nullptr;
/***********************************************************
* Local functions
return pAppIdData;
}
-int set_application_data(void*, uint32_t, AppIdData* data, StreamAppDataFree)
+int set_application_data(void*, uint32_t, AppIdSession* data, StreamAppDataFree)
{
pAppIdData = data;
return nullptr;
}
-bool is_session_decrypted(void*)
-{
- return true;
-}
-
void set_application_id(void*, int16_t, int16_t, int16_t, int16_t)
{
}
char** get_http_xff_precedence(void* ssn, uint32_t flags, int* nFields);
// Stream APIs
-bool is_session_decrypted(void* stream_session);
void set_application_id(
void* ssnptr, int16_t serviceAppid, int16_t ClientAppid,
int16_t payloadAppId, int16_t miscAppid);
#include "sf_types.h"
#include "util.h"
-#ifdef DYNAMIC_PREPROC_CONTEXT
-#include "sf_dynamic_preprocessor.h"
-#endif //DYNAMIC_PREPROC_CONTEXT
-
#ifdef INTEL_SOFT_CPM
#include "intel-soft-cpm.h"
#endif
#include "profiler.h"
-#ifndef DYNAMIC_PREPROC_CONTEXT
+
#include "snort.h"
-#endif
-#ifdef PERF_PROFILING
-PreprocStats mpsePerfStats;
-#endif
static uint64_t s_bcnt=0;
return (void*)p;
}
-#ifndef DYNAMIC_PREPROC_CONTEXT
void* mpseNewWithSnortConfig(struct _SnortConfig* sc,
int method, int use_global_counter_flag,
void (* userfree)(void* p),
return (void*)p;
}
-#endif //DYNAMIC_PREPROC_CONTEXT
-
void mpseVerbose(void* pvoid)
{
MPSE* p = (MPSE*)pvoid;
}
}
-#ifndef DYNAMIC_PREPROC_CONTEXT
int mpseAddPatternWithSnortConfig(SnortConfig* sc, void* pvoid, void* P, int m,
unsigned noCase, unsigned offset, unsigned depth,
unsigned negative, void* ID, int IID)
}
}
-#endif // DYNAMIC_PREPROC_CONTEXT
-
void mpseLargeShifts(void* pvoid, int flag)
{
MPSE* p = (MPSE*)pvoid;
return retv;
}
-#ifndef DYNAMIC_PREPROC_CONTEXT
int mpsePrepPatternsWithSnortConf(struct _SnortConfig* sc, void* pvoid,
int ( * build_tree )(struct _SnortConfig*, void* id, void** existing_tree),
int ( * neg_list_func )(void* id, void** list) )
return retv;
}
-#endif //DYNAMIC_PREPROC_CONTEXT
-
void mpseSetRuleMask(void* pvoid, BITOP* rm)
{
MPSE* p = (MPSE*)pvoid;
return 0;
}
-#ifndef DYNAMIC_PREPROC_CONTEXT
int mpsePrintSummaryWithSnortConfig(SnortConfig* sc, int method)
{
switch (method)
return 0;
}
-#endif //DYNAMIC_PREPROC_CONTEXT
-
void mpseInitSummary(void)
{
acsm_init_summary();
static void appIdTestSetup()
{
#ifdef REMOVED_WHILE_NOT_IN_USE
- static SessionAPI sessionAPI = { 0 };
- static StreamAPI streamAPI = { 0 };
testFilesPath = getenv("APPID_TESTS_PATH");
strcpy(rnaConfPath, testFilesPath);
strcat(rnaConfPath, "/rna.conf");
- _dpd.tokenSplit = mSplit;
- _dpd.tokenFree = mSplitFree;
- LogMessage = logMsg;
- _dpd.errMsg = errMsg;
- _dpd.debugMsg = debugMsg;
- _dpd.addProtocolReference = addProtocolReference;
- _dpd.addPreproc = addPreproc;
- _dpd.getParserPolicy = getParserPolicy;
- _dpd.getDefaultPolicy = getDefaultPolicy;
- _dpd.isAppIdRequired = isAppIdRequired;
- _dpd.getSnortInstance = getSnortInstance;
- _dpd.findProtocolReference = findProtocolReference;
-
- sessionAPI.enable_preproc_all_ports = enable_preproc_all_ports;
- sessionAPI.get_application_data = get_application_data;
- sessionAPI.set_application_data = set_application_data;
- sessionAPI.get_packet_direction = get_packet_direction;
- sessionAPI.get_session_flags = get_session_flags;
- sessionAPI.get_session_ip_address = get_session_ip_address;
- sessionAPI.get_application_protocol_id = get_application_protocol_id;
- sessionAPI.get_http_xff_precedence = get_http_xff_precedence;
- _dpd.sessionAPI = &sessionAPI;
-
- streamAPI.is_session_decrypted = is_session_decrypted;
- streamAPI.set_application_id = set_application_id;
- streamAPI.is_session_http2 = is_session_http2;
- _dpd.streamAPI = &streamAPI;
-
- _dpd.searchAPI = &searchAPI;
#endif
}
char fileName[16];
};
-#ifdef MPLS
struct MPLS_Hdr
{
uint16_t length;
uint8_t* start;
};
-#endif
// FIXIT-M: Temporary structs and defines for initial appid port.
using tSfPolicyId = int;
uint8_t protocol;
-#ifdef ACTIVE_RESPONSE
- uint8_t response_count;
-#endif
-
uint8_t inner_client_ttl;
uint8_t inner_server_ttl;
uint8_t outer_client_ttl;
StreamHAState ha_state;
StreamHAState cached_ha_state;
-#ifdef ENABLE_HA
struct timeval ha_next_update;
uint8_t ha_pending_mask;
uint8_t ha_flags;
-#endif
bool session_established;
bool new_session;
int16_t app_protocol_id[MAX_APP_PROTOCOL_ID];
-#ifdef MPLS
MPLS_Hdr* clientMplsHeader;
MPLS_Hdr* serverMplsHeader;
-#endif
};
void sessionFileInit();
THREAD_LOCAL struct ThirdPartyConfig thirdpartyConfig;
THREAD_LOCAL ThirdPartyAppIDModule* thirdparty_appid_module = nullptr;
-// FIXIT - these need to be define or otherwise obtained...
+// FIXIT-L: these need to be define or otherwise obtained...
static char* defaultXffFields[] = { nullptr /* HTTP_XFF_FIELD_X_FORWARDED_FOR, */
/* HTTP_XFF_FIELD_TRUE_CLIENT_IP */ };
|| ( thirdparty_appid_dir[0] == 0 ) )
return;
- // FIXIT - need to port loadAllLibs function to snort3
+ // FIXIT-L: need to port loadAllLibs function to snort3
// _dpd.loadAllLibs(thirdparty_appid_dir, LoadCallback);
if (thirdparty_appid_module == nullptr)
{
thirdpartyConfig.http_upgrade_reporting_enabled = 0;
thirdpartyConfig.appid_tp_dir[0] = '\0'; // use default path
- // FIXIT - need to provide log function and getSnortInstance function to 3rd party utils
+ // FIXIT-L: need to provide log function and getSnortInstance function to 3rd party utils
#ifdef REMOVED_WHILE_NOT_IN_USE
thirdpartyUtils.logMsg = &DebugFormat;
thirdpartyUtils.getSnortInstance = _dpd.getSnortInstance;
- // FIXIT - need to get xff fields from http config
+ // FIXIT-L: need to get xff fields from http config
thirdpartyConfig.xffFields = _dpd.getHttpXffFields(&thirdpartyConfig.numXffFields);
#endif
thirdpartyConfig.oldNumXffFields = thirdpartyConfig.numXffFields;
thirdpartyConfig.oldXffFields = thirdpartyConfig.xffFields;
- // FIXIT - need to get xff fields from http config
+ // FIXIT-L: need to get xff fields from http config
// thirdpartyConfig.xffFields = _dpd.getHttpXffFields(&thirdpartyConfig.numXffFields);
if (!thirdpartyConfig.xffFields)
{
// Adds entry to the expected session cache with a flow key generated from the network
// n-tuple parameters specified. Inspection will be turned off for this expected session
// when it arrives.
- int ignore_session(
- const sfip_t *addr1, uint16_t p1, const sfip_t *addr2, uint16_t p2,
+ int ignore_session( const sfip_t *addr1, uint16_t p1, const sfip_t *addr2, uint16_t p2,
PktType, char dir, uint32_t ppId);
// Resume inspection for flow.