]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1232 in SNORT/snort3 from tp_string to master
authorMike Stepanek (mstepane) <mstepane@cisco.com>
Fri, 18 May 2018 18:05:21 +0000 (14:05 -0400)
committerMike Stepanek (mstepane) <mstepane@cisco.com>
Fri, 18 May 2018 18:05:21 +0000 (14:05 -0400)
Squashed commit of the following:

commit d67139c8ecec99df3709d8ebac14fe52dc63921e
Author: Silviu Minut <sminut@cisco.com>
Date:   Fri May 18 12:51:52 2018 -0400

    appid: fix tabs and indentation

commit 3325d54ba6e18978bd16920b4e9ff0b55e9d51ad
Author: Silviu Minut <sminut@cisco.com>
Date:   Fri May 18 09:51:30 2018 -0400

    appid: fix segfault due to dereferencing null host pointer.

commit eec54e0b5ba244156fbed75aa3952eb5b2a23605
Author: Silviu Minut <sminut@cisco.com>
Date:   Thu May 17 15:11:21 2018 -0400

    appid: make tp_attribute_data more localized, so we only allocate/deallocate it if needed.

commit 3c426a26644146e5aa36216399b24e7ee8f2f1d0
Author: Silviu Minut <sminut@cisco.com>
Date:   Thu May 17 11:40:14 2018 -0400

    appid: fix memory leak in appid_http_event_test and warning in appid_http_session.cc

commit ad2c55c8c6bcfc70fc3d32242803b40895070fcf
Author: Silviu Minut <sminut@cisco.com>
Date:   Thu May 17 09:53:26 2018 -0400

    appid: change metadata buffers from std::string to pointers, to avoid extra copying

src/network_inspectors/appid/appid_http_session.cc
src/network_inspectors/appid/appid_http_session.h
src/network_inspectors/appid/appid_session.h
src/network_inspectors/appid/test/appid_mock_http_session.h
src/network_inspectors/appid/tp_appid_types.h
src/network_inspectors/appid/tp_appid_utils.cc

index 1edd7515b68d2c87db7cadfec7a2c52ecd94e0dd..f2d889edaecf06b81b060eb0fd6d1609a5981c11 100644 (file)
@@ -53,7 +53,21 @@ static const char* httpFieldName[ MAX_HTTP_FIELD_ID ] = // for use in debug mess
 snort::ProfileStats httpPerfStats;
 
 AppIdHttpSession::AppIdHttpSession(AppIdSession& asd)
-    : asd(asd)
+    : asd(asd),
+    host(nullptr),
+    url(nullptr),
+    uri(nullptr),
+    referer(nullptr),
+    useragent(nullptr),
+    via(nullptr),
+    cookie(nullptr),
+    body(nullptr),
+    response_code(nullptr),
+    content_type(nullptr),
+    location(nullptr),
+    req_body(nullptr),
+    server(nullptr),
+    x_working_with(nullptr)
 {
     http_matchers = HttpPatternMatchers::get_instance();
 }
@@ -61,6 +75,34 @@ AppIdHttpSession::AppIdHttpSession(AppIdSession& asd)
 AppIdHttpSession::~AppIdHttpSession()
 {
     delete xff_addr;
+    if (host)
+        delete host;
+    if (url)
+        delete url;
+    if (uri)
+        delete uri;
+    if (referer)
+        delete referer;
+    if (useragent)
+        delete useragent;
+    if (via)
+        delete via;
+    if (cookie)
+        delete cookie;
+    if (body)
+        delete body;
+    if (response_code)
+        delete response_code;
+    if (content_type)
+        delete content_type;
+    if (location)
+        delete location;
+    if (req_body)
+        delete req_body;
+    if (server)
+        delete server;
+    if (x_working_with)
+        delete x_working_with;
 }
 
 void AppIdHttpSession::free_chp_matches(ChpMatchDescriptor& cmd, unsigned num_matches)
@@ -81,7 +123,6 @@ int AppIdHttpSession::initial_chp_sweep(ChpMatchDescriptor& cmd)
             cmd.cur_ptype = (HttpFieldIds)i;
             http_matchers->scan_key_chp(cmd);
         }
-
     }
 
     if (cmd.match_tally.empty())
@@ -119,7 +160,7 @@ int AppIdHttpSession::initial_chp_sweep(ChpMatchDescriptor& cmd)
         ptype_scan_counts[i] = cah->ptype_scan_counts[i];
         ptype_req_counts[i] = cah->ptype_req_counts[i] + cah->ptype_rewrite_insert_used[i];
         if (i > 3 && !cah->ptype_scan_counts[i]
-                                             && !asd.get_session_flags(APPID_SESSION_SPDY_SESSION))
+            && !asd.get_session_flags(APPID_SESSION_SPDY_SESSION))
         {
             asd.clear_session_flags(APPID_SESSION_CHP_INSPECTING);
 #ifdef ENABLE_APPID_THIRD_PARTY
@@ -158,25 +199,25 @@ int AppIdHttpSession::initial_chp_sweep(ChpMatchDescriptor& cmd)
 
 void AppIdHttpSession::init_chp_match_descriptor(ChpMatchDescriptor& cmd)
 {
-    cmd.buffer[REQ_AGENT_FID] = useragent.c_str();
-    cmd.buffer[REQ_HOST_FID] = host.c_str();
-    cmd.buffer[REQ_REFERER_FID] = referer.c_str();
-    cmd.buffer[REQ_URI_FID] = uri.c_str();
-    cmd.buffer[REQ_COOKIE_FID] = cookie.c_str();
-    cmd.buffer[REQ_BODY_FID] = req_body.c_str();
-    cmd.buffer[RSP_CONTENT_TYPE_FID] = content_type.c_str();
-    cmd.buffer[RSP_LOCATION_FID] = location.c_str();
-    cmd.buffer[RSP_BODY_FID] = body.c_str();
-
-    cmd.length[REQ_AGENT_FID] = useragent.size();
-    cmd.length[REQ_HOST_FID] = host.size();
-    cmd.length[REQ_REFERER_FID] = referer.size();
-    cmd.length[REQ_URI_FID] = uri.size();
-    cmd.length[REQ_COOKIE_FID] = cookie.size();
-    cmd.length[REQ_BODY_FID] = req_body.size();
-    cmd.length[RSP_CONTENT_TYPE_FID] = content_type.size();
-    cmd.length[RSP_LOCATION_FID] = location.size();
-    cmd.length[RSP_BODY_FID] = body.size();
+    cmd.buffer[REQ_AGENT_FID] = useragent ? useragent->c_str() : nullptr;
+    cmd.buffer[REQ_HOST_FID] = host ? host->c_str() : nullptr;
+    cmd.buffer[REQ_REFERER_FID] = referer ? referer->c_str() : nullptr;
+    cmd.buffer[REQ_URI_FID] = uri ? uri->c_str() : nullptr;
+    cmd.buffer[REQ_COOKIE_FID] = cookie ? cookie->c_str() : nullptr;
+    cmd.buffer[REQ_BODY_FID] = req_body ? req_body->c_str() : nullptr;
+    cmd.buffer[RSP_CONTENT_TYPE_FID] = content_type ? content_type->c_str() : nullptr;
+    cmd.buffer[RSP_LOCATION_FID] = location ? location->c_str() : nullptr;
+    cmd.buffer[RSP_BODY_FID] = body ? body->c_str() : nullptr;
+
+    cmd.length[REQ_AGENT_FID] = useragent ? useragent->size() : 0;
+    cmd.length[REQ_HOST_FID] = host ? host->size() : 0;
+    cmd.length[REQ_REFERER_FID] = referer ? referer->size() : 0;
+    cmd.length[REQ_URI_FID] = uri ? uri->size() : 0;
+    cmd.length[REQ_COOKIE_FID] = cookie ? cookie->size() : 0;
+    cmd.length[REQ_BODY_FID] = req_body ? req_body->size() : 0;
+    cmd.length[RSP_CONTENT_TYPE_FID] = content_type ? content_type->size() : 0;
+    cmd.length[RSP_LOCATION_FID] = location ? location->size() : 0;
+    cmd.length[RSP_BODY_FID] = body ? body->size() : 0;
 }
 
 void AppIdHttpSession::process_chp_buffers()
@@ -244,7 +285,7 @@ void AppIdHttpSession::process_chp_buffers()
                 // either the num_matches value was zero and we failed early-on or we need to check
                 // for the min.
                 if (num_matches &&
-                                total_found < num_matches)
+                    total_found < num_matches)
                 {
                     // There was a minimum scans match count (num_matches != 0)
                     // And we did not reach that minimum
@@ -285,7 +326,7 @@ void AppIdHttpSession::process_chp_buffers()
         if (chp_candidate && chp_finished)
         {
             AppId chp_final = chp_alt_candidate ? chp_alt_candidate
-                            : CHP_APPIDINSTANCE_TO_ID(chp_candidate);
+                : CHP_APPIDINSTANCE_TO_ID(chp_candidate);
 
             if (app_type_flags & APP_TYPE_SERVICE)
                 asd.set_service_appid_data(chp_final, nullptr, version);
@@ -316,7 +357,8 @@ void AppIdHttpSession::process_chp_buffers()
                 if ( cmd.chp_rewritten[i] )
                 {
                     if (appidDebug->is_active())
-                        LogMessage("AppIdDbg %s Rewritten %s: %s\n", appidDebug->get_debug_session(),
+                        LogMessage("AppIdDbg %s Rewritten %s: %s\n",
+                            appidDebug->get_debug_session(),
                             httpFieldName[i], cmd.chp_rewritten[i]);
 
                     http_fields[i].field = cmd.chp_rewritten[i];
@@ -352,10 +394,11 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction)
     AppId client_id = APP_ID_NONE;
     AppId payload_id = APP_ID_NONE;
     bool have_tp = asd.tpsession != nullptr;
-    
+
     // For fragmented HTTP headers, do not process if none of the fields are set.
     // These fields will get set when the HTTP header is reassembled.
-    if ( useragent.empty() && host.empty() && referer.empty() && uri.empty() )
+
+    if ( !useragent && !host && !referer && !uri )
     {
         if (!skip_simple_detect)
             asd.clear_http_flags();
@@ -363,16 +406,17 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction)
     }
 
     if ( direction == APP_ID_FROM_RESPONDER &&
-                    !asd.get_session_flags(APPID_SESSION_RESPONSE_CODE_CHECKED) )
+        !asd.get_session_flags(APPID_SESSION_RESPONSE_CODE_CHECKED) )
     {
-        if ( !response_code.empty() )
+        if ( response_code )
         {
             asd.set_session_flags(APPID_SESSION_RESPONSE_CODE_CHECKED);
             constexpr auto RESPONSE_CODE_LENGTH = 3;
-            if (response_code.size() != RESPONSE_CODE_LENGTH)
+            if (response_code->size() != RESPONSE_CODE_LENGTH)
             {
                 if (appidDebug->is_active())
-                    LogMessage("AppIdDbg %s Bad http response code.\n", appidDebug->get_debug_session());
+                    LogMessage("AppIdDbg %s Bad http response code.\n",
+                        appidDebug->get_debug_session());
                 asd.reset_session_data();
                 return 0;
             }
@@ -384,7 +428,8 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction)
             /* didn't receive response code in first X packets. Stop processing this session */
             asd.reset_session_data();
             if (appidDebug->is_active())
-                LogMessage("AppIdDbg %s No response code received\n", appidDebug->get_debug_session());
+                LogMessage("AppIdDbg %s No response code received\n",
+                    appidDebug->get_debug_session());
             return 0;
         }
 #endif
@@ -394,7 +439,8 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction)
         asd.service.set_id(APP_ID_HTTP);
 
     if (appidDebug->is_active())
-        LogMessage("AppIdDbg %s chp_finished %d chp_hold_flow %d\n", appidDebug->get_debug_session(),
+        LogMessage("AppIdDbg %s chp_finished %d chp_hold_flow %d\n",
+            appidDebug->get_debug_session(),
             chp_finished, chp_hold_flow);
 
     if (!chp_finished || chp_hold_flow)
@@ -407,8 +453,8 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction)
             // Scan Server Header for Vendor & Version
             // FIXIT-M: Should we be checking the scan_flags even when
             //     tp_appid_module is off?
-            if ( (have_tp && (asd.scan_flags & SCAN_HTTP_VENDOR_FLAG) &&
-                  !server.empty()) || (!have_tp && !server.empty()) )
+            if ( (have_tp && (asd.scan_flags & SCAN_HTTP_VENDOR_FLAG) && server)
+                || (!have_tp && server) )
             {
                 if ( asd.service.get_id() == APP_ID_NONE || asd.service.get_id() == APP_ID_HTTP )
                 {
@@ -416,7 +462,7 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction)
                     char* vendorVersion = nullptr;
                     char* vendor = nullptr;
 
-                    http_matchers->get_server_vendor_version(server.c_str(), server.size(),
+                    http_matchers->get_server_vendor_version(server->c_str(), server->size(),
                         &vendorVersion, &vendor, &asd.subtype);
                     if (vendor || vendorVersion)
                     {
@@ -433,7 +479,7 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction)
                         AppIdServiceSubtype** tmpSubtype;
 
                         for (tmpSubtype = &asd.subtype; *tmpSubtype; tmpSubtype =
-                                        &(*tmpSubtype)->next)
+                            &(*tmpSubtype)->next)
                             ;
 
                         *tmpSubtype = local_subtype;
@@ -451,18 +497,22 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction)
 
             // Scan User-Agent for Browser types or Skype
             if ( (asd.scan_flags & SCAN_HTTP_USER_AGENT_FLAG)
-                            && asd.client.get_id() <= APP_ID_NONE && !useragent.empty() )
+                && asd.client.get_id() <= APP_ID_NONE && useragent )
             {
                 char* version = nullptr;
 
-                http_matchers->identify_user_agent(useragent.c_str(), useragent.size(),
+                http_matchers->identify_user_agent(useragent->c_str(), useragent->size(),
                     service_id, client_id, &version);
                 if (appidDebug->is_active())
                 {
-                    if (service_id > APP_ID_NONE and service_id != APP_ID_HTTP and asd.service.get_id() != service_id)
-                        LogMessage("AppIdDbg %s User Agent is service %d\n", appidDebug->get_debug_session(), service_id);
-                    if (client_id > APP_ID_NONE and client_id != APP_ID_HTTP and asd.client.get_id() != client_id)
-                        LogMessage("AppIdDbg %s User Agent is client %d\n", appidDebug->get_debug_session(), client_id);
+                    if (service_id > APP_ID_NONE and service_id != APP_ID_HTTP and
+                        asd.service.get_id() != service_id)
+                        LogMessage("AppIdDbg %s User Agent is service %d\n",
+                            appidDebug->get_debug_session(), service_id);
+                    if (client_id > APP_ID_NONE and client_id != APP_ID_HTTP and
+                        asd.client.get_id() != client_id)
+                        LogMessage("AppIdDbg %s User Agent is client %d\n",
+                            appidDebug->get_debug_session(), client_id);
                 }
                 asd.set_service_appid_data(service_id, nullptr, nullptr);
                 asd.set_client_appid_data(client_id, version);
@@ -471,12 +521,14 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction)
             }
 
             /* Scan Via Header for squid */
-            if ( !asd.is_payload_appid_set() && (asd.scan_flags & SCAN_HTTP_VIA_FLAG) && !via.empty() )
+            if ( !asd.is_payload_appid_set() && (asd.scan_flags & SCAN_HTTP_VIA_FLAG) && via )
             {
-                payload_id = http_matchers->get_appid_by_pattern(via.c_str(), via.size(), nullptr);
+                payload_id = http_matchers->get_appid_by_pattern(via->c_str(), via->size(),
+                    nullptr);
                 if (appidDebug->is_active() && payload_id > APP_ID_NONE &&
-                                asd.payload.get_id() != payload_id)
-                    LogMessage("AppIdDbg %s VIA is payload %d\n", appidDebug->get_debug_session(), payload_id);
+                    asd.payload.get_id() != payload_id)
+                    LogMessage("AppIdDbg %s VIA is payload %d\n", appidDebug->get_debug_session(),
+                        payload_id);
                 asd.set_payload_appid_data((AppId)payload_id, nullptr);
                 asd.scan_flags &= ~SCAN_HTTP_VIA_FLAG;
             }
@@ -486,28 +538,30 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction)
         // FIXIT-M: Should we be checking the scan_flags even when
         //     tp_appid_module is off?
         if ( (have_tp && (asd.scan_flags & SCAN_HTTP_XWORKINGWITH_FLAG) &&
-              !x_working_with.empty()) || (!have_tp && !x_working_with.empty()))
+            x_working_with) || (!have_tp && x_working_with))
         {
             AppId appId;
             char* version = nullptr;
 
-            appId = http_matchers->scan_header_x_working_with(x_working_with.c_str(),
-                x_working_with.size(), &version);
+            appId = http_matchers->scan_header_x_working_with(x_working_with->c_str(),
+                x_working_with->size(), &version);
             if ( appId )
             {
                 if (direction == APP_ID_FROM_INITIATOR)
                 {
                     if (appidDebug->is_active() && client_id > APP_ID_NONE && client_id !=
-                                    APP_ID_HTTP && asd.client.get_id() != client_id)
-                        LogMessage("AppIdDbg %s X is client %d\n", appidDebug->get_debug_session(), appId);
+                        APP_ID_HTTP && asd.client.get_id() != client_id)
+                        LogMessage("AppIdDbg %s X is client %d\n", appidDebug->get_debug_session(),
+                            appId);
 
                     asd.set_client_appid_data(appId, version);
                 }
                 else
                 {
                     if (appidDebug->is_active() && service_id > APP_ID_NONE && service_id !=
-                                    APP_ID_HTTP && asd.service.get_id() != service_id)
-                        LogMessage("AppIdDbg %s X service %d\n", appidDebug->get_debug_session(), appId);
+                        APP_ID_HTTP && asd.service.get_id() != service_id)
+                        LogMessage("AppIdDbg %s X service %d\n", appidDebug->get_debug_session(),
+                            appId);
                     asd.set_service_appid_data(appId, nullptr, version);
                 }
                 asd.scan_flags &= ~SCAN_HTTP_XWORKINGWITH_FLAG;
@@ -520,13 +574,15 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction)
         // FIXIT-M: Should we be checking the scan_flags even when
         //     tp_appid_module is off?
         if ( (have_tp && (asd.scan_flags & SCAN_HTTP_CONTENT_TYPE_FLAG)
-              && !content_type.empty() && !asd.is_payload_appid_set())
-             || (!have_tp && !asd.is_payload_appid_set() && !content_type.empty()) )
+            && content_type && !asd.is_payload_appid_set())
+            || (!have_tp && !asd.is_payload_appid_set() && content_type) )
         {
-            payload_id = http_matchers->get_appid_by_content_type(content_type.c_str(), content_type.size());
+            payload_id = http_matchers->get_appid_by_content_type(content_type->c_str(),
+                content_type->size());
             if (appidDebug->is_active() && payload_id > APP_ID_NONE
-                            && asd.payload.get_id() != payload_id)
-                LogMessage("AppIdDbg %s Content-Type is payload %d\n", appidDebug->get_debug_session(),
+                && asd.payload.get_id() != payload_id)
+                LogMessage("AppIdDbg %s Content-Type is payload %d\n",
+                    appidDebug->get_debug_session(),
                     payload_id);
             asd.set_payload_appid_data((AppId)payload_id, nullptr);
             asd.scan_flags &= ~SCAN_HTTP_CONTENT_TYPE_FLAG;
@@ -536,16 +592,20 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction)
         {
             AppId referredPayloadAppId = 0;
             char* version = nullptr;
-            char* my_host = snort_strdup(host.c_str());
-            if ( http_matchers->get_appid_from_url(my_host, url.c_str(), &version,
-                referer.c_str(), &client_id, &service_id, &payload_id, &referredPayloadAppId, false) )
+            char* my_host = host ? snort_strdup(host->c_str()) : nullptr;
+            const char* refStr = referer ? referer->c_str() : nullptr;
+            const char* urlStr = url ? url->c_str() : nullptr;
+            if ( http_matchers->get_appid_from_url(my_host, urlStr, &version,
+                refStr, &client_id, &service_id, &payload_id,
+                &referredPayloadAppId, false) )
             {
                 // do not overwrite a previously-set client or service
                 if (asd.client.get_id() <= APP_ID_NONE)
                 {
                     if (appidDebug->is_active() && client_id > APP_ID_NONE && client_id !=
-                                    APP_ID_HTTP && asd.client.get_id() != client_id)
-                        LogMessage("AppIdDbg %s URL is client %d\n", appidDebug->get_debug_session(),
+                        APP_ID_HTTP && asd.client.get_id() != client_id)
+                        LogMessage("AppIdDbg %s URL is client %d\n",
+                            appidDebug->get_debug_session(),
                             client_id);
                     asd.set_client_appid_data(client_id, nullptr);
                 }
@@ -553,15 +613,16 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction)
                 if (asd.service.get_id() <= APP_ID_NONE)
                 {
                     if (appidDebug->is_active() && service_id > APP_ID_NONE && service_id !=
-                                    APP_ID_HTTP && asd.service.get_id() != service_id)
-                        LogMessage("AppIdDbg %s URL is service %d\n", appidDebug->get_debug_session(),
+                        APP_ID_HTTP && asd.service.get_id() != service_id)
+                        LogMessage("AppIdDbg %s URL is service %d\n",
+                            appidDebug->get_debug_session(),
                             service_id);
                     asd.set_service_appid_data(service_id, nullptr, nullptr);
                 }
 
                 // DO overwrite a previously-set data
                 if (appidDebug->is_active() && payload_id > APP_ID_NONE &&
-                                asd.payload.get_id() != payload_id)
+                    asd.payload.get_id() != payload_id)
                     LogMessage("AppIdDbg %s URL is payload %d\n", appidDebug->get_debug_session(),
                         payload_id);
                 asd.set_payload_appid_data((AppId)payload_id, version);
@@ -569,8 +630,10 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction)
             }
 
             asd.scan_flags &= ~SCAN_HTTP_HOST_URL_FLAG;
-            snort_free(version);
-            snort_free(my_host);
+            if ( version )
+                snort_free(version);
+            if ( my_host )
+                snort_free(my_host);
         }
 
         if (asd.client.get_id() == APP_ID_APPLE_CORE_MEDIA)
@@ -637,7 +700,8 @@ void AppIdHttpSession::update_http_xff_address(struct XffFieldValue* xff_fields,
     {
         for (unsigned i = 0; i < numXffFields; i++)
             LogMessage("AppIdDbg %s XFF %s : %s\n", appidDebug->get_debug_session(),
-               xff_fields[i].field.c_str(), xff_fields[i].value.empty()? "(empty)": xff_fields[i].value);
+                xff_fields[i].field.c_str(), xff_fields[i].value.empty() ? "(empty)" :
+                xff_fields[i].value);
     }
 
     // xffPrecedence array is sorted based on precedence
@@ -653,7 +717,7 @@ void AppIdHttpSession::update_http_xff_address(struct XffFieldValue* xff_fields,
 
             if (strncasecmp(xff_fields[j].field.c_str(), xffPrecedence[i], UINT8_MAX) == 0)
             {
-                if(xff_fields[j].value.empty())
+                if (xff_fields[j].value.empty())
                     return;
 
                 // For a comma-separated list of addresses, pick the last address
@@ -693,30 +757,34 @@ void AppIdHttpSession::update_http_xff_address(struct XffFieldValue* xff_fields,
 
 void AppIdHttpSession::set_url(const char* url)
 {
+    if ( this->url )
+        delete this->url;
     if ( url )
-        this->url = url;
+        this->url = new std::string(url);   // FIXIT-M null terminated?
     else
-        this->url.clear();
+        this->url = nullptr;
 }
 
 void AppIdHttpSession::set_referer(char* referer)
 {
+    if ( this->referer )
+        delete this->referer;
     if ( referer )
-        this->referer = referer;
+        this->referer = new std::string(referer);
     else
-        this->referer.clear();
+        this->referer = nullptr;
 }
 
 const char* AppIdHttpSession::get_new_url()
 {
     return http_fields[REQ_URI_FID].field.empty()
-                    ? nullptr : http_fields[REQ_URI_FID].field.c_str();
+           ? nullptr : http_fields[REQ_URI_FID].field.c_str();
 }
 
 const char* AppIdHttpSession::get_new_cookie()
 {
     return http_fields[REQ_COOKIE_FID].field.empty()
-                    ? nullptr : http_fields[REQ_COOKIE_FID].field.c_str();
+           ? nullptr : http_fields[REQ_COOKIE_FID].field.c_str();
 }
 
 const char* AppIdHttpSession::get_new_field(HttpFieldIds fieldId)
@@ -764,75 +832,203 @@ uint16_t AppIdHttpSession::get_cookie_end_offset()
     return http_fields[REQ_COOKIE_FID].end_offset;
 }
 
-void AppIdHttpSession::update_host(const uint8_t* new_host, int32_t len)
+void AppIdHttpSession::update_host(const std::string* new_host)
 {
-    host.assign((const char*)new_host, len);
+    if (host)
+        delete host;
+    host = new_host;
 }
 
-void AppIdHttpSession::update_uri(const uint8_t* new_uri, int32_t len)
+void AppIdHttpSession::update_uri(const std::string* new_uri)
 {
-    uri.assign((const char*)new_uri, len);
+    if (uri)
+        delete uri;
+    uri = new_uri;
 }
 
 void AppIdHttpSession::update_url()
 {
-    url = "http://";
-    url += host + uri;
+    if (host and uri)
+    {
+        if (url)
+            delete url;
+        url = new std::string(std::string("http://") + *host + *uri);
+    }
+}
+
+void AppIdHttpSession::update_url(const std::string* new_url)
+{
+    if ( url )
+        delete url;
+    url = new_url;
+}
+
+void AppIdHttpSession::update_useragent(const std::string* new_ua)
+{
+    if (useragent)
+        delete useragent;
+    useragent = new_ua;
+}
+
+void AppIdHttpSession::update_cookie(const std::string* new_cookie)
+{
+    if (cookie)
+        delete cookie;
+    cookie = new_cookie;
+}
+
+void AppIdHttpSession::update_referer(const std::string* new_referer)
+{
+    if (referer)
+        delete referer;
+    referer = new_referer;
+}
+
+void AppIdHttpSession::update_x_working_with(const std::string* new_xww)
+{
+    if (x_working_with)
+        delete x_working_with;
+    x_working_with = new_xww;
+}
+
+void AppIdHttpSession::update_content_type(const std::string* new_content_type)
+{
+    if (content_type)
+        delete content_type;
+    content_type = new_content_type;
+}
+
+void AppIdHttpSession::update_location(const std::string* new_location)
+{
+    if (location)
+        delete location;
+    location = new_location;
+}
+
+void AppIdHttpSession::update_server(const std::string* new_server)
+{
+    if (server)
+        delete server;
+    server = new_server;
+}
+
+void AppIdHttpSession::update_via(const std::string* new_via)
+{
+    if (via)
+        delete via;
+    via = new_via;
+}
+
+void AppIdHttpSession::update_body(const std::string* new_body)
+{
+    if (body)
+        delete body;
+    body = new_body;
+}
+
+void AppIdHttpSession::update_req_body(const std::string* new_req_body)
+{
+    if (req_body)
+        delete req_body;
+    req_body = new_req_body;
+}
+
+void AppIdHttpSession::update_response_code(const std::string* new_rc)
+{
+    if (response_code)
+        delete response_code;
+    response_code = new_rc;
+}
+
+void AppIdHttpSession::update_host(const uint8_t* new_host, int32_t len)
+{
+    if ( host )
+        delete host;
+    host = new std::string((const char*)new_host, len);
+}
+
+void AppIdHttpSession::update_uri(const uint8_t* new_uri, int32_t len)
+{
+    if ( uri )
+        delete uri;
+    uri = new std::string((const char*)new_uri, len);
 }
 
 void AppIdHttpSession::update_useragent(const uint8_t* new_ua, int32_t len)
 {
-    useragent.assign((const char*)new_ua, len);
+    if ( useragent )
+        delete useragent;
+    useragent = new std::string((const char*)new_ua, len);
 }
 
 void AppIdHttpSession::update_cookie(const uint8_t* new_cookie, int32_t len)
 {
-    cookie.assign((const char*)new_cookie, len);
+    if ( cookie )
+        delete cookie;
+    cookie = new std::string((const char*)new_cookie, len);
 }
 
 void AppIdHttpSession::update_referer(const uint8_t* new_referer, int32_t len)
 {
-    referer.assign((const char*)new_referer, len);
+    if ( referer )
+        delete referer;
+    referer = new std::string((const char*)new_referer, len);
 }
 
 void AppIdHttpSession::update_x_working_with(const uint8_t* new_xww, int32_t len)
 {
-    x_working_with.assign((const char*)new_xww, len);
+    if ( x_working_with )
+        delete x_working_with;
+    x_working_with = new std::string((const char*)new_xww, len);
 }
 
 void AppIdHttpSession::update_content_type(const uint8_t* new_content_type, int32_t len)
 {
-    content_type.assign((const char*)new_content_type, len);
+    if ( content_type )
+        delete content_type;
+    content_type = new std::string((const char*)new_content_type, len);
 }
 
 void AppIdHttpSession::update_location(const uint8_t* new_location, int32_t len)
 {
-    location.assign((const char*)new_location, len);
+    if ( location )
+        delete location;
+    location = new std::string((const char*)new_location, len);
 }
 
 void AppIdHttpSession::update_server(const uint8_t* new_server, int32_t len)
 {
-    server.assign((const char*)new_server, len);
+    if ( server )
+        delete server;
+    server = new std::string((const char*)new_server, len);
 }
 
 void AppIdHttpSession::update_via(const uint8_t* new_via, int32_t len)
 {
-    via.assign((const char*)new_via, len);
+    if ( via )
+        delete via;
+    via = new std::string((const char*)new_via, len);
 }
 
 void AppIdHttpSession::update_body(const uint8_t* new_body, int32_t len)
 {
-    body.assign((const char*)new_body, len);
+    if ( body )
+        delete body;
+    body = new std::string((const char*)new_body, len);
 }
 
 void AppIdHttpSession::update_req_body(const uint8_t* new_req_body, int32_t len)
 {
-    req_body.assign((const char*)new_req_body, len);
+    if ( req_body )
+        delete req_body;
+    req_body = new std::string((const char*)new_req_body, len);
 }
 
 void AppIdHttpSession::update_response_code(const char* new_rc)
 {
-    response_code = new_rc;
+    if ( response_code )
+        delete response_code;
+    response_code = new std::string((const char*)new_rc);  // FIXIT-L null term?
 }
 
 void AppIdHttpSession::reset_ptype_scan_counts()
@@ -840,4 +1036,3 @@ void AppIdHttpSession::reset_ptype_scan_counts()
     memset(ptype_scan_counts, 0, sizeof(ptype_scan_counts));
 }
 
-
index 74bfd6733f9808d3975c30d06f519f251e0f3c9f..a3fc3006c6c7f96dbfcf1a09f65223fd8b7bc750 100644 (file)
@@ -78,50 +78,50 @@ public:
     void update_http_xff_address(struct XffFieldValue* xff_fields, uint32_t numXffFields);
 
     const char* get_user_agent()
-    { return useragent.empty() ? nullptr : useragent.c_str(); }
+    { return useragent ? useragent->c_str() : nullptr; }
 
     const char* get_host()
-    { return host.empty() ? nullptr : host.c_str(); }
+    { return host ? host->c_str() : nullptr; }
 
     const char* get_url()
-    { return url.empty() ? nullptr : url.c_str(); }
+    { return url ? url->c_str() : nullptr; }
 
     void set_url(const char* url = nullptr);
 
     const char* get_uri()
-    { return uri.empty() ? nullptr : uri.c_str(); }
+    { return uri ? uri->c_str() : nullptr; }
 
     const char* get_via()
-    { return via.empty() ? nullptr : via.c_str(); }
+    { return via ? via->c_str() : nullptr; }
 
     const char* get_referer()
-    { return referer.empty() ? nullptr : referer.c_str(); }
+    { return referer ? referer->c_str() : nullptr; }
 
     void set_referer(char* referer = nullptr);
 
     const char* get_cookie()
-    { return cookie.empty() ? nullptr : cookie.c_str(); }
+    { return cookie ? cookie->c_str() : nullptr; }
 
     const char* get_response_code()
-    { return response_code.empty() ? nullptr : response_code.c_str(); }
+    { return response_code ? response_code->c_str() : nullptr; }
 
     const char* get_content_type()
-    { return content_type.empty() ? nullptr : content_type.c_str(); }
+    { return content_type ? content_type->c_str() : nullptr; }
 
     const char* get_location()
-    { return location.empty() ? nullptr : location.c_str(); }
+    { return location ? location->c_str() : nullptr; }
 
     const char* get_req_body()
-    { return req_body.empty() ? nullptr : req_body.c_str(); }
+    { return req_body ? req_body->c_str() : nullptr; }
 
     const char* get_server()
-    { return server.empty() ? nullptr : server.c_str(); }
+    { return server ? server->c_str() : nullptr; }
 
     const char* get_body()
-    { return body.empty() ? nullptr : body.c_str(); }
+    { return body ? body->c_str() : nullptr; }
 
     const char* get_x_working_with()
-    { return x_working_with.empty() ? nullptr : x_working_with.c_str(); }
+    { return x_working_with ? x_working_with->c_str() : nullptr; }
 
     const char* get_new_url();
     const char* get_new_cookie();
@@ -138,9 +138,34 @@ public:
     snort::SfIp* get_xff_addr()
     { return xff_addr; }
 
+    // FIXME-L
+    // We get these fields from 2 sources: HttpEvent or ThirdParty.
+    // From HttpEvent we get them as char*, from ThirdParty we get them
+    // as string*. Since we own ThirdParty, we can simply snatch the
+    // pointer, thus avoiding an extra copy. From HttpEvent, though, we
+    // must make a hard copy. Consequently, currently we have to have
+    // two sets of update_foo() functions: one for ThirdParty (that just
+    // snatches the string* pointer) and another for HttpEvent (that makes
+    // a hard copy). These should be consolidated at some point.
+
+    // These are used with ThirdParty (tp_appid_utils.cc)
+    void update_host(const std::string* new_host);
+    void update_uri(const std::string* new_uri);
+    void update_useragent(const std::string* new_ua);
+    void update_cookie(const std::string* new_cookie);
+    void update_referer(const std::string* new_referer);
+    void update_x_working_with(const std::string* new_xww);
+    void update_content_type(const std::string* new_content_type);
+    void update_location(const std::string* new_location);
+    void update_server(const std::string* new_server);
+    void update_via(const std::string* new_via);
+    void update_body(const std::string* new_body);
+    void update_req_body(const std::string* new_req_body);
+    void update_response_code(const std::string* new_rc);
+
+    // These are used with HttpEvent (appid_http_event_handler.cc)
     void update_host(const uint8_t* new_host, int32_t len);
     void update_uri(const uint8_t* new_uri, int32_t len);
-    void update_url();
     void update_useragent(const uint8_t* new_ua, int32_t len);
     void update_cookie(const uint8_t* new_cookie, int32_t len);
     void update_referer(const uint8_t* new_referer, int32_t len);
@@ -152,6 +177,10 @@ public:
     void update_body(const uint8_t* new_body, int32_t len);
     void update_req_body(const uint8_t* new_req_body, int32_t len);
     void update_response_code(const char* new_rc);
+
+    void update_url();
+    void update_url(const std::string* new_url);
+
     void set_is_webdav(bool webdav)
     { is_webdav = webdav; }
 
@@ -204,20 +233,20 @@ protected:
     HttpPatternMatchers* http_matchers = nullptr;
 
     AppIdSession& asd;
-    std::string host;
-    std::string url;
-    std::string uri;
-    std::string referer;
-    std::string useragent;
-    std::string via;
-    std::string cookie;
-    std::string body;
-    std::string response_code;
-    std::string content_type;
-    std::string location;
-    std::string req_body;
-    std::string server;
-    std::string x_working_with;
+    const std::string* host;
+    const std::string* url;
+    const std::string* uri;
+    const std::string* referer;
+    const std::string* useragent;
+    const std::string* via;
+    const std::string* cookie;
+    const std::string* body;
+    const std::string* response_code;
+    const std::string* content_type;
+    const std::string* location;
+    const std::string* req_body;
+    const std::string* server;
+    const std::string* x_working_with;
     bool is_webdav = false;
     bool chp_finished = false;
     AppId chp_candidate = APP_ID_NONE;
@@ -233,12 +262,11 @@ protected:
     const char** xffPrecedence = nullptr;
     unsigned numXffFields = 0;
     HttpField http_fields[MAX_HTTP_FIELD_ID];
-    int ptype_req_counts[MAX_HTTP_FIELD_ID] = {0};
-    int ptype_scan_counts[MAX_HTTP_FIELD_ID] = {0};
+    int ptype_req_counts[MAX_HTTP_FIELD_ID] = { 0 };
+    int ptype_scan_counts[MAX_HTTP_FIELD_ID] = { 0 };
 #if RESPONSE_CODE_PACKET_THRESHHOLD
     unsigned response_code_packets = 0;
 #endif
-
 };
 
 #endif
index cd888e7f81edc5e85e7bec7be6989e943c8ef5da..35b628ad27535355a9599b7f1e2eb1b50036844f 100644 (file)
@@ -127,11 +127,32 @@ struct CommonAppIdData
 struct TlsSession
 {
     char* tls_host = nullptr;
-    int tls_host_strlen = 0;
+    int tls_host_strlen = 0;     // FIXIT-M: not rvalue, remove
     char* tls_cname = nullptr;
-    int tls_cname_strlen = 0;
+    int tls_cname_strlen = 0;    // FIXIT-M: not rvalue, remove
     char* tls_orgUnit = nullptr;
-    int tls_orgUnit_strlen = 0;
+    int tls_orgUnit_strlen = 0;  // FIXiT-M: not rvalue, remove
+
+    void set_tls_host(const char* new_tls_host, uint32_t len)
+    {
+        if (tls_host) snort_free(tls_host);
+        tls_host=snort_strndup(new_tls_host,len);
+        tls_host_strlen=len;
+    }
+
+    void set_tls_cname(const char* new_tls_cname, uint32_t len)
+    {
+        if (tls_cname) snort_free(tls_cname);
+        tls_cname=snort_strndup(new_tls_cname,len);
+        tls_cname_strlen=len;
+    }
+
+    void set_tls_org_unit(const char* new_tls_org_unit, uint32_t len)
+    {
+        if (tls_orgUnit) snort_free(tls_orgUnit);
+        tls_orgUnit=snort_strndup(new_tls_org_unit,len);
+        tls_orgUnit_strlen=len;
+    }
 };
 
 class AppIdSession : public snort::FlowData
index 1181d25d6920413a996174a6afdedf3c90071f0d..64b6ddbeacfeb2aeef015885002b627a4b33fdc2 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef APPID_MOCK_HTTP_SESSION_H
 #define APPID_MOCK_HTTP_SESSION_H
 
+#include <string>
+
 AppIdHttpSession::AppIdHttpSession(AppIdSession& session)
     : asd(session)
 {
@@ -29,6 +31,34 @@ AppIdHttpSession::AppIdHttpSession(AppIdSession& session)
 AppIdHttpSession::~AppIdHttpSession()
 {
     delete xff_addr;
+    if (host)
+        delete host;
+    if (url)
+        delete url;
+    if (uri)
+        delete uri;
+    if (referer)
+        delete referer;
+    if (useragent)
+        delete useragent;
+    if (via)
+        delete via;
+    if (cookie)
+        delete cookie;
+    if (body)
+        delete body;
+    if (response_code)
+        delete response_code;
+    if (content_type)
+        delete content_type;
+    if (location)
+        delete location;
+    if (req_body)
+        delete req_body;
+    if (server)
+        delete server;
+    if (x_working_with)
+        delete x_working_with;
 }
 
 int AppIdHttpSession::process_http_packet(AppidSessionDirection) { return 0; }
@@ -53,13 +83,14 @@ char const* RSP_BODY = "this is the body of the http response";
 #define URI_OFFSET 22
 #define COOKIE_OFFSET 44
 
-static void replace_header_data(std::string& header, const uint8_t* content, int32_t clen)
+static void replace_header_data(const std::string*& header, const uint8_t* content, int32_t clen)
 {
     if (clen <= 0)
         return;
 
-    header.clear();
-    header.append((char*)content, clen);
+    if (header)
+        delete header;
+    header=new std::string((const char*)content,clen);
 }
 
 void AppIdHttpSession::update_host(const uint8_t* new_host, int32_t len)
@@ -74,8 +105,12 @@ void AppIdHttpSession::update_uri(const uint8_t* new_uri, int32_t len)
 
 void AppIdHttpSession::update_url()
 {
-    url = "http://";
-    url += host + uri;
+    if (host and uri)
+    {
+        if (url)
+            delete url;
+        url=new std::string(std::string("http://") + *host + *uri);
+    }
 }
 
 void AppIdHttpSession::update_useragent(const uint8_t* new_ua, int32_t len)
@@ -130,15 +165,19 @@ void AppIdHttpSession::update_req_body(const uint8_t* new_req_body, int32_t len)
 
 void AppIdHttpSession::update_response_code(const char* new_rc)
 {
-    response_code = new_rc;
+    if ( response_code )
+        delete response_code;
+    response_code = new std::string((char*)new_rc);
 }
 
 void AppIdHttpSession::set_url(const char* url)
 {
+    if ( this->url )
+        delete this->url;
     if ( url )
-        this->url = url;
+        this->url = new std::string(url);   // FIXIT-M null terminated?
     else
-        this->url.clear();
+        this->url = nullptr;
 }
 
 class MockAppIdHttpSession : public AppIdHttpSession
@@ -150,20 +189,20 @@ public:
         SfIp* ip = new SfIp;
         ip->pton(AF_INET, APPID_UT_XFF_IP_ADDR);
         xff_addr = ip;
-        content_type = CONTENT_TYPE;
-        cookie = COOKIE;
-        host = HOST;
-        location = LOCATION;
-        referer = REFERER;
-        response_code = RESPONSE_CODE;
-        server = SERVER;
-        url = URL;
-        uri = URI;
-        useragent = USERAGENT;
-        via = VIA;
-        x_working_with = X_WORKING_WITH;
-        body = RSP_BODY;
-        req_body = REQ_BODY;
+        content_type = new std::string(CONTENT_TYPE);
+        cookie = new std::string(COOKIE);
+        host = new std::string(HOST);
+        location = new std::string(LOCATION);
+        referer = new std::string(REFERER);
+        response_code = new std::string(RESPONSE_CODE);
+        server = new std::string(SERVER);
+        url = new std::string(URL);
+        uri = new std::string(URI);
+        useragent = new std::string(USERAGENT);
+        via = new std::string(VIA);
+        x_working_with = new std::string(X_WORKING_WITH);
+        body = new std::string(RSP_BODY);
+        req_body = new std:: string(REQ_BODY);
         http_fields[REQ_URI_FID].start_offset = URI_OFFSET;
         http_fields[REQ_URI_FID].end_offset = URI_OFFSET + strlen(URI);
         http_fields[REQ_COOKIE_FID].start_offset = COOKIE_OFFSET;
@@ -185,20 +224,47 @@ public:
 
     void reset()
     {
-        content_type.clear();
-        cookie.clear();
-        host.clear();
-        location.clear();
-        referer.clear();
-        response_code.clear();
-        server.clear();
-        url.clear();
-        uri.clear();
-        useragent.clear();
-        via.clear();
-        x_working_with.clear();
-        body.clear();
-        req_body.clear();
+        delete content_type;
+        content_type = nullptr;
+
+        delete cookie;
+        cookie = nullptr;
+
+        delete host;
+        host = nullptr;
+
+        delete location;
+        location = nullptr;
+
+        delete referer;
+        referer = nullptr;
+
+        delete response_code;
+        response_code = nullptr;
+
+        delete server;
+        server = nullptr;
+
+        delete url;
+        url = nullptr;
+
+        delete uri;
+        uri = nullptr;
+
+        delete useragent;
+        useragent = nullptr;
+
+        delete via;
+        via = nullptr;
+
+        delete x_working_with;
+        x_working_with = nullptr;
+
+        delete body;
+        body = nullptr;
+
+        delete req_body;
+        req_body = nullptr;
     }
 
     static AppIdHttpSession* init_http_session(AppIdSession& asd)
@@ -207,9 +273,6 @@ public:
 
         return hsession;
     }
-
-
-
 };
 
 #endif
index b89b505d9012a013cff991ae694bd5cc90cb946c..f93f6f7e09e6a8b99e3f2387295eb213143899a9 100644 (file)
@@ -58,9 +58,9 @@ enum TPSessionAttr
 };
 
 #define TPAD_GET(func)                                          \
-    const string* func(bool caller_owns_it = 0)                 \
+    string* func(bool caller_owns_it = 0)                       \
     {                                                           \
-        const string* tmp = func ## _buf;                       \
+        string* tmp = func ## _buf;                             \
         if (caller_owns_it)                                     \
             func ## _buf = nullptr;                             \
         return tmp;                                             \
index 9c7563e032972b4aa9433dab22ef3c7aa633b791..70de5621d93ca24c2f8ddb506b4b4ea8c48c5e49 100644 (file)
@@ -70,7 +70,7 @@ static bool contains(const vector<Type_t>& vec, const ValType_t& val)
 static inline bool check_reinspect(const Packet* p, const AppIdSession& asd)
 {
     return p->dsize && !asd.get_session_flags(APPID_SESSION_NO_TPI) &&
-        asd.get_session_flags(APPID_SESSION_HTTP_SESSION) && asd.is_tp_appid_done();
+           asd.get_session_flags(APPID_SESSION_HTTP_SESSION) && asd.is_tp_appid_done();
 }
 
 static inline int check_ssl_appid_for_reinspect(AppId app_id)
@@ -97,15 +97,16 @@ static inline void process_http_session(AppIdSession& asd,
     ThirdPartyAppIDAttributeData& attribute_data)
 {
     AppIdHttpSession* hsession = asd.get_http_session();
-    const string* field=0;
+    string* field=0;
+    bool own=true;
 
     hsession->reset_ptype_scan_counts();
 
     if (asd.get_session_flags(APPID_SESSION_SPDY_SESSION))
     {
-        const string* spdyRequestScheme=attribute_data.spdy_request_scheme();
-        const string* spdyRequestHost=attribute_data.spdy_request_host();
-        const string* spdyRequestPath=attribute_data.spdy_request_path();
+        const string* spdyRequestScheme=attribute_data.spdy_request_scheme(false);
+        const string* spdyRequestHost=attribute_data.spdy_request_host(own);
+        const string* spdyRequestPath=attribute_data.spdy_request_path(own);
 
         if (spdyRequestScheme && spdyRequestHost && spdyRequestPath )
         {
@@ -138,8 +139,7 @@ static inline void process_http_session(AppIdSession& asd,
             if (hsession->get_host())
                 hsession->set_chp_finished(false);
 
-            hsession->update_host((const uint8_t*)spdyRequestHost->c_str(),
-                spdyRequestHost->size());
+            hsession->update_host(spdyRequestHost);
             hsession->set_field_offset(REQ_HOST_FID,
                 attribute_data.spdy_request_host_begin());
             hsession->set_field_end_offset(REQ_HOST_FID,
@@ -157,8 +157,7 @@ static inline void process_http_session(AppIdSession& asd,
             if (hsession->get_uri())
                 hsession->set_chp_finished(false);
 
-            hsession->update_uri((const uint8_t*)spdyRequestPath->c_str(),
-                spdyRequestPath->size());
+            hsession->update_uri(spdyRequestPath);
             hsession->set_field_offset(REQ_URI_FID, attribute_data.spdy_request_path_begin());
             hsession->set_field_end_offset(REQ_URI_FID, attribute_data.spdy_request_path_end());
             if (appidDebug->is_active())
@@ -169,14 +168,13 @@ static inline void process_http_session(AppIdSession& asd,
     }
     else
     {
-        if ( (field=attribute_data.http_request_host()) != nullptr )
+        if ( (field=attribute_data.http_request_host(own)) != nullptr )
         {
             if (hsession->get_host())
                 if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
                     hsession->set_chp_finished(false);
 
-            hsession->update_host((const uint8_t*)field->c_str(),
-                field->size());
+            hsession->update_host(field);
             hsession->set_field_offset(REQ_HOST_FID, attribute_data.http_request_host_begin());
             hsession->set_field_end_offset(REQ_HOST_FID, attribute_data.http_request_host_end());
             if (appidDebug->is_active())
@@ -186,7 +184,7 @@ static inline void process_http_session(AppIdSession& asd,
             asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
         }
 
-        if ( (field=attribute_data.http_request_url()) != nullptr )
+        if ( (field=attribute_data.http_request_url(own)) != nullptr )
         {
             static const char httpScheme[] = "http://";
 
@@ -197,23 +195,24 @@ static inline void process_http_session(AppIdSession& asd,
             if (asd.get_session_flags(APPID_SESSION_DECRYPTED) and
                 memcmp(field->c_str(), httpScheme, sizeof(httpScheme)-1)==0)
             {
-                std::string url("https://");
-                url.append(field->c_str() + sizeof(httpScheme)-1);
-                hsession->set_url(url.c_str());
+                // This is the only instance that requires that field be
+                // non const and the reason TPAD_GET in tp_appid_types.h
+                // returns string* rather than const string*.
+                // In all other cases field can be const string*.
+                field->insert(4,'s',1);
             }
-            else
-                hsession->set_url(field->c_str());
+            hsession->update_url(field);
 
             asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
         }
 
-        if ( (field=attribute_data.http_request_uri()) != nullptr)
+        if ( (field=attribute_data.http_request_uri(own)) != nullptr)
         {
             if (hsession->get_uri())
                 if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
                     hsession->set_chp_finished(false);
 
-            hsession->update_uri((const uint8_t*)field->c_str(),field->size());
+            hsession->update_uri(field);
             hsession->set_field_offset(REQ_URI_FID, attribute_data.http_request_uri_begin());
             hsession->set_field_end_offset(REQ_URI_FID, attribute_data.http_request_uri_end());
             if (appidDebug->is_active())
@@ -223,33 +222,33 @@ static inline void process_http_session(AppIdSession& asd,
         }
     }
 
-    // FIXIT-M: these cases are duplicate.
-    if ( (field=attribute_data.http_request_via()) != nullptr )
+    // FIXIT-M: except for request/response, these cases are duplicate.
+    if ( (field=attribute_data.http_request_via(own)) != nullptr )
     {
         if (hsession->get_via())
             if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
                 hsession->set_chp_finished(false);
 
-        hsession->update_via((const uint8_t*)field->c_str(),field->size());
+        hsession->update_via(field);
         asd.scan_flags |= SCAN_HTTP_VIA_FLAG;
     }
-    else if ( (field=attribute_data.http_response_via()) != nullptr )
+    else if ( (field=attribute_data.http_response_via(own)) != nullptr )
     {
         if (hsession->get_via())
             if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
                 hsession->set_chp_finished(false);
 
-        hsession->update_via((const uint8_t*)field->c_str(),field->size());
+        hsession->update_via(field);
         asd.scan_flags |= SCAN_HTTP_VIA_FLAG;
     }
 
-    if ( (field=attribute_data.http_request_user_agent()) != nullptr )
+    if ( (field=attribute_data.http_request_user_agent(own)) != nullptr )
     {
         if (hsession->get_user_agent())
             if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
                 hsession->set_chp_finished(false);
 
-        hsession->update_useragent((const uint8_t*)field->c_str(),field->size());
+        hsession->update_useragent(field);
         if (appidDebug->is_active())
             LogMessage("AppIdDbg %s User Agent (%u-%u) is %s\n",
                 appidDebug->get_debug_session(), hsession->get_field_offset(REQ_AGENT_FID),
@@ -258,7 +257,7 @@ static inline void process_http_session(AppIdSession& asd,
     }
 
     // Check to see if third party discovered HTTP/2. - once it supports it...
-    if ( (field=attribute_data.http_response_version()) != nullptr )
+    if ( (field=attribute_data.http_response_version(false)) != nullptr )
     {
         if (appidDebug->is_active())
             LogMessage("AppIdDbg %s HTTP response version is %s\n",
@@ -272,7 +271,7 @@ static inline void process_http_session(AppIdSession& asd,
         }
     }
 
-    if ( (field=attribute_data.http_response_code()) != nullptr )
+    if ( (field=attribute_data.http_response_code(own)) != nullptr )
     {
         if (appidDebug->is_active())
             LogMessage("AppIdDbg %s HTTP response code is %s\n",
@@ -281,13 +280,13 @@ static inline void process_http_session(AppIdSession& asd,
             if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
                 hsession->set_chp_finished(false);
 
-        hsession->update_response_code((const char*)field->c_str());
+        hsession->update_response_code(field);
     }
 
     // Check to see if we've got an upgrade to HTTP/2 (if enabled).
     //  - This covers the "without prior knowledge" case (i.e., the client
     //    asks the server to upgrade to HTTP/2).
-    if ( (field=attribute_data.http_response_upgrade()) != nullptr )
+    if ( (field=attribute_data.http_response_upgrade(false) ) != nullptr )
     {
         if (appidDebug->is_active())
             LogMessage("AppIdDbg %s HTTP response upgrade is %s\n",
@@ -305,7 +304,7 @@ static inline void process_http_session(AppIdSession& asd,
                 }
     }
 
-    if ( (field=attribute_data.http_request_referer()) != nullptr )
+    if ( (field=attribute_data.http_request_referer(own)) != nullptr )
     {
         if (appidDebug->is_active())
             LogMessage("AppIdDbg %s referrer is %s\n",
@@ -314,7 +313,7 @@ static inline void process_http_session(AppIdSession& asd,
             if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
                 hsession->set_chp_finished(false);
 
-        hsession->update_referer((const uint8_t*)field->c_str(), field->size());
+        hsession->update_referer(field);
         hsession->set_field_offset(REQ_REFERER_FID, attribute_data.http_request_referer_begin());
         hsession->set_field_end_offset(REQ_REFERER_FID, attribute_data.http_request_referer_end());
         if (appidDebug->is_active())
@@ -324,13 +323,13 @@ static inline void process_http_session(AppIdSession& asd,
                 hsession->get_referer());
     }
 
-    if ( (field=attribute_data.http_request_cookie()) != nullptr )
+    if ( (field=attribute_data.http_request_cookie(own)) != nullptr )
     {
         if (hsession->get_cookie())
             if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
                 hsession->set_chp_finished(false);
 
-        hsession->update_cookie((const uint8_t*)field->c_str(), field->size());
+        hsession->update_cookie(field);
         hsession->set_field_offset(REQ_COOKIE_FID, attribute_data.http_request_cookie_begin());
         hsession->set_field_end_offset(REQ_COOKIE_FID, attribute_data.http_request_cookie_end());
         // FIXIT-M currently we're not doing this, check if necessary
@@ -344,27 +343,27 @@ static inline void process_http_session(AppIdSession& asd,
                 hsession->get_cookie());
     }
 
-    if ( (field=attribute_data.http_response_content()) != nullptr )
+    if ( (field=attribute_data.http_response_content(own)) != nullptr )
     {
         if (hsession->get_content_type())
             if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
                 hsession->set_chp_finished(false);
 
-        hsession->update_content_type((const uint8_t*)field->c_str(), field->size());
+        hsession->update_content_type(field);
         asd.scan_flags |= SCAN_HTTP_CONTENT_TYPE_FLAG;
     }
 
     if (hsession->get_ptype_scan_count(RSP_LOCATION_FID) &&
-        (field=attribute_data.http_response_location()) != nullptr)
+        (field=attribute_data.http_response_location(own)) != nullptr)
     {
         if (hsession->get_location())
             if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
                 hsession->set_chp_finished(false);
 
-        hsession->update_location((const uint8_t*)field->c_str(), field->size());
+        hsession->update_location(field);
     }
 
-    if ( (field=attribute_data.http_request_body()) != nullptr )
+    if ( (field=attribute_data.http_request_body(own)) != nullptr )
     {
         if (appidDebug->is_active())
             LogMessage("AppIdDbg %s got a request body %s\n",
@@ -372,17 +371,17 @@ static inline void process_http_session(AppIdSession& asd,
         if (hsession->get_req_body())
             if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
                 hsession->set_chp_finished(false);
-        hsession->update_req_body((const uint8_t*)field->c_str(), field->size());
+        hsession->update_req_body(field);
     }
 
     if (hsession->get_ptype_scan_count(RSP_BODY_FID) &&
-        (field=attribute_data.http_response_body()) != nullptr)
+        (field=attribute_data.http_response_body(own)) != nullptr)
     {
         if (hsession->get_body())
             if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT))
                 hsession->set_chp_finished(false);
 
-        hsession->update_body((const uint8_t*)field->c_str(), field->size());
+        hsession->update_body(field);
     }
 
     if (attribute_data.numXffFields)
@@ -395,15 +394,15 @@ static inline void process_http_session(AppIdSession& asd,
         asd.tpsession->set_attr(TP_ATTR_CONTINUE_MONITORING);
     }
 
-    if ( (field=attribute_data.http_response_server()) != nullptr)
+    if ( (field=attribute_data.http_response_server(own)) != nullptr)
     {
-        hsession->update_server((const uint8_t*)field->c_str(), field->size());
+        hsession->update_server(field);
         asd.scan_flags |= SCAN_HTTP_VENDOR_FLAG;
     }
 
-    if ( (field=attribute_data.http_request_x_working_with()) != nullptr )
+    if ( (field=attribute_data.http_request_x_working_with(own)) != nullptr )
     {
-        hsession->update_x_working_with((const uint8_t*)field->c_str(), field->size());
+        hsession->update_x_working_with(field);
         asd.scan_flags |= SCAN_HTTP_XWORKINGWITH_FLAG;
     }
 }
@@ -416,23 +415,25 @@ static inline void process_rtmp(AppIdSession& asd,
     AppId client_id = 0;
     AppId payload_id = 0;
     AppId referred_payload_app_id = 0;
+    bool own = true;
 
     const string* field=0;
 
     if (!hsession->get_url())
     {
-        if ( (field=attribute_data.http_request_url()) != nullptr )
+        if ( (field=attribute_data.http_request_url(own)) != nullptr )
         {
-            hsession->set_url(field->c_str());
+            // hsession->set_url(field->c_str());
+            hsession->update_url(field);
             asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG;
         }
     }
 
     if ( !asd.config->mod_config->referred_appId_disabled && !hsession->get_referer() )
     {
-        if ( (field=attribute_data.http_request_referer()) != nullptr )
+        if ( (field=attribute_data.http_request_referer(own)) != nullptr )
         {
-            hsession->update_referer((const uint8_t*)field->c_str(), field->size());
+            hsession->update_referer(field);
         }
     }
 
@@ -476,7 +477,7 @@ static inline void process_ssl(AppIdSession& asd,
 {
     AppId tmpAppId = APP_ID_NONE;
     int tmpConfidence = 0;
-    const string* field=0;
+    const string* field = 0;
 
     // if (tp_appid_module && asd.tpsession)
     tmpAppId = asd.tpsession->get_appid(tmpConfidence);
@@ -489,11 +490,9 @@ static inline void process_ssl(AppIdSession& asd,
     if (!asd.client.get_id())
         asd.set_client_appid_data(APP_ID_SSL_CLIENT, nullptr);
 
-    if ( (field=attribute_data.tls_host()) != nullptr )
+    if ( (field=attribute_data.tls_host(false)) != nullptr )
     {
-        if (asd.tsession->tls_host)
-            snort_free(asd.tsession->tls_host);
-        asd.tsession->tls_host = snort_strdup(field->c_str());
+        asd.tsession->set_tls_host(field->c_str(), field->size());
         if (check_ssl_appid_for_reinspect(tmpAppId))
             asd.scan_flags |= SCAN_SSL_HOST_FLAG;
     }
@@ -502,16 +501,12 @@ static inline void process_ssl(AppIdSession& asd,
     {
         if ( (field=attribute_data.tls_cname()) != nullptr )
         {
-            if (asd.tsession->tls_cname)
-                snort_free(asd.tsession->tls_cname);
-            asd.tsession->tls_cname = snort_strdup(field->c_str());
+            asd.tsession->set_tls_cname(field->c_str(), field->size());
         }
 
         if ( (field=attribute_data.tls_org_unit()) != nullptr )
         {
-            if (asd.tsession->tls_orgUnit)
-                snort_free(asd.tsession->tls_orgUnit);
-            asd.tsession->tls_orgUnit = snort_strdup(field->c_str());
+            asd.tsession->set_tls_org_unit(field->c_str(), field->size());
         }
     }
 }
@@ -586,7 +581,6 @@ static inline void check_terminate_tp_module(AppIdSession& asd, uint16_t tpPktCo
 bool do_discovery(AppIdSession& asd, IpProtocol protocol,
     Packet* p, AppidSessionDirection& direction)
 {
-    ThirdPartyAppIDAttributeData tp_attribute_data;
     vector<AppId> tp_proto_list;
     bool isTpAppidDiscoveryDone = false;
 
@@ -638,9 +632,10 @@ bool do_discovery(AppIdSession& asd, IpProtocol protocol,
             {
                 Profile tpLibPerfStats_profile_context(tpLibPerfStats);
                 int tp_confidence;
+                ThirdPartyAppIDAttributeData tp_attribute_data;
                 if (!asd.tpsession)
                 {
-                   const TPLibHandler* tph = asd.config->tp_handler();
+                    const TPLibHandler* tph = asd.config->tp_handler();
                     CreateThirdPartyAppIDSession_t tpsf = tph->tpsession_factory();
                     if ( !(asd.tpsession = tpsf()) )
                         FatalError("Could not allocate asd.tpsession data");
@@ -835,3 +830,4 @@ bool do_discovery(AppIdSession& asd, IpProtocol protocol,
 
     return isTpAppidDiscoveryDone;
 }
+