]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #683 in SNORT/snort3 from appid_sip to master
authorRuss Combs (rucombs) <rucombs@cisco.com>
Thu, 3 Nov 2016 15:52:54 +0000 (11:52 -0400)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Thu, 3 Nov 2016 15:52:54 +0000 (11:52 -0400)
Squashed commit of the following:

commit e3763a9177b370e6de5e00a315b22a40321048ec
Author: Carter Waxman <cwaxman@cisco.com>
Date:   Wed Nov 2 11:05:16 2016 -0400

    Updated build dependency fix

commit f9a3162c78f4472b29928f981d1c1cfc0d3ea4c6
Author: Carter Waxman <cwaxman@cisco.com>
Date:   Fri Oct 28 17:56:08 2016 -0400

    fixed expect cache session data insertion

commit e3c70ad588df032b1d0dc89bdcfc6090e88ffe58
Author: Carter Waxman <cwaxman@cisco.com>
Date:   Fri Oct 21 11:06:48 2016 -0400

    Encapsulated dialog

commit cc96d7f938375a78519543f4fc68d735f7cac9eb
Author: Carter Waxman <cwaxman@cisco.com>
Date:   Wed Oct 19 12:03:03 2016 -0400

    Encapsulated sipMsg

commit c79a09e1f82b3698c1808ecb51f84e648687c5d5
Author: Carter Waxman <cwaxman@cisco.com>
Date:   Fri Oct 14 14:58:13 2016 -0400

    Implemented SipEventHandler

15 files changed:
src/flow/expect_cache.cc
src/network_inspectors/appid/appid_inspector.cc
src/network_inspectors/appid/appid_module.cc
src/network_inspectors/appid/appid_module.h
src/network_inspectors/appid/detector_plugins/detector_sip.cc
src/network_inspectors/appid/detector_plugins/detector_sip.h
src/pub_sub/CMakeLists.txt
src/pub_sub/Makefile.am
src/pub_sub/sip_events.cc [new file with mode: 0644]
src/pub_sub/sip_events.h [new file with mode: 0644]
src/service_inspectors/service_inspectors.cc
src/service_inspectors/sip/CMakeLists.txt
src/service_inspectors/sip/Makefile.am
src/service_inspectors/sip/sip_common.h
src/service_inspectors/sip/sip_dialog.cc

index 30cd584b034f0e91236f850c56509f20d7dea948..04162d2420dad99ca09a43ca393ae6f8a0b485b4 100644 (file)
@@ -346,7 +346,7 @@ int ExpectCache::add_flow(const Packet *ctrlPkt,
                     last = nullptr;
                     break;
                 }
-                fd = fd->next;
+                lfd = lfd->next;
             }
         }
     }
index 8cab9c50d3ff55b1543dc777a5b873b504ff6622..fd7aaedcc359857aec60b3547b8c30ec134f5ae9 100644 (file)
@@ -44,6 +44,7 @@
 #include "detector_plugins/detector_sip.h"
 #include "detector_plugins/detector_pattern.h"
 #include "appid_http_event_handler.h"
+#include "pub_sub/sip_events.h"
 
 static void dump_appid_stats()
 {
@@ -79,6 +80,7 @@ bool AppIdInspector::configure(SnortConfig*)
 
     get_data_bus().subscribe(HTTP_REQUEST_HEADER_EVENT_KEY, new HttpEventHandler(HttpEventHandler::REQUEST_EVENT));
     get_data_bus().subscribe(HTTP_RESPONSE_HEADER_EVENT_KEY, new HttpEventHandler(HttpEventHandler::RESPONSE_EVENT));
+    get_data_bus().subscribe(SIP_EVENT_TYPE_SIP_DIALOG_KEY, new SipEventHandler());
 
     return active_config->init_appid();
 
@@ -86,11 +88,6 @@ bool AppIdInspector::configure(SnortConfig*)
 #ifdef REMOVED_WHILE_NOT_IN_USE
     _dpd.registerGeAppId(getOpenAppId);
     _dpd.registerSslAppIdLookup(sslAppGroupIdLookup);
-
-    // FIXIT-M AppID will need to register for SIP events for sip detection to work...
-    if (_dpd.streamAPI->service_event_subscribe(PP_SIP, SIP_EVENT_TYPE_SIP_DIALOG,
-        SipSessionSnortCallback) == false)
-        DynamicPreprocessorFatalMessage("failed to subscribe to SIP_DIALOG\n");
 #endif
 }
 
index a0e9640bb717279a00f733ec6bc33c0e51ac178f..3cb0055312e73420bd1d7f745a7701673cef6f7d 100644 (file)
@@ -84,6 +84,8 @@ const PegInfo appid_pegs[] =
     { "rsync_flows", "count of rsync service flows discovered by appid" },
     { "rtmp_flows", "count of rtmp flows discovered by appid" },
     { "rtp_clients", "count of rtp clients discovered by appid" },
+    { "sip_clients", "count of SIP clients discovered by appid" },
+    { "sip_flows", "count of SIP flows discovered by appid" },
     { "smtp_aol_clients", "count of AOL smtp clients discovered by appid" },
     { "smtp_applemail_clients", "count of Apple Mail smtp clients discovered by appid" },
     { "smtp_eudora_clients", "count of Eudora smtp clients discovered by appid" },
index 204e7b4909f9474a7c632a48d5ae94956aa3e7ac..55516f69d80b9f575dee6398a9c41d0ff28bea07 100644 (file)
@@ -76,6 +76,8 @@ struct AppIdStats
     PegCount rsync_flows;
     PegCount rtmp_flows;
     PegCount rtp_clients;
+    PegCount sip_clients;
+    PegCount sip_flows;
     PegCount smtp_aol_clients;
     PegCount smtp_applemail_clients;
     PegCount smtp_eudora_clients;
index 4fb0ff5fb68a278b2922783b8af1621cd2f580dc..2a048bec23d754d7f68071215f509c75cc9bac2c 100644 (file)
 
 #include "detector_sip.h"
 
-#include "http_url_patterns.h"
+#include "appid/appid_module.h"
+#include "appid_utils/sf_mlmp.h"
 #include "fw_appid.h"
+#include "http_url_patterns.h"
 #include "service_plugins/service_base.h"
-#include "appid_utils/sf_mlmp.h"
 #include "utils/util.h"
 
 #include "log/messages.h"
 #include "main/snort_debug.h"
-#include "service_inspectors/sip/sip_common.h"
+#include "pub_sub/sip_events.h"
+
+using namespace std;
 
 static const char SIP_REGISTER_BANNER[] = "REGISTER ";
 static const char SIP_INVITE_BANNER[] = "INVITE ";
@@ -62,7 +65,7 @@ static const unsigned MAX_VENDOR_SIZE = 64;
 
 enum SIPState
 {
-    SIP_STATE_INIT=0,
+    SIP_STATE_INIT = 0,
     SIP_STATE_REGISTER,
     SIP_STATE_CALL
 };
@@ -78,12 +81,12 @@ enum tSIP_FLAGS
 
 struct ClientSIPData
 {
-    void* owner;
-    SIPState state;
-    uint32_t flags;
-    char* userName;
-    char* clientUserAgent;
-    char* from;
+    void* owner = nullptr;
+    SIPState state = SIP_STATE_INIT;
+    uint32_t flags = 0;
+    const string* user_name = nullptr;
+    const string* client_user_agent = nullptr;
+    const string* from = nullptr;
 };
 
 struct DetectorSipConfig
@@ -105,7 +108,7 @@ static CLIENT_APP_RETCODE sip_tcp_client_init(const InitClientAppAPI* const init
     SF_LIST* config);
 static CLIENT_APP_RETCODE sip_tcp_client_validate(const uint8_t* data, uint16_t size,
     const int dir, AppIdSession* asd, Packet* pkt, Detector* userData);
-static int get_sip_client_app(void* patternMatcher, char* pattern, uint32_t patternLen,
+static int get_sip_client_app(void* patternMatcher, const char* pattern, uint32_t patternLen,
     AppId* ClientAppId, char** clientVersion);
 static void clean_sip_ua();
 static void clean_sip_server();
@@ -300,25 +303,18 @@ static CLIENT_APP_RETCODE sip_tcp_client_init(const InitClientAppAPI* const init
 }
 
 static void clientDataFree(void* data)
-{
-    ClientSIPData* fd = (ClientSIPData*)data;
-    snort_free(fd->from);
-    snort_free(fd->clientUserAgent);
-    snort_free(fd->userName);
-    free (fd);
-}
+{ delete (ClientSIPData*)data; }
 
 // static const char* const SIP_USRNAME_BEGIN_MARKER = "<sip:";
 static CLIENT_APP_RETCODE sip_client_validate(const uint8_t*, uint16_t, const int,
     AppIdSession* asd, Packet*, Detector*)
 {
-    ClientSIPData* fd;
-
-    fd = (ClientSIPData*)sip_udp_client_mod.api->data_get(asd,
+    ClientSIPData* fd = (ClientSIPData*)sip_udp_client_mod.api->data_get(asd,
         sip_udp_client_mod.flow_data_index);
-    if (!fd)
+
+    if( !fd )
     {
-        fd = (ClientSIPData*)snort_calloc(sizeof(ClientSIPData));
+        fd = new ClientSIPData();
         sip_udp_client_mod.api->data_add(asd, fd,
             sip_udp_client_mod.flow_data_index, &clientDataFree);
         fd->owner = &sip_udp_client_mod;
@@ -350,7 +346,7 @@ static int sipAppAddPattern(DetectorAppSipPattern** patternList, AppId ClientApp
     return 0;
 }
 
-int sipUaPatternAdd( AppId ClientAppId, const char* clientVersion, const char* pattern)
+int sipUaPatternAdd(AppId ClientAppId, const char* clientVersion, const char* pattern)
 {
     return sipAppAddPattern(&detector_sip_config.sip_ua_list, ClientAppId, clientVersion, pattern);
 }
@@ -368,18 +364,18 @@ int finalize_sip_ua()
     DetectorAppSipPattern* patternNode;
 
     detector_sip_config.sip_ua_matcher = mlmpCreate();
-    if (!detector_sip_config.sip_ua_matcher)
+    if( !detector_sip_config.sip_ua_matcher )
         return -1;
 
     detector_sip_config.sip_server_matcher = mlmpCreate();
-    if (!detector_sip_config.sip_server_matcher)
+    if( !detector_sip_config.sip_server_matcher )
     {
         mlmpDestroy((tMlmpTree*)detector_sip_config.sip_ua_matcher);
         detector_sip_config.sip_ua_matcher = nullptr;
         return -1;
     }
 
-    for (patternNode = detector_sip_config.sip_ua_list; patternNode; patternNode = patternNode->next)
+    for( patternNode = detector_sip_config.sip_ua_list; patternNode; patternNode = patternNode->next )
     {
         num_patterns = parseMultipleHTTPPatterns((const char*)patternNode->pattern.pattern,
             patterns,  PATTERN_PART_MAX, 0);
@@ -388,7 +384,7 @@ int finalize_sip_ua()
         mlmpAddPattern((tMlmpTree*)detector_sip_config.sip_ua_matcher, patterns, patternNode);
     }
 
-    for (patternNode = detector_sip_config.sip_server_list; patternNode; patternNode = patternNode->next)
+    for( patternNode = detector_sip_config.sip_server_list; patternNode; patternNode = patternNode->next )
     {
         num_patterns = parseMultipleHTTPPatterns((const char*)patternNode->pattern.pattern,
             patterns,  PATTERN_PART_MAX, 0);
@@ -406,13 +402,13 @@ static void clean_sip_ua()
 {
     DetectorAppSipPattern* node;
 
-    if (detector_sip_config.sip_ua_matcher)
+    if( detector_sip_config.sip_ua_matcher )
     {
         mlmpDestroy((tMlmpTree*)detector_sip_config.sip_ua_matcher);
         detector_sip_config.sip_ua_matcher = nullptr;
     }
 
-    for (node = detector_sip_config.sip_ua_list; node; node = detector_sip_config.sip_ua_list)
+    for( node = detector_sip_config.sip_ua_list; node; node = detector_sip_config.sip_ua_list )
     {
         detector_sip_config.sip_ua_list = node->next;
         snort_free((void*)node->pattern.pattern);
@@ -425,13 +421,13 @@ static void clean_sip_server()
 {
     DetectorAppSipPattern* node;
 
-    if (detector_sip_config.sip_server_matcher)
+    if( detector_sip_config.sip_server_matcher )
     {
         mlmpDestroy((tMlmpTree*)detector_sip_config.sip_server_matcher);
         detector_sip_config.sip_server_matcher = nullptr;
     }
 
-    for (node = detector_sip_config.sip_server_list; node; node = detector_sip_config.sip_server_list)
+    for( node = detector_sip_config.sip_server_list; node; node = detector_sip_config.sip_server_list )
     {
         detector_sip_config.sip_server_list = node->next;
         snort_free((void*)node->pattern.pattern);
@@ -440,13 +436,13 @@ static void clean_sip_server()
     }
 }
 
-static int get_sip_client_app(void* patternMatcher, char* pattern, uint32_t patternLen,
+static int get_sip_client_app(void* patternMatcher, const char* pattern, uint32_t patternLen,
     AppId* ClientAppId, char** clientVersion)
 {
     tMlmpPattern patterns[3];
     DetectorAppSipPattern* data;
 
-    if (!pattern)
+    if( !pattern )
         return 0;
 
     patterns[0].pattern = (uint8_t*)pattern;
@@ -455,7 +451,7 @@ static int get_sip_client_app(void* patternMatcher, char* pattern, uint32_t patt
 
     data = (DetectorAppSipPattern*)mlmpMatchPatternGeneric((tMlmpTree*)patternMatcher, patterns);
 
-    if (data == nullptr)
+    if( !data )
         return 0;
 
     *ClientAppId = data->userData.ClientAppId;
@@ -471,7 +467,7 @@ static void createRtpFlow(AppIdSession* asd, const Packet* pkt, const sfip_t* cl
 
     fp = AppIdSession::create_future_session(pkt, cliIp, cliPort, srvIp, srvPort, proto, app_id,
             APPID_EARLY_SESSION_FLAG_FW_RULE);
-    if (fp)
+    if( fp )
     {
         fp->client_app_id = asd->client_app_id;
         fp->payload_app_id = asd->payload_app_id;
@@ -482,7 +478,7 @@ static void createRtpFlow(AppIdSession* asd, const Packet* pkt, const sfip_t* cl
     // create an RTCP flow as well
     fp2 = AppIdSession::create_future_session(pkt, cliIp, cliPort + 1, srvIp, srvPort + 1, proto, app_id,
             APPID_EARLY_SESSION_FLAG_FW_RULE);
-    if (fp2)
+    if( fp2 )
     {
         fp2->client_app_id = asd->client_app_id;
         fp2->payload_app_id = asd->payload_app_id;
@@ -491,41 +487,43 @@ static void createRtpFlow(AppIdSession* asd, const Packet* pkt, const sfip_t* cl
     }
 }
 
-static int addFutureRtpFlows(AppIdSession* asd, const SipDialog* dialog, const Packet* p)
+static void addFutureRtpFlows(SipEvent& event, AppIdSession* asd)
 {
-    SIP_MediaData* mdataA,* mdataB;
+    event.begin_media_sessions();
 
-    // check the first media asd
-    if (nullptr == dialog->mediaSessions)
-        return -1;
-    // check the second media asd
-    if (nullptr == dialog->mediaSessions->nextS)
-        return -1;
+    auto session_a = event.next_media_session();
+    auto session_b= event.next_media_session();
+
+    if( !session_a || !session_b )
+        return;
 
     DebugFormat(DEBUG_SIP, "Adding future media sessions ID: %u and %u\n",
-        dialog->mediaSessions->sessionID, dialog->mediaSessions->nextS->sessionID);
+        session_b->get_id(), session_b->get_id());
 
-    mdataA = dialog->mediaSessions->medias;
-    mdataB = dialog->mediaSessions->nextS->medias;
-    while ((nullptr != mdataA)&&(nullptr != mdataB))
+    session_a->begin_media_data();
+    session_b->begin_media_data();
+
+    auto media_a = session_a->next_media_data();
+    auto media_b = session_b->next_media_data();
+
+    while( media_a && media_b )
     {
         DebugFormat(DEBUG_SIP, "Adding future channels Source IP: %s Port: %hu\n",
-            sfip_to_str(&mdataA->maddress), mdataA->mport);
+            sfip_to_str(media_a->get_address()), media_a->get_port());
         DebugFormat(DEBUG_SIP, "Adding future channels Destine IP: %s Port: %hu\n",
-            sfip_to_str(&mdataB->maddress), mdataB->mport);
-
-        createRtpFlow(asd, p, &mdataA->maddress, mdataA->mport, &mdataB->maddress,
-            mdataB->mport, IpProtocol::UDP, APP_ID_RTP);
-        createRtpFlow(asd, p, &mdataB->maddress, mdataB->mport, &mdataA->maddress,
-            mdataA->mport, IpProtocol::UDP, APP_ID_RTP);
-        mdataA = mdataA->nextM;
-        mdataB = mdataB->nextM;
+            sfip_to_str(media_b->get_address()), media_b->get_port());
+
+        createRtpFlow(asd, event.get_packet(), media_a->get_address(), media_a->get_port(),
+            media_b->get_address(), media_b->get_port(), IpProtocol::UDP, APP_ID_RTP);
+        createRtpFlow(asd, event.get_packet(), media_b->get_address(), media_b->get_port(),
+            media_a->get_address(), media_b->get_port(), IpProtocol::UDP, APP_ID_RTP);
+
+        media_a = session_a->next_media_data();
+        media_b = session_b->next_media_data();
     }
-    return 0;
 }
 
-static void SipSessionCbClientProcess(const Packet* p, const SipHeaders* headers, const
-    SipDialog* dialog, AppIdSession* asd)
+static void SipSessionCbClientProcess(SipEvent& event, AppIdSession* asd)
 {
     ClientSIPData* fd;
     AppId ClientAppId = APP_ID_SIP;
@@ -534,78 +532,65 @@ static void SipSessionCbClientProcess(const Packet* p, const SipHeaders* headers
 
     fd = (ClientSIPData*)sip_udp_client_mod.api->data_get(asd,
         sip_udp_client_mod.flow_data_index);
-    if (!fd)
+    if( !fd )
     {
-        fd = (ClientSIPData*)snort_calloc(sizeof(ClientSIPData));
+        fd = new ClientSIPData();
         sip_udp_client_mod.api->data_add(asd, fd,
             sip_udp_client_mod.flow_data_index, &clientDataFree);
         fd->owner = &sip_udp_client_mod;
         asd->set_session_flags(APPID_SESSION_CLIENT_GETS_SERVER_PACKETS);
     }
 
-    if (fd->owner != &sip_udp_client_mod && fd->owner != &sip_tcp_client_mod)
+    if( fd->owner != &sip_udp_client_mod && fd->owner != &sip_tcp_client_mod )
         return;
 
-    direction = (p->is_from_client()) ?
+    direction = (event.get_packet()->is_from_client()) ?
         APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
 
-    if (headers->methodFlag == SIP_METHOD_INVITE && direction == APP_ID_FROM_INITIATOR)
+    if( event.is_invite() && direction == APP_ID_FROM_INITIATOR )
     {
-        if (headers->from && headers->fromLen)
-        {
-            snort_free(fd->from);
-            fd->from = snort_strndup(headers->from, headers->fromLen);
-        }
-
-        if (headers->userName && headers->userNameLen)
-        {
-            snort_free(fd->userName);
-            fd->userName = snort_strndup(headers->userName, headers->userNameLen);
-        }
-        if (headers->userAgent && headers->userAgentLen)
-        {
-            snort_free(fd->clientUserAgent);
-            fd->clientUserAgent = snort_strndup(headers->userAgent, headers->userAgentLen);
-        }
+        fd->from = event.get_from();
+        fd->user_name = event.get_user_name();
+        fd->client_user_agent = event.get_user_agent();
     }
 
-    if (fd->clientUserAgent)
+    if( fd->client_user_agent )
     {
-        if (get_sip_client_app(detector_sip_config.sip_ua_matcher,
-            fd->clientUserAgent, strlen(fd->clientUserAgent), &ClientAppId, &clientVersion))
+        ifget_sip_client_app(detector_sip_config.sip_ua_matcher,
+            fd->client_user_agent->c_str(), fd->client_user_agent->size(), &ClientAppId, &clientVersion) )
             goto success;
     }
 
-    if ( fd->from && !(fd->flags & SIP_FLAG_SERVER_CHECKED))
+    if( fd->from && !(fd->flags & SIP_FLAG_SERVER_CHECKED) )
     {
         fd->flags |= SIP_FLAG_SERVER_CHECKED;
 
-        if (get_sip_client_app(detector_sip_config.sip_server_matcher,
-            (char*)fd->from, strlen(fd->from), &ClientAppId, &clientVersion))
+        ifget_sip_client_app(detector_sip_config.sip_server_matcher,
+            fd->from->c_str(), fd->from->size(), &ClientAppId, &clientVersion) )
             goto success;
     }
 
-    if (!dialog || dialog->state != SIP_DLG_ESTABLISHED)
+    if( !event.is_dialog_established() )
         return;
 
 success:
     //client detection successful
     sip_udp_client_mod.api->add_app(asd, APP_ID_SIP, ClientAppId, clientVersion);
+    appid_stats.sip_clients++;
 
-    if (fd->userName)
-        sip_udp_client_mod.api->add_user(asd, (char*)fd->userName, APP_ID_SIP, 1);
+    if( fd->user_name )
+        sip_udp_client_mod.api->add_user(asd, fd->user_name->c_str(), APP_ID_SIP, 1);
 
     asd->set_session_flags(APPID_SESSION_CLIENT_DETECTED);
 }
 
-static void SipSessionCbServiceProcess(const Packet* p, const SipHeaders* headers, const
-    SipDialog* dialog, AppIdSession* asd)
+static void SipSessionCbServiceProcess(SipEvent& event, AppIdSession* asd)
 {
     ServiceSIPData* ss;
     int direction;
 
     ss = (ServiceSIPData*)sip_service_mod.api->data_get(asd, sip_service_mod.flow_data_index);
-    if (!ss)
+    if( !ss )
     {
         ss = (ServiceSIPData*)snort_calloc(sizeof(ServiceSIPData));
         sip_service_mod.api->data_add(asd, ss, sip_service_mod.flow_data_index, &snort_free);
@@ -613,80 +598,42 @@ static void SipSessionCbServiceProcess(const Packet* p, const SipHeaders* header
 
     ss->serverPkt = 0;
 
-    direction = p->is_from_client() ? APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
+    direction = event.get_packet()->is_from_client() ? APP_ID_FROM_INITIATOR : APP_ID_FROM_RESPONDER;
 
-    if (direction == APP_ID_FROM_RESPONDER)
+    if( direction == APP_ID_FROM_RESPONDER )
     {
-        if (headers->userAgent && headers->userAgentLen)
+        if( event.get_user_agent() )
         {
-            memcpy(ss->vendor, headers->userAgent,
-                headers->userAgentLen > (MAX_VENDOR_SIZE - 1) ?  (MAX_VENDOR_SIZE - 1) :
-                headers->userAgentLen);
+            memcpy(ss->vendor, event.get_user_agent()->c_str(),
+                event.get_user_agent()->size() > (MAX_VENDOR_SIZE - 1) ?  (MAX_VENDOR_SIZE - 1) :
+                event.get_user_agent()->size());
         }
-        else if (headers->server && headers->serverLen)
+        else if( event.get_server() )
         {
-            memcpy(ss->vendor, headers->server,
-                headers->serverLen > (MAX_VENDOR_SIZE - 1) ?  (MAX_VENDOR_SIZE - 1) :
-                headers->serverLen);
+            memcpy(ss->vendor, event.get_server()->c_str(),
+                event.get_server()->size() > (MAX_VENDOR_SIZE - 1) ?  (MAX_VENDOR_SIZE - 1) :
+                event.get_server()->size());
         }
     }
 
-    if (!dialog)
+    if( !event.has_dialog() )
         return;
 
-    if (dialog->mediaUpdated)
-        addFutureRtpFlows(asd, dialog, p);
+    if( event.is_media_updated() )
+        addFutureRtpFlows(event, asd);
 
-    if (dialog->state == SIP_DLG_ESTABLISHED)
+    if( event.is_dialog_established() )
     {
-        if (!asd->get_session_flags(APPID_SESSION_SERVICE_DETECTED))
+        if( !asd->get_session_flags(APPID_SESSION_SERVICE_DETECTED) )
         {
             asd->set_session_flags(APPID_SESSION_CONTINUE);
-            sip_service_mod.api->add_service(asd, p, direction, &svc_element,
+            sip_service_mod.api->add_service(asd, event.get_packet(), direction, &svc_element,
                 APP_ID_SIP, ss->vendor[0] ? ss->vendor : nullptr, nullptr, nullptr);
+            appid_stats.sip_flows++;
         }
     }
 }
 
-void SipSessionSnortCallback(void*, ServiceEventType, void* data)
-{
-    AppIdSession* asd = nullptr;
-    SipEventData* eventData = (SipEventData*)data;
-
-    const Packet* p = eventData->packet;
-    const SipHeaders* headers = eventData->headers;
-    const SipDialog* dialog = eventData->dialog;
-
-#ifdef DEBUG_APP_ID_SESSIONS
-    {
-        char src_ip[INET6_ADDRSTRLEN];
-        char dst_ip[INET6_ADDRSTRLEN];
-        const sfip_t* ip;
-
-        src_ip[0] = 0;
-        ip = p->ptrs.ip_api.get_src();
-        sfip_ntop(ip, src_ip, sizeof(src_ip));
-        dst_ip[0] = 0;
-        ip = p->ptrs.ip_api.get_dst();
-        sfip_ntop(ip, dst_ip, sizeof(dst_ip));
-        fprintf(SF_DEBUG_FILE, "AppId Sip Snort Callback Session %s-%u -> %s-%u %d\n", src_ip,
-            (unsigned)p->src_port, dst_ip, (unsigned)p->dst_port, IsTCP(p) ? IpProtocol::TCP :
-            IpProtocol::UDP);
-    }
-#endif
-    if(p->flow)
-       asd = appid_api.get_appid_data(p->flow);
-
-    if(!asd)
-    {
-       WarningMessage("AppId Session does not exist.\n");
-       return;
-    }
-
-    SipSessionCbClientProcess(p, headers, dialog, asd);
-    SipSessionCbServiceProcess(p, headers, dialog, asd);
-}
-
 static int sip_service_init(const InitServiceAPI* const init_api)
 {
     init_api->RegisterPattern(&sip_service_validate, IpProtocol::UDP,
@@ -765,3 +712,35 @@ static int sip_service_validate(ServiceValidationArgs* args)
     return SERVICE_INPROCESS;
 }
 
+void SipEventHandler::handle(DataEvent& event, Flow* flow)
+{
+    AppIdSession* asd = nullptr;
+
+#ifdef DEBUG_APP_ID_SESSIONS
+    {
+        char src_ip[INET6_ADDRSTRLEN];
+        char dst_ip[INET6_ADDRSTRLEN];
+        const sfip_t* ip;
+
+        src_ip[0] = 0;
+        ip = p->ptrs.ip_api.get_src();
+        sfip_ntop(ip, src_ip, sizeof(src_ip));
+        dst_ip[0] = 0;
+        ip = p->ptrs.ip_api.get_dst();
+        sfip_ntop(ip, dst_ip, sizeof(dst_ip));
+        fprintf(SF_DEBUG_FILE, "AppId Sip Snort Callback Session %s-%u -> %s-%u %d\n", src_ip,
+            (unsigned)p->src_port, dst_ip, (unsigned)p->dst_port, IsTCP(p) ? IpProtocol::TCP :
+            IpProtocol::UDP);
+    }
+#endif
+    if( flow )
+       asd = appid_api.get_appid_data(flow);
+
+    if( !asd )
+       return;
+
+    SipSessionCbClientProcess((SipEvent&)event, asd);
+    SipSessionCbServiceProcess((SipEvent&)event, asd);
+}
+
+
index deb5b6e8c345edfab6fb435a7ae970348ee84c77..23eb96e87a71d06908e8f87e0dfcc78386d1cc2c 100644 (file)
@@ -24,8 +24,9 @@
 
 //  AppId structures for SIP detection
 
-#include "detector_api.h"
 #include "appid_utils/sf_multi_mpse.h"
+#include "detector_api.h"
+#include "framework/data_bus.h"
 
 struct RNAServiceValidationModule;
 
@@ -53,5 +54,11 @@ void SipSessionSnortCallback(void* ssnptr, ServiceEventType, void* eventData);
 int sipUaPatternAdd( AppId, const char* clientVersion, const char* uaPattern);
 int sipServerPatternAdd(AppId, const char* clientVersion, const char* uaPattern);
 int finalize_sip_ua();
+
+class SipEventHandler : public DataHandler
+{
+public:
+    void handle(DataEvent&, Flow*);
+};
 #endif
 
index 68862c27f71b31adb6c43335441732c39f751b23..5989a6b75d03ee8e26f963527eebd18564650a3a 100644 (file)
@@ -1,4 +1,6 @@
 add_library( pub_sub STATIC
     http_events.cc
     http_events.h
+    sip_events.cc
+    sip_events.h
 )
index f52d3b36996683cac6007122fa35d39b34718c67..4421082d600541d71dfeb4f3765745b07d7d2583 100644 (file)
@@ -3,9 +3,10 @@ noinst_LIBRARIES = libpub_sub.a
 
 libpub_sub_a_SOURCES = \
 http_events.cc \
-http_events.h
+http_events.h \
+sip_events.cc \
+sip_events.h
 
 #if ENABLE_UNIT_TESTS
 #SUBDIRS = test
 #endif
-
diff --git a/src/pub_sub/sip_events.cc b/src/pub_sub/sip_events.cc
new file mode 100644 (file)
index 0000000..cd7829f
--- /dev/null
@@ -0,0 +1,114 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2016-2016 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+// sip_events.cc author Carter Waxman <cwaxman@cisco.com>
+
+#include "sip_events.h"
+
+#include "service_inspectors/sip/sip_common.h"
+#include "service_inspectors/sip/sip_dialog.h"
+
+using namespace std;
+
+SipEvent::SipEvent(const Packet* p, const SIPMsg* msg, const SIP_DialogData* dialog)
+{
+    this->p = p;
+    this->msg = msg;
+    this->dialog = dialog;
+
+    if( msg->from )
+        from = string(msg->from, msg->fromLen);
+
+    if( msg->userName )
+        user_name = string(msg->userName, msg->userNameLen);
+
+    if( msg->userAgent )
+        user_agent = string(msg->userAgent, msg->userAgentLen);
+
+    if( msg->server )
+        server = string(msg->server, msg->serverLen);
+}
+
+SipEvent::~SipEvent()
+{
+    for( auto& session : sessions )
+        delete session;
+}
+
+bool SipEvent::is_invite() const
+{ return msg->methodFlag == SIP_METHOD_INVITE; }
+
+bool SipEvent::is_media_updated() const
+{ return msg->mediaUpdated; }
+
+bool SipEvent::has_dialog() const
+{ return dialog; }
+
+bool SipEvent::is_dialog_established() const
+{ return has_dialog() && dialog->state == SIP_DLG_ESTABLISHED; }
+
+void SipEvent::begin_media_sessions()
+{
+    if( has_dialog() )
+        current_media_session = dialog->mediaSessions;
+}
+
+SipEventMediaSession* SipEvent::next_media_session()
+{
+    if( !current_media_session )
+        return nullptr;
+    
+    auto session = new SipEventMediaSession(current_media_session);
+    sessions.push_front(session);
+
+    current_media_session = current_media_session->nextS;
+
+    return session;
+}
+
+
+SipEventMediaSession::~SipEventMediaSession()
+{
+    for( auto& d : data )
+        delete d;
+}
+
+uint32_t SipEventMediaSession::get_id() const
+{ return session->sessionID; }
+
+void SipEventMediaSession::begin_media_data()
+{ current_media_data = session->medias; }
+
+SipEventMediaData* SipEventMediaSession::next_media_data()
+{
+    if( !current_media_data )
+        return nullptr;
+    
+   auto d = new SipEventMediaData(current_media_data);
+   data.push_front(d);
+   
+   current_media_data = current_media_data->nextM;
+   
+   return d; 
+}
+
+
+const sfip_t* SipEventMediaData::get_address() const
+{ return &data->maddress; }
+
+uint16_t SipEventMediaData::get_port() const
+{ return data->mport; }
diff --git a/src/pub_sub/sip_events.h b/src/pub_sub/sip_events.h
new file mode 100644 (file)
index 0000000..b956593
--- /dev/null
@@ -0,0 +1,120 @@
+//--------------------------------------------------------------------------
+// Copyright (C) 2016-2016 Cisco and/or its affiliates. All rights reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License Version 2 as published
+// by the Free Software Foundation.  You may not use, modify or distribute
+// this program under any other version of the GNU General Public License.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+//--------------------------------------------------------------------------
+// sip_events.h author Carter Waxman <cwaxman@cisco.com>
+
+#ifndef SIP_EVENTS_H
+#define SIP_EVENTS_H
+
+// This event conveys data published by the SIP service inspector to be consumed
+// by data bus subscribers
+
+#include <list>
+
+#include "framework/data_bus.h"
+#include "protocols/packet.h"
+
+#define SIP_EVENT_TYPE_SIP_DIALOG_KEY "sip_event_type_sip_dialog"
+
+enum SipEventType
+{
+    SIP_EVENT_TYPE_SIP_DIALOG
+};
+
+struct SIPMsg;
+struct SIP_DialogData;
+struct SIP_MediaSession;
+struct SIP_MediaData;
+
+class SipEventMediaData
+{
+public:
+    SipEventMediaData(SIP_MediaData* data)
+    { this->data = data; } 
+    
+    const sfip_t* get_address() const;
+    uint16_t get_port() const;
+
+private:
+    SIP_MediaData* data;
+};
+
+class SipEventMediaSession
+{
+public:
+    SipEventMediaSession(SIP_MediaSession* session)
+    { this->session = session; }
+
+    ~SipEventMediaSession();
+
+    uint32_t get_id() const;
+
+    void begin_media_data();
+    SipEventMediaData* next_media_data();
+
+private:
+    SIP_MediaSession* session;
+
+    std::list<SipEventMediaData*> data;
+    SIP_MediaData* current_media_data = nullptr;
+};
+
+class SipEvent : public DataEvent
+{
+public:
+    SipEvent(const Packet*, const SIPMsg*, const SIP_DialogData*);
+    ~SipEvent();
+
+    const Packet* get_packet() override
+    { return p; }
+
+    const std::string* get_from() const
+    { return from.size() ? &from : nullptr; }
+
+    const std::string* get_user_name() const
+    { return user_name.size() ? &user_name : nullptr; }
+
+    const std::string* get_user_agent() const
+    { return user_agent.size() ? &user_agent : nullptr; }
+
+    const std::string* get_server() const
+    { return server.size() ? &server : nullptr; }
+
+    bool is_invite() const;
+    bool is_media_updated() const;
+    bool has_dialog() const;
+    bool is_dialog_established() const;
+
+    void begin_media_sessions();
+    SipEventMediaSession* next_media_session();
+
+private:
+    const Packet* p;
+
+    const SIPMsg* msg;
+    const SIP_DialogData* dialog;
+
+    std::string from;
+    std::string user_name;
+    std::string user_agent;
+    std::string server;
+
+    std::list<SipEventMediaSession*> sessions;
+    SIP_MediaSession* current_media_session = nullptr;
+};
+
+#endif
index d3a14a0044ce341121b2613842bcdb68bb1ebc47..f1b0a28124d212c7d0cc9758aeee7c5016626397 100644 (file)
 extern const BaseApi* sin_imap;
 extern const BaseApi* sin_pop;
 extern const BaseApi* sin_smtp;
+extern const BaseApi* sin_sip;
 extern const BaseApi* sin_ssl;
+extern const BaseApi* ips_sip_body;
+extern const BaseApi* ips_sip_header;
+extern const BaseApi* ips_sip_method;
+extern const BaseApi* ips_sip_stat_code;
 extern const BaseApi* ips_ssl_state;
 extern const BaseApi* ips_ssl_version;
 
@@ -46,10 +51,6 @@ extern const BaseApi* ips_gtp_version;
 extern const BaseApi* ips_modbus_data;
 extern const BaseApi* ips_modbus_func;
 extern const BaseApi* ips_modbus_unit;
-extern const BaseApi* ips_sip_body;
-extern const BaseApi* ips_sip_header;
-extern const BaseApi* ips_sip_method;
-extern const BaseApi* ips_sip_stat_code;
 
 // FIXIT-L use snort_plugins aliases for static builds
 // so only one extern symbol per library is required
@@ -82,7 +83,6 @@ extern const BaseApi* sin_gtp;
 extern const BaseApi* sin_modbus;
 extern const BaseApi* sin_http;
 extern const BaseApi* sin_rpc_decode;
-extern const BaseApi* sin_sip;
 extern const BaseApi* sin_ssh;
 extern const BaseApi* sin_telnet;
 extern const BaseApi* sin_wizard;
@@ -92,8 +92,14 @@ const BaseApi* service_inspectors[] =
 {
     sin_imap,
     sin_pop,
+    sin_sip,
     sin_smtp,
     sin_ssl,
+
+    ips_sip_body,
+    ips_sip_header,
+    ips_sip_method,
+    ips_sip_stat_code,
     ips_ssl_state,
     ips_ssl_version,
 
@@ -112,10 +118,6 @@ const BaseApi* service_inspectors[] =
     ips_modbus_data,
     ips_modbus_func,
     ips_modbus_unit,
-    ips_sip_body,
-    ips_sip_header,
-    ips_sip_method,
-    ips_sip_stat_code,
 
     ips_http_uri,
     ips_http_client_body,
@@ -146,7 +148,6 @@ const BaseApi* service_inspectors[] =
     sin_modbus,
     sin_http,
     sin_rpc_decode,
-    sin_sip,
     sin_ssh,
     sin_telnet,
     sin_wizard,
index 6bf263be028d820dc4ed1ea838ae017a26f14b8a..2506f93d4c0302f4f909391bebf177dfc9471791 100644 (file)
@@ -19,10 +19,11 @@ set( FILE_LIST
     ips_sip_method.cc
 )
 
-if (STATIC_INSPECTORS)
+#FIXIT-M fix dependency loops
+#if (STATIC_INSPECTORS)
     add_library( sip STATIC ${FILE_LIST})
 
-else (STATIC_INSPECTORS)
-    add_shared_library(sip inspectors ${FILE_LIST})
+#else (STATIC_INSPECTORS)
+#    add_shared_library(sip inspectors ${FILE_LIST})
 
-endif (STATIC_INSPECTORS)
+#endif (STATIC_INSPECTORS)
index ddec28ddfcc967edc4b890bb174aea5028f682e6..3ed76b07079a0fce2c6e23610b23b881468d1460 100644 (file)
@@ -18,14 +18,14 @@ ips_sip.cc \
 ips_sip_stat_code.cc \
 ips_sip_method.cc
 
-if STATIC_INSPECTORS
+#if STATIC_INSPECTORS
 noinst_LIBRARIES = libsip.a
 libsip_a_SOURCES = $(file_list)
-else
-shlibdir = $(pkglibdir)/inspectors
-shlib_LTLIBRARIES = libsip.la
-libsip_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
-libsip_la_LDFLAGS = $(AM_LDFLAGS) -export-dynamic -shared
-libsip_la_SOURCES = $(file_list)
-endif
+#else
+#shlibdir = $(pkglibdir)/inspectors
+#shlib_LTLIBRARIES = libsip.la
+#libsip_la_CXXFLAGS = $(AM_CXXFLAGS) -DBUILDING_SO
+#libsip_la_LDFLAGS = $(AM_LDFLAGS) -export-dynamic -shared
+#libsip_la_SOURCES = $(file_list)
+#endif
 
index e6c39fd5bdd7685db21cc192f3d8b0b566e4ec55..84d0b13b1acefa5ccf06317eaafc62ff9dd20482 100644 (file)
 #ifndef SIP_COMMON_H
 #define SIP_COMMON_H
 
+#include "framework/data_bus.h"
+
 // Header containing datatypes/definitions shared by SSL inspector files.
 
-typedef enum _SIP_method
+enum SIPMethodsFlag
 {
     SIP_METHOD_NULL        = 0,    // 0x0000,
     SIP_METHOD_INVITE      = 1,    // 0x0001,
@@ -43,7 +45,7 @@ typedef enum _SIP_method
     SIP_METHOD_PRACK       = 14,   // 0x2000,
     SIP_METHOD_USER_DEFINE = 15,   // 0x4000,
     SIP_METHOD_USER_DEFINE_MAX = 32// 0x80000000,
-} SIPMethodsFlag;
+};
 
 struct SipHeaders
 {
@@ -103,17 +105,5 @@ struct SipDialog
     bool mediaUpdated;
 };
 
-struct SipEventData
-{
-    const Packet* packet;
-    const SipHeaders* headers;
-    const SipDialog* dialog;
-};
-
-enum SipEventType
-{
-    SIP_EVENT_TYPE_SIP_DIALOG
-};
-
 #endif
 
index 0e3d3fcc1c98d4fe261fe757383e9adc020dbc99..4b845bc54b654ec987de57df3295c098f1b576a2 100644 (file)
@@ -31,6 +31,7 @@
 #include "main/snort_config.h"
 #include "main/snort_debug.h"
 #include "main/snort_types.h"
+#include "pub_sub/sip_events.h"
 #include "protocols/vlan.h"
 #include "sfip/sf_ip.h"
 #include "stream/stream.h"
@@ -650,60 +651,11 @@ static int SIP_deleteDialog(SIP_DialogData* currDialog, SIP_DialogList* dList)
     return true;
 }
 
-// FIXIT-H Publish event for appid
-#if 0
-/*********************************************************************
- * Update appId sip detector with parsed SIP message and dialog
- *
- * Arguments:
- *  Packet * - pointer to packet structure
- *  SIPMsg        * - pointer to parserd SIP messgage
- *  SIPData       * - pointer to SIP session
- *
- * Returns:
- *  None
- *
- *********************************************************************/
-static void sip_update_appid(const Packet* p, const SIPMsg* sipMsg, const SIP_DialogData* dialog)
+static void sip_publish_data_bus(const Packet* p, const SIPMsg* sip_msg, const SIP_DialogData* dialog)
 {
-    SipHeaders hdrs;
-    SipDialog dlg;
-    SipEventData sipEventData;
-
-    hdrs.callid = sipMsg->call_id;
-    hdrs.callidLen = sipMsg->callIdLen;
-    hdrs.methodFlag = sipMsg->methodFlag;
-
-    hdrs.userAgent = sipMsg->userAgent;
-    hdrs.userAgentLen = sipMsg->userAgentLen;
-    hdrs.server = sipMsg->server;
-    hdrs.serverLen = sipMsg->serverLen;
-    hdrs.userName = sipMsg->userName;
-    hdrs.userNameLen = sipMsg->userNameLen;
-    hdrs.from = sipMsg->from;
-    hdrs.fromLen= sipMsg->fromLen;
-
-    sipEventData.headers = &hdrs;
-
-    if (dialog)
-    {
-        dlg.state = dialog->state;
-        dlg.mediaSessions = dialog->mediaSessions;
-        dlg.mediaUpdated = sipMsg->mediaUpdated;
-        sipEventData.dialog = &dlg;
-    }
-    else
-    {
-        sipEventData.dialog = NULL;
-    }
-
-    sipEventData.packet = p;
-
-    if (Stream::service_event_publish(PP_SIP, p->flow, SIP_EVENT_TYPE_SIP_DIALOG, &sipEventData)
-     == false)
-     ErrorMessage("failed to publish to SIP_DIALOG\n");
+    SipEvent event(p, sip_msg, dialog);
+    get_data_bus().publish(SIP_EVENT_TYPE_SIP_DIALOG_KEY, event, p->flow);
 }
-#endif
 
 /********************************************************************
  * Function: SIP_updateDialog()
@@ -722,10 +674,10 @@ static void sip_update_appid(const Packet* p, const SIPMsg* sipMsg, const SIP_Di
 int SIP_updateDialog(SIPMsg* sipMsg, SIP_DialogList* dList, Packet* p, SIP_PROTO_CONF* config)
 {
     SIP_DialogData* dialog;
-    SIP_DialogData* oldDialog = NULL;
+    SIP_DialogData* oldDialog = nullptr;
     int ret;
 
-    if ((NULL == sipMsg)||(0 == sipMsg->dlgID.callIdHash))
+    if ((nullptr == sipMsg)||(0 == sipMsg->dlgID.callIdHash))
         return false;
 
     DebugFormat(DEBUG_SIP, "Updating Dialog id: %u, From: %u, To: %u\n",
@@ -735,7 +687,7 @@ int SIP_updateDialog(SIPMsg* sipMsg, SIP_DialogList* dList, Packet* p, SIP_PROTO
 
     /*Find out the dialog in the dialog list*/
 
-    while (NULL != dialog)
+    while (nullptr != dialog)
     {
         DebugFormat(DEBUG_SIP, "Dialog id: %u, From: %u, To: %u\n",
             dialog->dlgID.callIdHash,dialog->dlgID.fromTagHash,dialog->dlgID.toTagHash);
@@ -765,17 +717,12 @@ int SIP_updateDialog(SIPMsg* sipMsg, SIP_DialogList* dList, Packet* p, SIP_PROTO
     else
         ret = false;
 
-// FIXIT-H Publish event for appid
-#if 0
-    for (dialog = dList->head;
-        dialog;
-        dialog = dialog->nextD)
+    for (dialog = dList->head; dialog; dialog = dialog->nextD)
     {
         if (sipMsg->dlgID.callIdHash == dialog->dlgID.callIdHash)
             break;
     }
-    sip_update_appid(p, sipMsg, dialog);
-#endif
+    sip_publish_data_bus(p, sipMsg, dialog);
 
     return ret;
 }