From: Mike Stepanek (mstepane) Date: Mon, 18 Jun 2018 18:40:04 +0000 (-0400) Subject: Merge pull request #1272 in SNORT/snort3 from appid_httpMetaArray to master X-Git-Tag: 3.0.0-246~54 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e072f28785aec2fe6f4d0c54b5a8a035aa68e0b0;p=thirdparty%2Fsnort3.git Merge pull request #1272 in SNORT/snort3 from appid_httpMetaArray to master Squashed commit of the following: commit 8cf36b098955d12fed86df29ff29c654be8249f9 Author: Silviu Minut Date: Wed Jun 13 18:33:15 2018 -0400 appid: consolidate http metadata by removing the string pointers and keeping an array of pointers and offsets. appid: add convenience get_cfield function returning a char* rather than string* appid: add back get_xff_addr(), which was mistakenly removed. appid: use the convenince get_cfield function appid: code clean-up appid: reduce the size of the meta_offset array and add comments to the HttpFieldIds enum. appid: nit pick fixes and temporary static friend function inside the AppIdHttpSession class. appid: revert the static friend experiment and make the meta_offset array protected in AppIdHttpSession, with public set/get functions. appid: uncrustify appid: provide separate get/set functions for offsets, do away with MAX_PATTERN_TYPE and rename MAX_HTTP_FIELD_ID to NUM_HTTP_FIELDS appid: uncrustify appid_http_session.h commit ef1aedfc90c2e25db192f5ead615f9d36f6c9757 Author: Silviu Minut Date: Fri Jun 8 23:04:48 2018 -0400 appid: remove http_fields array from AppIdHttpSession appid: consolidate http metadata in appid by removing the http_fields array from http session. Needs clean-up. appid: code clean-up for removing duplicate http metadata and unit test fix. appid: clean-up after rebase to master appid: remove commented out http_fields array appid: do not delete metadata string pointers in AppIdHttpSession::process_http_packet --- diff --git a/src/network_inspectors/appid/appid_detector.cc b/src/network_inspectors/appid/appid_detector.cc index e06626fe6..2da7f5374 100644 --- a/src/network_inspectors/appid/appid_detector.cc +++ b/src/network_inspectors/appid/appid_detector.cc @@ -70,18 +70,17 @@ void AppIdDetector::add_info(AppIdSession& asd, const char* info) { AppIdHttpSession* hsession = asd.get_http_session(); - if ( !hsession->get_url() ) - hsession->set_url(info); + if ( !hsession->get_field(MISC_URL_FID) ) + hsession->set_field(MISC_URL_FID, new std::string(info)); } void AppIdDetector::add_user(AppIdSession& asd, const char* username, AppId appId, bool success) { - asd.client.update_user( appId, username); + asd.client.update_user(appId, username); if ( success ) asd.set_session_flags(APPID_SESSION_LOGIN_SUCCEEDED); else asd.clear_session_flags(APPID_SESSION_LOGIN_SUCCEEDED); - } void AppIdDetector::add_payload(AppIdSession& asd, AppId payload_id) @@ -89,7 +88,8 @@ void AppIdDetector::add_payload(AppIdSession& asd, AppId payload_id) asd.payload.set_id(payload_id); } -void AppIdDetector::add_app(AppIdSession& asd, AppId service_id, AppId client_id, const char* version) +void AppIdDetector::add_app(AppIdSession& asd, AppId service_id, AppId client_id, + const char* version) { if ( version ) asd.client.set_version(version); @@ -126,3 +126,4 @@ const char* AppIdDetector::get_code_string(APPID_STATUS_CODE code) const } return "unknown code"; } + diff --git a/src/network_inspectors/appid/appid_discovery.cc b/src/network_inspectors/appid/appid_discovery.cc index 3f13f8e9e..de9db4472 100644 --- a/src/network_inspectors/appid/appid_discovery.cc +++ b/src/network_inspectors/appid/appid_discovery.cc @@ -51,7 +51,6 @@ using namespace snort; - bool do_tp_discovery(AppIdSession&, IpProtocol, Packet*, AppidSessionDirection&); AppIdDiscovery::AppIdDiscovery(AppIdInspector& ins) @@ -96,7 +95,6 @@ void AppIdDiscovery::release_plugins() delete &ClientDiscovery::get_instance(); } - void AppIdDiscovery::register_detector(const std::string& name, AppIdDetector* cd, IpProtocol proto) { // FIXIT-L - check for dup name? @@ -141,7 +139,8 @@ void AppIdDiscovery::do_application_discovery(Packet* p, AppIdInspector& inspect AppidSessionDirection direction = APP_ID_FROM_INITIATOR; AppIdSession* asd = (AppIdSession*)p->flow->get_flow_data(AppIdSession::inspector_id); - if ( !do_pre_discovery(p, &asd, inspector, protocol, direction) ) return; + if ( !do_pre_discovery(p, &asd, inspector, protocol, direction) ) + return; bool is_discovery_done = do_discovery(p, *asd, protocol, direction); @@ -355,7 +354,7 @@ static bool is_packet_ignored(AppIdSession* asd, Packet* p, AppidSessionDirectio } else if ( p->is_rebuilt() && !p->flow->is_proxied() ) { - // FIXIT-M: In snort2x, a rebuilt packet was ignored whether it had a session or not. + // FIXIT-M: In snort2x, a rebuilt packet was ignored whether it had a session or not. // Here, we are ignoring rebuilt packet only if it has a session. Why? if ( asd ) { @@ -364,12 +363,15 @@ static bool is_packet_ignored(AppIdSession* asd, Packet* p, AppidSessionDirectio { HttpPatternMatchers::get_instance()->get_http_offsets(p, hsession); if (appidDebug->is_active()) - LogMessage("AppIdDbg %s Offsets from rebuilt packet: uri: %u-%u cookie: %u-%u\n", + { + uint16_t uri_start, uri_end, cookie_start, cookie_end; + hsession->get_offset(REQ_URI_FID, uri_start, uri_end); + hsession->get_offset(REQ_COOKIE_FID, cookie_start, cookie_end); + LogMessage( + "AppIdDbg %s Offsets from rebuilt packet: uri: %u-%u cookie: %u-%u\n", appidDebug->get_debug_session(), - hsession->get_field_offset(REQ_URI_FID), - hsession->get_field_end_offset(REQ_URI_FID), - hsession->get_field_offset(REQ_COOKIE_FID), - hsession->get_field_end_offset(REQ_COOKIE_FID)); + uri_start, uri_end, cookie_start, cookie_end); + } } appid_stats.ignored_packets++; return true; @@ -509,7 +511,8 @@ static uint64_t is_session_monitored(AppIdSession& asd, const Packet* p, AppidSe return flow_flags; } -static uint64_t is_session_monitored(const Packet* p, AppidSessionDirection dir, AppIdInspector& inspector) +static uint64_t is_session_monitored(const Packet* p, AppidSessionDirection dir, + AppIdInspector& inspector) { uint64_t flags = 0; uint64_t flow_flags = APPID_SESSION_DISCOVER_APP; @@ -689,7 +692,8 @@ bool AppIdDiscovery::do_pre_discovery(Packet* p, AppIdSession** p_asd, AppIdInsp } if ( appidDebug->is_enabled() ) - appidDebug->activate(p->flow, asd, inspector.get_appid_config()->mod_config->log_all_sessions); + appidDebug->activate(p->flow, asd, + inspector.get_appid_config()->mod_config->log_all_sessions); if ( is_packet_ignored(asd, p, direction) ) return false; @@ -707,7 +711,8 @@ bool AppIdDiscovery::do_pre_discovery(Packet* p, AppIdSession** p_asd, AppIdInsp { asd->set_session_flags(APPID_SESSION_MID); if (appidDebug->is_active()) - LogMessage("AppIdDbg %s New AppId mid-stream session\n", appidDebug->get_debug_session()); + LogMessage("AppIdDbg %s New AppId mid-stream session\n", + appidDebug->get_debug_session()); } else if (appidDebug->is_active()) LogMessage("AppIdDbg %s New AppId session\n", appidDebug->get_debug_session()); @@ -746,9 +751,10 @@ bool AppIdDiscovery::do_pre_discovery(Packet* p, AppIdSession** p_asd, AppIdInsp { asd->set_session_flags(APPID_SESSION_OOO); if (appidDebug->is_active()) - LogMessage("AppIdDbg %s Packet out-of-order, %s%sflow\n", appidDebug->get_debug_session(), - (p->packet_flags & PKT_STREAM_ORDER_BAD)? "bad ":"not-ok ", - asd->get_session_flags(APPID_SESSION_MID)? "mid-stream ":""); + LogMessage("AppIdDbg %s Packet out-of-order, %s%sflow\n", + appidDebug->get_debug_session(), + (p->packet_flags & PKT_STREAM_ORDER_BAD) ? "bad " : "not-ok ", + asd->get_session_flags(APPID_SESSION_MID) ? "mid-stream " : ""); // Shut off service/client discoveries, since they skip not-ok data packets and // may keep failing on subsequent data packets causing performance degradation @@ -757,9 +763,11 @@ bool AppIdDiscovery::do_pre_discovery(Packet* p, AppIdSession** p_asd, AppIdInsp { asd->service_disco_state = APPID_DISCO_STATE_FINISHED; asd->client_disco_state = APPID_DISCO_STATE_FINISHED; - asd->set_session_flags(APPID_SESSION_SERVICE_DETECTED | APPID_SESSION_CLIENT_DETECTED); + asd->set_session_flags(APPID_SESSION_SERVICE_DETECTED | + APPID_SESSION_CLIENT_DETECTED); if (appidDebug->is_active()) - LogMessage("AppIdDbg %s stopped service/client discovery\n", appidDebug->get_debug_session()); + LogMessage("AppIdDbg %s stopped service/client discovery\n", + appidDebug->get_debug_session()); } } else @@ -830,14 +838,14 @@ bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd, IpProtocol proto case IpProtocol::TCP: if (asd.get_session_flags(APPID_SESSION_SYN_RST)) // TCP-specific exception break; - // fallthrough + // fallthrough case IpProtocol::UDP: // Both TCP and UDP need this test to be made // against only the p->src_port of the response. // For all other cases the port parameter is never checked. if (direction != APP_ID_FROM_RESPONDER) break; - // fallthrough + // fallthrough // All protocols other than TCP and UDP come straight here. default: { @@ -856,7 +864,7 @@ bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd, IpProtocol proto } // Length-based service detection - if ( (p->dsize > 0) and (asd.service.get_port_service_id() <= APP_ID_NONE) + if ( (p->dsize > 0)and (asd.service.get_port_service_id() <= APP_ID_NONE) and (asd.length_sequence.sequence_cnt < LENGTH_SEQUENCE_CNT_MAX) ) { uint8_t index = asd.length_sequence.sequence_cnt; diff --git a/src/network_inspectors/appid/appid_http_event_handler.cc b/src/network_inspectors/appid/appid_http_event_handler.cc index 73247541b..88e2f7ea3 100644 --- a/src/network_inspectors/appid/appid_http_event_handler.cc +++ b/src/network_inspectors/appid/appid_http_event_handler.cc @@ -62,13 +62,13 @@ void HttpEventHandler::handle(DataEvent& event, Flow* flow) header_start = http_event->get_host(header_length); if (header_length > 0) { - hsession->update_host(header_start, header_length); + hsession->set_field(REQ_HOST_FID, header_start, header_length); asd->scan_flags |= SCAN_HTTP_HOST_URL_FLAG; header_start = http_event->get_uri(header_length); if (header_length > 0) { - hsession->update_uri(header_start, header_length); + hsession->set_field(REQ_URI_FID, header_start, header_length); hsession->update_url(); } } @@ -76,16 +76,16 @@ void HttpEventHandler::handle(DataEvent& event, Flow* flow) header_start = http_event->get_user_agent(header_length); if (header_length > 0) { - hsession->update_useragent(header_start, header_length); + hsession->set_field(REQ_AGENT_FID, header_start, header_length); asd->scan_flags |= SCAN_HTTP_USER_AGENT_FLAG; } header_start = http_event->get_cookie(header_length); - hsession->update_cookie(header_start, header_length); + hsession->set_field(REQ_COOKIE_FID, header_start, header_length); header_start = http_event->get_referer(header_length); - hsession->update_referer(header_start, header_length); + hsession->set_field(REQ_REFERER_FID, header_start, header_length); header_start = http_event->get_x_working_with(header_length); - hsession->update_x_working_with(header_start, header_length); + hsession->set_field(MISC_XWW_FID, header_start, header_length); hsession->set_is_webdav(http_event->contains_webdav_method()); // FIXIT-M: Should we get request body (may be expensive to copy)? @@ -95,11 +95,11 @@ void HttpEventHandler::handle(DataEvent& event, Flow* flow) else // Response headers. { header_start = http_event->get_content_type(header_length); - hsession->update_content_type(header_start, header_length); + hsession->set_field(RSP_CONTENT_TYPE_FID, header_start, header_length); header_start = http_event->get_location(header_length); - hsession->update_location(header_start, header_length); + hsession->set_field(RSP_LOCATION_FID, header_start, header_length); header_start = http_event->get_server(header_length); - hsession->update_server(header_start, header_length); + hsession->set_field(MISC_SERVER_FID, header_start, header_length); int32_t responseCodeNum = http_event->get_response_code(); if (responseCodeNum > 0 && responseCodeNum < 700) @@ -108,7 +108,7 @@ void HttpEventHandler::handle(DataEvent& event, Flow* flow) char tmpstr[32]; ret = snprintf(tmpstr, sizeof(tmpstr), "%d", responseCodeNum); if ( ret < sizeof(tmpstr) ) - hsession->update_response_code(tmpstr); + hsession->set_field(MISC_RESP_CODE_FID, (const uint8_t*)tmpstr, ret); } // FIXIT-M: Get Location header data. @@ -121,7 +121,7 @@ void HttpEventHandler::handle(DataEvent& event, Flow* flow) header_start = http_event->get_via(header_length); if (header_length > 0) { - hsession->update_via(header_start, header_length); + hsession->set_field(MISC_VIA_FID, header_start, header_length); asd->scan_flags |= SCAN_HTTP_VIA_FLAG; } diff --git a/src/network_inspectors/appid/appid_http_session.cc b/src/network_inspectors/appid/appid_http_session.cc index aa69ef037..cd3b73b0b 100644 --- a/src/network_inspectors/appid/appid_http_session.cc +++ b/src/network_inspectors/appid/appid_http_session.cc @@ -39,7 +39,7 @@ using namespace snort; -static const char* httpFieldName[ MAX_HTTP_FIELD_ID ] = // for use in debug messages +static const char* httpFieldName[ NUM_HTTP_FIELDS ] = // for use in debug messages { "useragent", "host", @@ -55,56 +55,23 @@ static const char* httpFieldName[ MAX_HTTP_FIELD_ID ] = // for use in debug mess snort::ProfileStats httpPerfStats; AppIdHttpSession::AppIdHttpSession(AppIdSession& 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) + : asd(asd) { http_matchers = HttpPatternMatchers::get_instance(); + + for ( int i = 0; i < NUM_HTTP_FIELDS; i++) + { + meta_offset[i].first = 0; + meta_offset[i].second = 0; + } } 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; + + for ( int i = 0; i < NUM_METADATA_FIELDS; i++) + delete meta_data[i]; } void AppIdHttpSession::free_chp_matches(ChpMatchDescriptor& cmd, unsigned num_matches) @@ -157,7 +124,7 @@ int AppIdHttpSession::initial_chp_sweep(ChpMatchDescriptor& cmd) candidate has been chosen and it is pointed to by cah we will preserve any match sets until the calls to scanCHP() ***************************************************************/ - for (unsigned i = 0; i < MAX_HTTP_FIELD_ID; i++) + for (unsigned i = 0; i < NUM_HTTP_FIELDS; i++) { ptype_scan_counts[i] = cah->ptype_scan_counts[i]; ptype_req_counts[i] = cah->ptype_req_counts[i] + cah->ptype_rewrite_insert_used[i]; @@ -201,25 +168,20 @@ int AppIdHttpSession::initial_chp_sweep(ChpMatchDescriptor& cmd) void AppIdHttpSession::init_chp_match_descriptor(ChpMatchDescriptor& cmd) { - 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; + for (int i = REQ_AGENT_FID; i < NUM_HTTP_FIELDS; i++) + { + const std::string* field = meta_data[i]; + if (field) + { + cmd.buffer[i] = field->c_str(); + cmd.length[i] = field->size(); + } + else + { + cmd.buffer[i] = nullptr; + cmd.length[i] = 0; + } + } } void AppIdHttpSession::process_chp_buffers() @@ -232,10 +194,6 @@ void AppIdHttpSession::process_chp_buffers() if ( !chp_candidate ) { - // remove artifacts from previous matches before we start again. - for (auto f : http_fields) - f.field.clear(); - if ( !initial_chp_sweep(cmd) ) chp_finished = true; // this is a failure case. } @@ -245,7 +203,7 @@ void AppIdHttpSession::process_chp_buffers() char* user = nullptr; char* version = nullptr; - for (unsigned i = 0; i < MAX_HTTP_FIELD_ID; i++) + for (unsigned i = 0; i < NUM_HTTP_FIELDS; i++) { if ( !ptype_scan_counts[i] ) continue; @@ -300,7 +258,8 @@ void AppIdHttpSession::process_chp_buffers() } } - free_chp_matches(cmd, MAX_PATTERN_TYPE); + // pass the index of last chp_matcher, not the length the array! + free_chp_matches(cmd, NUM_HTTP_FIELDS-1); if ( !chp_candidate ) { @@ -355,7 +314,7 @@ void AppIdHttpSession::process_chp_buffers() asd.set_session_flags(APPID_SESSION_LOGIN_SUCCEEDED); } - for (unsigned i = 0; i < MAX_HTTP_FIELD_ID; i++) + for (unsigned i = 0; i < NUM_HTTP_FIELDS; i++) if ( cmd.chp_rewritten[i] ) { if (appidDebug->is_active()) @@ -363,7 +322,9 @@ void AppIdHttpSession::process_chp_buffers() appidDebug->get_debug_session(), httpFieldName[i], cmd.chp_rewritten[i]); - http_fields[i].field = cmd.chp_rewritten[i]; + set_field((HttpFieldIds)i, (const uint8_t*)cmd.chp_rewritten[i], + strlen(cmd.chp_rewritten[i])); + delete [] cmd.chp_rewritten[i]; cmd.chp_rewritten[i] = nullptr; } @@ -397,6 +358,11 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction) AppId payload_id = APP_ID_NONE; bool have_tp = asd.tpsession; + const std::string* useragent = meta_data[REQ_AGENT_FID]; + const std::string* host = meta_data[REQ_HOST_FID]; + const std::string* referer = meta_data[REQ_REFERER_FID]; + const std::string* uri = meta_data[REQ_URI_FID]; + // 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. @@ -410,7 +376,8 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction) if ( direction == APP_ID_FROM_RESPONDER && !asd.get_session_flags(APPID_SESSION_RESPONSE_CODE_CHECKED) ) { - if ( response_code ) + const std::string* response_code; + if ( (response_code = meta_data[MISC_RESP_CODE_FID]) != nullptr ) { asd.set_session_flags(APPID_SESSION_RESPONSE_CODE_CHECKED); constexpr auto RESPONSE_CODE_LENGTH = 3; @@ -459,6 +426,7 @@ 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? + const std::string* server = meta_data[MISC_SERVER_FID]; if ( (have_tp && (asd.scan_flags & SCAN_HTTP_VENDOR_FLAG) && server) || (!have_tp && server) ) { @@ -527,6 +495,7 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction) } /* Scan Via Header for squid */ + const std::string* via = meta_data[MISC_VIA_FID]; 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(), @@ -543,6 +512,7 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction) /* Scan X-Working-With HTTP header */ // FIXIT-M: Should we be checking the scan_flags even when // tp_appid_module is off? + const std::string* x_working_with = meta_data[MISC_XWW_FID]; if ( (have_tp && (asd.scan_flags & SCAN_HTTP_XWORKINGWITH_FLAG) && x_working_with) || (!have_tp && x_working_with)) { @@ -579,6 +549,7 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction) // Scan Content-Type Header for multimedia types and scan contents // FIXIT-M: Should we be checking the scan_flags even when // tp_appid_module is off? + const std::string* content_type = meta_data[RSP_CONTENT_TYPE_FID]; if ( (have_tp && (asd.scan_flags & SCAN_HTTP_CONTENT_TYPE_FLAG) && content_type && !asd.is_payload_appid_set()) || (!have_tp && !asd.is_payload_appid_set() && content_type) ) @@ -600,6 +571,7 @@ int AppIdHttpSession::process_http_packet(AppidSessionDirection direction) char* version = nullptr; char* my_host = host ? snort_strdup(host->c_str()) : nullptr; const char* refStr = referer ? referer->c_str() : nullptr; + const std::string* url = meta_data[MISC_URL_FID]; 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, @@ -761,283 +733,18 @@ void AppIdHttpSession::update_http_xff_address(struct XffFieldValue* xff_fields, #endif } -void AppIdHttpSession::set_url(const char* url) -{ - if ( this->url ) - delete this->url; - if ( url ) - this->url = new std::string(url); // FIXIT-M null terminated? - else - this->url = nullptr; -} - -void AppIdHttpSession::set_referer(char* referer) -{ - if ( this->referer ) - delete this->referer; - if ( referer ) - this->referer = new std::string(referer); - else - 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(); -} - -const char* AppIdHttpSession::get_new_cookie() -{ - return http_fields[REQ_COOKIE_FID].field.empty() - ? nullptr : http_fields[REQ_COOKIE_FID].field.c_str(); -} - -const char* AppIdHttpSession::get_new_field(HttpFieldIds fieldId) -{ - return http_fields[fieldId].field.empty() ? nullptr : http_fields[fieldId].field.c_str(); -} - -uint16_t AppIdHttpSession::get_field_offset(HttpFieldIds fid) -{ - return http_fields[fid].field.empty() ? 0 : http_fields[fid].start_offset; -} - -void AppIdHttpSession::set_field_offset(HttpFieldIds fid, uint16_t value) -{ - http_fields[fid].start_offset = value; -} - -uint16_t AppIdHttpSession::get_field_end_offset(HttpFieldIds fid) -{ - return http_fields[fid].field.empty() ? 0 : http_fields[fid].end_offset; -} - -void AppIdHttpSession::set_field_end_offset(HttpFieldIds fid, uint16_t value) -{ - http_fields[fid].end_offset = value; -} - -uint16_t AppIdHttpSession::get_uri_offset() -{ - return http_fields[REQ_URI_FID].start_offset; -} - -uint16_t AppIdHttpSession::get_uri_end_offset() -{ - return http_fields[REQ_URI_FID].end_offset; -} - -uint16_t AppIdHttpSession::get_cookie_offset() -{ - return http_fields[REQ_COOKIE_FID].start_offset; -} - -uint16_t AppIdHttpSession::get_cookie_end_offset() -{ - return http_fields[REQ_COOKIE_FID].end_offset; -} - -void AppIdHttpSession::update_host(const std::string* new_host) -{ - if (host) - delete host; - host = new_host; -} - -void AppIdHttpSession::update_uri(const std::string* new_uri) -{ - if (uri) - delete uri; - uri = new_uri; -} - void AppIdHttpSession::update_url() { + const std::string* host = meta_data[REQ_HOST_FID]; + const std::string* uri = meta_data[REQ_URI_FID]; if (host and uri) { - if (url) - delete url; - url = new std::string(std::string("http://") + *host + *uri); + if (meta_data[MISC_URL_FID]) + delete meta_data[MISC_URL_FID]; + meta_data[MISC_URL_FID] = 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) -{ - 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) -{ - 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) -{ - if ( referer ) - delete referer; - if ( new_referer and len ) referer = new std::string((const char*)new_referer, len); - else referer = nullptr; -} - -void AppIdHttpSession::update_x_working_with(const uint8_t* new_xww, int32_t 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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() { memset(ptype_scan_counts, 0, sizeof(ptype_scan_counts)); @@ -1045,75 +752,10 @@ void AppIdHttpSession::reset_ptype_scan_counts() void AppIdHttpSession::clear_all_fields() { - if (host) - { - delete host; - host = nullptr; - } - if (url) - { - delete url; - url = nullptr; - } - if (uri) - { - delete uri; - uri = nullptr; - } - if (referer) - { - delete referer; - referer = nullptr; - } - if (useragent) - { - delete useragent; - useragent = nullptr; - } - if (via) - { - delete via; - via = nullptr; - } - if (cookie) - { - delete cookie; - cookie = nullptr; - } - if (body) - { - delete body; - body = nullptr; - } - if (response_code) - { - delete response_code; - response_code = nullptr; - } - if (content_type) - { - delete content_type; - content_type = nullptr; - } - if (location) - { - delete location; - location = nullptr; - } - if (req_body) - { - delete req_body; - req_body = nullptr; - } - if (server) - { - delete server; - server = nullptr; - } - if (x_working_with) + for ( int i = 0; i < NUM_METADATA_FIELDS; i++) { - delete x_working_with; - x_working_with = nullptr; + delete meta_data[i]; + meta_data[i] = nullptr; } if (xff_addr) { diff --git a/src/network_inspectors/appid/appid_http_session.h b/src/network_inspectors/appid/appid_http_session.h index 44bfcc42e..70b5bb59b 100644 --- a/src/network_inspectors/appid/appid_http_session.h +++ b/src/network_inspectors/appid/appid_http_session.h @@ -23,6 +23,7 @@ #define APPID_HTTP_SESSION_H #include +#include #include "flow/flow.h" #include "sfip/sf_ip.h" @@ -36,8 +37,14 @@ class ChpMatchDescriptor; class HttpPatternMatchers; // These values are used in Lua code as raw numbers. Do NOT reassign new values. +// 0 - 8 (inclusive) : used heavily in CHP code. DO NOT CHANGE. +// 9 - NUM_METADATA_FIELDS : extra metadata buffers, beyond CHP. +// NUM_METADATA_FIELDS : must always follow the last metadata FID. +// NUM_HTTP_FIELDS : number of CHP filds, so always RSP_BODY_FID + 1 enum HttpFieldIds : uint8_t { + // 0-8: CHP fields. DO NOT CHANGE + // Request-side headers REQ_AGENT_FID, // 0 REQ_HOST_FID, // 1 @@ -49,9 +56,20 @@ enum HttpFieldIds : uint8_t RSP_CONTENT_TYPE_FID, // 6 RSP_LOCATION_FID, // 7 RSP_BODY_FID, // 8 - MAX_HTTP_FIELD_ID, // 9 - MAX_PATTERN_TYPE = RSP_BODY_FID, - MAX_KEY_PATTERN = REQ_URI_FID, + + // extra (non-CHP) metadata fields. + MISC_VIA_FID, // 9 + MISC_RESP_CODE_FID, // 10 + MISC_SERVER_FID, // 11 + MISC_XWW_FID, // 12 + MISC_URL_FID, // 13 + + // Total number of metadata fields, always first after actual FIDs. + NUM_METADATA_FIELDS, // 14 + + // Number of CHP fields, always 1 past RSP_BODY_FIELD + NUM_HTTP_FIELDS = MISC_VIA_FID, + MAX_KEY_PATTERN = REQ_URI_FID, // DO NOT CHANGE, used in CHP }; #define RESPONSE_CODE_PACKET_THRESHHOLD 0 @@ -61,125 +79,61 @@ enum HttpFieldIds : uint8_t #define APP_TYPE_CLIENT 0x2 #define APP_TYPE_PAYLOAD 0x4 -struct HttpField -{ - std::string field; - uint16_t start_offset = 0; - uint16_t end_offset = 0; -}; - class AppIdHttpSession { public: + typedef std::pair pair_t; + AppIdHttpSession(AppIdSession&); virtual ~AppIdHttpSession(); int process_http_packet(AppidSessionDirection direction); void update_http_xff_address(struct XffFieldValue* xff_fields, uint32_t numXffFields); - const char* get_user_agent() - { return useragent ? useragent->c_str() : nullptr; } - - const char* get_host() - { return host ? host->c_str() : nullptr; } - - const char* get_url() - { return url ? url->c_str() : nullptr; } - - void set_url(const char* url = nullptr); - - const char* get_uri() - { return uri ? uri->c_str() : nullptr; } - - const char* get_via() - { return via ? via->c_str() : nullptr; } - - const char* get_referer() - { return referer ? referer->c_str() : nullptr; } - - void set_referer(char* referer = nullptr); - - const char* get_cookie() - { return cookie ? cookie->c_str() : nullptr; } - - const char* get_response_code() - { return response_code ? response_code->c_str() : nullptr; } - - const char* get_content_type() - { return content_type ? content_type->c_str() : nullptr; } - - const char* get_location() - { return location ? location->c_str() : nullptr; } - - const char* get_req_body() - { return req_body ? req_body->c_str() : nullptr; } - - const char* get_server() - { return server ? server->c_str() : nullptr; } - - const char* get_body() - { return body ? body->c_str() : nullptr; } - - const char* get_x_working_with() - { return x_working_with ? x_working_with->c_str() : nullptr; } - - const char* get_new_url(); - const char* get_new_cookie(); - const char* get_new_field(HttpFieldIds fieldId); - uint16_t get_field_offset(HttpFieldIds fid); - void set_field_offset(HttpFieldIds fid, uint16_t value); - uint16_t get_field_end_offset(HttpFieldIds fid); - void set_field_end_offset(HttpFieldIds fid, uint16_t value); - uint16_t get_uri_offset(); - uint16_t get_uri_end_offset(); - uint16_t get_cookie_offset(); - uint16_t get_cookie_end_offset(); + void update_url(); 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_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); - void update_x_working_with(const uint8_t* new_xww, int32_t len); - void update_content_type(const uint8_t* new_content_type, int32_t len); - void update_location(const uint8_t* new_location, int32_t len); - void update_server(const uint8_t* new_server, int32_t len); - void update_via(const uint8_t* new_via, int32_t len); - 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); + const std::string* get_field(HttpFieldIds id) + { return meta_data[id]; } + + const char* get_cfield(HttpFieldIds id) + { return meta_data[id] != nullptr ? meta_data[id]->c_str() : nullptr; } + + void set_field(HttpFieldIds id, const std::string* str) + { + delete meta_data[id]; + meta_data[id] = str; + } + + void set_field(HttpFieldIds id, const uint8_t* str, int32_t len) + { + delete meta_data[id]; + meta_data[id] = str and len ? new std::string((const char*)str, len) : nullptr; + } + + bool get_offset(int id, uint16_t& start, uint16_t& end) + { + if ( REQ_AGENT_FID <= id and id < NUM_HTTP_FIELDS ) + { + start = meta_offset[id].first; + end = meta_offset[id].second; + return true; + } + return false; + } + + bool set_offset(int id, uint16_t start, uint16_t end) + { + if ( REQ_AGENT_FID <= id and id < NUM_HTTP_FIELDS ) + { + meta_offset[id].first = start; + meta_offset[id].second = end; + return true; + } + return false; + } void set_is_webdav(bool webdav) { is_webdav = webdav; } @@ -227,6 +181,7 @@ public: void clear_all_fields(); protected: + void init_chp_match_descriptor(ChpMatchDescriptor& cmd); int initial_chp_sweep(ChpMatchDescriptor&); void process_chp_buffers(); @@ -235,20 +190,17 @@ protected: HttpPatternMatchers* http_matchers = nullptr; AppIdSession& asd; - 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; + + // FIXIT-M the meta data buffers in this array are only set from + // third party (tp_appid_utils.cc) and from http inspect + // (appid_http_event_handler.cc). The set_field functions should + // only be accessible to those functions/classes, but the process + // functions in tp_appid_utils.cc are static. Thus the public + // set_field() functions in AppIdHttpSession. We do need set functions + // for this array, as old pointers need to be deleted upon set(). + const std::string* meta_data[NUM_METADATA_FIELDS] = { 0 }; + pair_t meta_offset[NUM_HTTP_FIELDS]; + bool is_webdav = false; bool chp_finished = false; AppId chp_candidate = APP_ID_NONE; @@ -263,9 +215,8 @@ protected: snort::SfIp* xff_addr = nullptr; 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[NUM_HTTP_FIELDS] = { 0 }; + int ptype_scan_counts[NUM_HTTP_FIELDS] = { 0 }; #if RESPONSE_CODE_PACKET_THRESHHOLD unsigned response_code_packets = 0; #endif diff --git a/src/network_inspectors/appid/appid_session.cc b/src/network_inspectors/appid/appid_session.cc index 5bcd44a18..ec425986f 100644 --- a/src/network_inspectors/appid/appid_session.cc +++ b/src/network_inspectors/appid/appid_session.cc @@ -224,7 +224,7 @@ void AppIdSession::reinit_session_data() referred_payload_app_id = tp_payload_app_id = APP_ID_NONE; clear_session_flags(APPID_SESSION_CONTINUE); if ( hsession ) - hsession->set_url(nullptr); + hsession->set_field(MISC_URL_FID, nullptr); } //service @@ -456,16 +456,16 @@ void AppIdSession::examine_rtmp_metadata() if ( !hsession ) hsession = new AppIdHttpSession(*this); - if ( const char* url = hsession->get_url() ) + if ( const char* url = hsession->get_cfield(MISC_URL_FID) ) { HttpPatternMatchers* http_matchers = HttpPatternMatchers::get_instance(); - + const char* referer = hsession->get_cfield(REQ_REFERER_FID); if ( ( ( http_matchers->get_appid_from_url(nullptr, url, &version, - hsession->get_referer(), &client_id, &service_id, + referer, &client_id, &service_id, &payload_id, &referred_payload_id, true) ) || ( http_matchers->get_appid_from_url(nullptr, url, &version, - hsession->get_referer(), &client_id, &service_id, + referer, &client_id, &service_id, &payload_id, &referred_payload_id, false) ) ) ) { /* do not overwrite a previously-set client or service */ @@ -664,7 +664,7 @@ void AppIdSession::stop_rna_service_inspection(Packet* p, AppidSessionDirection service_disco_state = APPID_DISCO_STATE_FINISHED; if ( (is_tp_appid_available() || get_session_flags(APPID_SESSION_NO_TPI) ) - and payload.get_id() == APP_ID_NONE ) + and payload.get_id() == APP_ID_NONE ) payload.set_id(APP_ID_UNKNOWN); set_session_flags(APPID_SESSION_SERVICE_DETECTED); @@ -867,8 +867,9 @@ void AppIdSession::clear_http_flags() void AppIdSession::clear_http_data() { - if (!hsession) return; - hsession->clear_all_fields(); + if (!hsession) + return; + hsession->clear_all_fields(); } AppIdHttpSession* AppIdSession::get_http_session() @@ -906,16 +907,15 @@ bool AppIdSession::is_tp_processing_done() const { #ifdef ENABLE_APPID_THIRD_PARTY if ( TPLibHandler::have_tp() && - !get_session_flags(APPID_SESSION_NO_TPI) && - (!is_tp_appid_done() || - get_session_flags(APPID_SESSION_APP_REINSPECT | APPID_SESSION_APP_REINSPECT_SSL))) + !get_session_flags(APPID_SESSION_NO_TPI) && + (!is_tp_appid_done() || + get_session_flags(APPID_SESSION_APP_REINSPECT | APPID_SESSION_APP_REINSPECT_SSL))) return false; #endif return true; } - bool AppIdSession::is_tp_appid_available() const { #ifdef ENABLE_APPID_THIRD_PARTY @@ -935,3 +935,4 @@ bool AppIdSession::is_tp_appid_available() const return true; } + diff --git a/src/network_inspectors/appid/detector_plugins/http_url_patterns.cc b/src/network_inspectors/appid/detector_plugins/http_url_patterns.cc index 2545027aa..bd8e9e9c2 100644 --- a/src/network_inspectors/appid/detector_plugins/http_url_patterns.cc +++ b/src/network_inspectors/appid/detector_plugins/http_url_patterns.cc @@ -23,6 +23,8 @@ #include "config.h" #endif +#include + #include "http_url_patterns.h" #include "app_info_table.h" @@ -35,6 +37,8 @@ using namespace snort; +typedef AppIdHttpSession::pair_t pair_t; + static const char* const FP_OPERATION_AND = "%&%"; static const unsigned PATTERN_PART_MAX = 10; @@ -152,124 +156,127 @@ struct MatchedPatterns static DetectorHTTPPatterns static_content_type_patterns = { { SINGLE, 0, APP_ID_QUICKTIME, 0, - APP_ID_QUICKTIME, sizeof(QUICKTIME_BANNER)-1, (const uint8_t*)QUICKTIME_BANNER }, + APP_ID_QUICKTIME, sizeof(QUICKTIME_BANNER)-1, (const uint8_t*)QUICKTIME_BANNER }, { SINGLE, 0, APP_ID_MPEG, 0, - APP_ID_MPEG, sizeof(MPEG_BANNER)-1, (const uint8_t*)MPEG_BANNER }, + APP_ID_MPEG, sizeof(MPEG_BANNER)-1, (const uint8_t*)MPEG_BANNER }, { SINGLE, 0, APP_ID_MPEG, 0, - APP_ID_MPEG, sizeof(MPA_BANNER)-1, (const uint8_t*)MPA_BANNER }, + APP_ID_MPEG, sizeof(MPA_BANNER)-1, (const uint8_t*)MPA_BANNER }, { SINGLE, 0, APP_ID_MPEG, 0, - APP_ID_MPEG, sizeof(MP4A_BANNER)-1, (const uint8_t*)MP4A_BANNER }, + APP_ID_MPEG, sizeof(MP4A_BANNER)-1, (const uint8_t*)MP4A_BANNER }, { SINGLE, 0, APP_ID_MPEG, 0, - APP_ID_MPEG, sizeof(ROBUST_MPA_BANNER)-1, (const uint8_t*)ROBUST_MPA_BANNER }, + APP_ID_MPEG, sizeof(ROBUST_MPA_BANNER)-1, (const uint8_t*)ROBUST_MPA_BANNER }, { SINGLE, 0, APP_ID_MPEG, 0, - APP_ID_MPEG, sizeof(XSCPLS_BANNER)-1, (const uint8_t*)XSCPLS_BANNER }, + APP_ID_MPEG, sizeof(XSCPLS_BANNER)-1, (const uint8_t*)XSCPLS_BANNER }, { SINGLE, 0, APP_ID_SHOCKWAVE, 0, - APP_ID_SHOCKWAVE, sizeof(SHOCKWAVE_BANNER)-1, (const uint8_t*)SHOCKWAVE_BANNER }, + APP_ID_SHOCKWAVE, sizeof(SHOCKWAVE_BANNER)-1, (const uint8_t*)SHOCKWAVE_BANNER }, { SINGLE, 0, APP_ID_RSS, 0, - APP_ID_RSS, sizeof(RSS_BANNER)-1, (const uint8_t*)RSS_BANNER }, + APP_ID_RSS, sizeof(RSS_BANNER)-1, (const uint8_t*)RSS_BANNER }, { SINGLE, 0, APP_ID_ATOM, 0, - APP_ID_ATOM, sizeof(ATOM_BANNER)-1, (const uint8_t*)ATOM_BANNER }, + APP_ID_ATOM, sizeof(ATOM_BANNER)-1, (const uint8_t*)ATOM_BANNER }, { SINGLE, 0, APP_ID_MP4, 0, - APP_ID_MP4, sizeof(MP4_BANNER)-1, (const uint8_t*)MP4_BANNER }, + APP_ID_MP4, sizeof(MP4_BANNER)-1, (const uint8_t*)MP4_BANNER }, { SINGLE, 0, APP_ID_WMV, 0, - APP_ID_WMV, sizeof(WMV_BANNER)-1, (const uint8_t*)WMV_BANNER }, + APP_ID_WMV, sizeof(WMV_BANNER)-1, (const uint8_t*)WMV_BANNER }, { SINGLE, 0, APP_ID_WMA, 0, - APP_ID_WMA, sizeof(WMA_BANNER)-1, (const uint8_t*)WMA_BANNER }, + APP_ID_WMA, sizeof(WMA_BANNER)-1, (const uint8_t*)WMA_BANNER }, { SINGLE, 0, APP_ID_WAV, 0, - APP_ID_WAV, sizeof(WAV_BANNER)-1, (const uint8_t*)WAV_BANNER }, + APP_ID_WAV, sizeof(WAV_BANNER)-1, (const uint8_t*)WAV_BANNER }, { SINGLE, 0, APP_ID_WAV, 0, - APP_ID_WAV, sizeof(X_WAV_BANNER)-1, (const uint8_t*)X_WAV_BANNER }, + APP_ID_WAV, sizeof(X_WAV_BANNER)-1, (const uint8_t*)X_WAV_BANNER }, { SINGLE, 0, APP_ID_WAV, 0, - APP_ID_WAV, sizeof(VND_WAV_BANNER)-1, (const uint8_t*)VND_WAV_BANNER }, + APP_ID_WAV, sizeof(VND_WAV_BANNER)-1, (const uint8_t*)VND_WAV_BANNER }, { SINGLE, 0, APP_ID_FLASH_VIDEO, 0, - APP_ID_FLASH_VIDEO, sizeof(FLV_BANNER)-1, (const uint8_t*)FLV_BANNER }, + APP_ID_FLASH_VIDEO, sizeof(FLV_BANNER)-1, (const uint8_t*)FLV_BANNER }, { SINGLE, 0, APP_ID_FLASH_VIDEO, 0, - APP_ID_FLASH_VIDEO, sizeof(M4V_BANNER)-1, (const uint8_t*)M4V_BANNER }, + APP_ID_FLASH_VIDEO, sizeof(M4V_BANNER)-1, (const uint8_t*)M4V_BANNER }, { SINGLE, 0, APP_ID_FLASH_VIDEO, 0, - APP_ID_FLASH_VIDEO, sizeof(GPP_BANNER)-1, (const uint8_t*)GPP_BANNER }, + APP_ID_FLASH_VIDEO, sizeof(GPP_BANNER)-1, (const uint8_t*)GPP_BANNER }, { SINGLE, 0, APP_ID_GENERIC, 0, - APP_ID_GENERIC, sizeof(VIDEO_BANNER)-1, (const uint8_t*)VIDEO_BANNER }, + APP_ID_GENERIC, sizeof(VIDEO_BANNER)-1, (const uint8_t*)VIDEO_BANNER }, { SINGLE, 0, APP_ID_GENERIC, 0, - APP_ID_GENERIC, sizeof(AUDIO_BANNER)-1, (const uint8_t*)AUDIO_BANNER }, + APP_ID_GENERIC, sizeof(AUDIO_BANNER)-1, (const uint8_t*)AUDIO_BANNER }, }; static DetectorHTTPPatterns static_via_http_detector_patterns = { - { SINGLE, APP_ID_SQUID, 0, 0, APP_ID_SQUID, SQUID_PATTERN_SIZE, (const uint8_t*)SQUID_PATTERN }, + { SINGLE, APP_ID_SQUID, 0, 0, APP_ID_SQUID, SQUID_PATTERN_SIZE, + (const uint8_t*)SQUID_PATTERN }, }; static DetectorHTTPPatterns static_http_host_payload_patterns = { { SINGLE, 0, 0, APP_ID_MYSPACE, - APP_ID_MYSPACE, MYSPACE_PATTERN_SIZE, (const uint8_t*)MYSPACE_PATTERN }, + APP_ID_MYSPACE, MYSPACE_PATTERN_SIZE, (const uint8_t*)MYSPACE_PATTERN }, { SINGLE, 0, 0, APP_ID_GMAIL, - APP_ID_GMAIL, GMAIL_PATTERN_SIZE, (const uint8_t*)GMAIL_PATTERN }, + APP_ID_GMAIL, GMAIL_PATTERN_SIZE, (const uint8_t*)GMAIL_PATTERN }, { SINGLE, 0, 0, APP_ID_GMAIL, - APP_ID_GMAIL, GMAIL_PATTERN2_SIZE, (const uint8_t*)GMAIL_PATTERN2 }, + APP_ID_GMAIL, GMAIL_PATTERN2_SIZE, (const uint8_t*)GMAIL_PATTERN2 }, { SINGLE, 0, 0, APP_ID_AOL_EMAIL, - APP_ID_AOL_EMAIL, AOL_PATTERN_SIZE, (const uint8_t*)AOL_PATTERN }, + APP_ID_AOL_EMAIL, AOL_PATTERN_SIZE, (const uint8_t*)AOL_PATTERN }, { SINGLE, 0, 0, APP_ID_MICROSOFT_UPDATE, - APP_ID_MICROSOFT_UPDATE, MSUP_PATTERN_SIZE, (const uint8_t*)MSUP_PATTERN }, + APP_ID_MICROSOFT_UPDATE, MSUP_PATTERN_SIZE, (const uint8_t*)MSUP_PATTERN }, { SINGLE, 0, 0, APP_ID_MICROSOFT_UPDATE, - APP_ID_MICROSOFT_UPDATE,MSUP_PATTERN2_SIZE, (const uint8_t*)MSUP_PATTERN2 }, + APP_ID_MICROSOFT_UPDATE,MSUP_PATTERN2_SIZE, (const uint8_t*)MSUP_PATTERN2 }, { SINGLE, 0, 0, APP_ID_YAHOOMAIL, - APP_ID_YAHOOMAIL, YAHOO_MAIL_PATTERN_SIZE, (const uint8_t*)YAHOO_MAIL_PATTERN }, + APP_ID_YAHOOMAIL, YAHOO_MAIL_PATTERN_SIZE, (const uint8_t*)YAHOO_MAIL_PATTERN }, { SINGLE, 0, 0, APP_ID_YAHOO_TOOLBAR, - APP_ID_YAHOO_TOOLBAR, YAHOO_TB_PATTERN_SIZE, (const uint8_t*)YAHOO_TB_PATTERN }, + APP_ID_YAHOO_TOOLBAR, YAHOO_TB_PATTERN_SIZE, (const uint8_t*)YAHOO_TB_PATTERN }, { SINGLE, 0, 0, APP_ID_ADOBE_UPDATE, - APP_ID_ADOBE_UPDATE, ADOBE_UP_PATTERN_SIZE, (const uint8_t*)ADOBE_UP_PATTERN }, + APP_ID_ADOBE_UPDATE, ADOBE_UP_PATTERN_SIZE, (const uint8_t*)ADOBE_UP_PATTERN }, { SINGLE, 0, 0, APP_ID_HOTMAIL, - APP_ID_HOTMAIL, HOTMAIL_PATTERN1_SIZE, (const uint8_t*)HOTMAIL_PATTERN1 }, + APP_ID_HOTMAIL, HOTMAIL_PATTERN1_SIZE, (const uint8_t*)HOTMAIL_PATTERN1 }, { SINGLE, 0, 0, APP_ID_HOTMAIL, - APP_ID_HOTMAIL, HOTMAIL_PATTERN2_SIZE, (const uint8_t*)HOTMAIL_PATTERN2 }, + APP_ID_HOTMAIL, HOTMAIL_PATTERN2_SIZE, (const uint8_t*)HOTMAIL_PATTERN2 }, { SINGLE, 0, 0, APP_ID_GOOGLE_TOOLBAR, - APP_ID_GOOGLE_TOOLBAR, GOOGLE_TB_PATTERN_SIZE, (const uint8_t*)GOOGLE_TB_PATTERN }, + APP_ID_GOOGLE_TOOLBAR, GOOGLE_TB_PATTERN_SIZE, (const uint8_t*)GOOGLE_TB_PATTERN }, }; static DetectorHTTPPatterns static_client_agent_patterns = { { USER_AGENT_HEADER, 0, FAKE_VERSION_APP_ID, 0, - FAKE_VERSION_APP_ID, VERSION_PATTERN_SIZE, (const uint8_t*)VERSION_PATTERN }, + FAKE_VERSION_APP_ID, VERSION_PATTERN_SIZE, (const uint8_t*)VERSION_PATTERN }, { USER_AGENT_HEADER, APP_ID_HTTP, APP_ID_INTERNET_EXPLORER, 0, - APP_ID_INTERNET_EXPLORER, sizeof(MSIE_PATTERN)-1, (const uint8_t*)MSIE_PATTERN }, + APP_ID_INTERNET_EXPLORER, sizeof(MSIE_PATTERN)-1, (const uint8_t*)MSIE_PATTERN }, { USER_AGENT_HEADER, APP_ID_HTTP, APP_ID_KONQUEROR, 0, - APP_ID_KONQUEROR, sizeof(KONQUEROR_PATTERN)-1, (const uint8_t*)KONQUEROR_PATTERN }, + APP_ID_KONQUEROR, sizeof(KONQUEROR_PATTERN)-1, (const uint8_t*)KONQUEROR_PATTERN }, { USER_AGENT_HEADER, APP_ID_SKYPE_AUTH, APP_ID_SKYPE, 0, - APP_ID_SKYPE, sizeof(SKYPE_PATTERN)-1, (const uint8_t*)SKYPE_PATTERN }, + APP_ID_SKYPE, sizeof(SKYPE_PATTERN)-1, (const uint8_t*)SKYPE_PATTERN }, { USER_AGENT_HEADER, APP_ID_BITTORRENT, APP_ID_BITTORRENT, 0, - APP_ID_BITTORRENT, sizeof(BITTORRENT_PATTERN)-1, (const uint8_t*)BITTORRENT_PATTERN }, + APP_ID_BITTORRENT, sizeof(BITTORRENT_PATTERN)-1, (const uint8_t*)BITTORRENT_PATTERN }, { USER_AGENT_HEADER, APP_ID_HTTP, APP_ID_FIREFOX, 0, - APP_ID_FIREFOX, sizeof(FIREFOX_PATTERN)-1, (const uint8_t*)FIREFOX_PATTERN }, + APP_ID_FIREFOX, sizeof(FIREFOX_PATTERN)-1, (const uint8_t*)FIREFOX_PATTERN }, { USER_AGENT_HEADER, APP_ID_HTTP, APP_ID_WGET, 0, - APP_ID_WGET, sizeof(WGET_PATTERN)-1, (const uint8_t*)WGET_PATTERN }, + APP_ID_WGET, sizeof(WGET_PATTERN)-1, (const uint8_t*)WGET_PATTERN }, { USER_AGENT_HEADER, APP_ID_HTTP, APP_ID_CURL, 0, - APP_ID_CURL, sizeof(CURL_PATTERN)-1, (const uint8_t*)CURL_PATTERN }, + APP_ID_CURL, sizeof(CURL_PATTERN)-1, (const uint8_t*)CURL_PATTERN }, { USER_AGENT_HEADER, APP_ID_HTTP, APP_ID_GOOGLE_DESKTOP, 0, - APP_ID_GOOGLE_DESKTOP, sizeof(GOOGLE_DESKTOP_PATTERN)-1, (const uint8_t*)GOOGLE_DESKTOP_PATTERN }, + APP_ID_GOOGLE_DESKTOP, sizeof(GOOGLE_DESKTOP_PATTERN)-1, + (const uint8_t*)GOOGLE_DESKTOP_PATTERN }, { USER_AGENT_HEADER, APP_ID_HTTP, APP_ID_PICASA, 0, - APP_ID_PICASA, sizeof(PICASA_PATTERN)-1, (const uint8_t*)PICASA_PATTERN }, + APP_ID_PICASA, sizeof(PICASA_PATTERN)-1, (const uint8_t*)PICASA_PATTERN }, { USER_AGENT_HEADER, APP_ID_HTTP, APP_ID_SAFARI, 0, - APP_ID_SAFARI, sizeof(SAFARI_PATTERN)-1, (const uint8_t*)SAFARI_PATTERN }, + APP_ID_SAFARI, sizeof(SAFARI_PATTERN)-1, (const uint8_t*)SAFARI_PATTERN }, { USER_AGENT_HEADER, APP_ID_HTTP, APP_ID_OPERA, 0, - APP_ID_OPERA, sizeof(OPERA_PATTERN)-1, (const uint8_t*)OPERA_PATTERN }, + APP_ID_OPERA, sizeof(OPERA_PATTERN)-1, (const uint8_t*)OPERA_PATTERN }, { USER_AGENT_HEADER, APP_ID_HTTP, APP_ID_CHROME, 0, - APP_ID_CHROME, sizeof(CHROME_PATTERN)-1, (const uint8_t*)CHROME_PATTERN }, + APP_ID_CHROME, sizeof(CHROME_PATTERN)-1, (const uint8_t*)CHROME_PATTERN }, { USER_AGENT_HEADER, APP_ID_HTTP, APP_ID_SAFARI_MOBILE_DUMMY, 0, - APP_ID_SAFARI_MOBILE_DUMMY, sizeof(MOBILE_PATTERN)-1, (const uint8_t*)MOBILE_PATTERN }, + APP_ID_SAFARI_MOBILE_DUMMY, sizeof(MOBILE_PATTERN)-1, (const uint8_t*)MOBILE_PATTERN }, { USER_AGENT_HEADER, APP_ID_HTTP, APP_ID_BLACKBERRY_BROWSER, 0, - APP_ID_BLACKBERRY_BROWSER, sizeof(BLACKBERRY_PATTERN)-1, (const uint8_t*)BLACKBERRY_PATTERN }, + APP_ID_BLACKBERRY_BROWSER, sizeof(BLACKBERRY_PATTERN)-1, + (const uint8_t*)BLACKBERRY_PATTERN }, { USER_AGENT_HEADER, APP_ID_HTTP, APP_ID_ANDROID_BROWSER, 0, - APP_ID_ANDROID_BROWSER, sizeof(ANDROID_PATTERN)-1, (const uint8_t*)ANDROID_PATTERN }, + APP_ID_ANDROID_BROWSER, sizeof(ANDROID_PATTERN)-1, (const uint8_t*)ANDROID_PATTERN }, { USER_AGENT_HEADER, APP_ID_HTTP, APP_ID_WINDOWS_MEDIA_PLAYER, 0, - APP_ID_WINDOWS_MEDIA_PLAYER, sizeof(MEDIAPLAYER_PATTERN)-1, (const uint8_t*)MEDIAPLAYER_PATTERN }, + APP_ID_WINDOWS_MEDIA_PLAYER, sizeof(MEDIAPLAYER_PATTERN)-1, + (const uint8_t*)MEDIAPLAYER_PATTERN }, { USER_AGENT_HEADER, APP_ID_HTTP, APP_ID_APPLE_EMAIL, 0, - APP_ID_APPLE_EMAIL, sizeof(APPLE_EMAIL_PATTERN)-1, (const uint8_t*)APPLE_EMAIL_PATTERN }, + APP_ID_APPLE_EMAIL, sizeof(APPLE_EMAIL_PATTERN)-1, (const uint8_t*)APPLE_EMAIL_PATTERN }, }; static int match_query_elements(tMlpPattern* packetData, tMlpPattern* userPattern, char* appVersion, size_t appVersionSize) { - if (appVersion == nullptr) return 0; @@ -366,11 +373,11 @@ HttpPatternMatchers::~HttpPatternMatchers() delete field_matcher; - for (size_t i = 0; i <= MAX_PATTERN_TYPE; i++) + for (size_t i = 0; i < NUM_HTTP_FIELDS; i++) delete chp_matchers[i]; for (auto* pattern : host_url_patterns) - delete pattern; + delete pattern; host_url_patterns.clear(); if ( host_url_matcher ) mlmpDestroy(host_url_matcher); @@ -475,11 +482,12 @@ void HttpPatternMatchers::insert_app_url_pattern(DetectorAppUrlPattern* pattern) HttpPatternMatchers::insert_url_pattern(pattern); } -int HttpPatternMatchers::add_mlmp_pattern(tMlmpTree* matcher, DetectorHTTPPattern& pattern ) +int HttpPatternMatchers::add_mlmp_pattern(tMlmpTree* matcher, DetectorHTTPPattern& pattern) { assert(pattern.pattern); - HostUrlDetectorPattern* detector = new HostUrlDetectorPattern(pattern.pattern, pattern.pattern_size); + HostUrlDetectorPattern* detector = new HostUrlDetectorPattern(pattern.pattern, + pattern.pattern_size); host_url_patterns.push_back(detector); detector->payload_id = pattern.payload_id; @@ -581,7 +589,7 @@ static int chp_pattern_match(void* id, void*, int match_end_pos, void* data, voi ChpMatchDescriptor* cmd = (ChpMatchDescriptor*)data; CHPAction* target = (CHPAction*)id; - cmd->chp_matches[cmd->cur_ptype].push_back( { target, match_end_pos - target->psize } ); + cmd->chp_matches[cmd->cur_ptype].push_back({ target, match_end_pos - target->psize }); return 0; } @@ -595,7 +603,7 @@ static inline void chp_add_candidate_to_tally(CHPMatchTally& match_tally, CHPApp } match_tally.push_back({ chpapp, chpapp->key_pattern_length_sum, - chpapp->key_pattern_count - 1 }); + chpapp->key_pattern_count - 1 }); } // In addition to creating the linked list of matching actions this function will @@ -667,14 +675,14 @@ int HttpPatternMatchers::process_host_patterns(DetectorHTTPPatterns patterns) int HttpPatternMatchers::process_chp_list(CHPListElement* chplist) { - for (size_t i = 0; i <= MAX_PATTERN_TYPE; i++) + for (size_t i = 0; i < NUM_HTTP_FIELDS; i++) chp_matchers[i] = new snort::SearchTool("ac_full", true); for (CHPListElement* chpe = chplist; chpe; chpe = chpe->next) chp_matchers[chpe->chp_action.ptype]->add(chpe->chp_action.pattern, chpe->chp_action.psize, &chpe->chp_action, true); - for (size_t i = 0; i <= MAX_PATTERN_TYPE; i++) + for (size_t i = 0; i < NUM_HTTP_FIELDS; i++) chp_matchers[i]->prep(); return 1; @@ -704,10 +712,12 @@ static FieldPattern http_field_patterns[] = { (const uint8_t*)HTTP_FIELD_PREFIX_HOST, REQ_HOST_FID, HTTP_FIELD_PREFIX_HOST_SIZE }, { (const uint8_t*)HTTP_FIELD_PREFIX_REFERER, REQ_REFERER_FID, HTTP_FIELD_PREFIX_REFERER_SIZE }, { (const uint8_t*)HTTP_FIELD_PREFIX_COOKIE, REQ_COOKIE_FID, HTTP_FIELD_PREFIX_COOKIE_SIZE }, - { (const uint8_t*)HTTP_FIELD_PREFIX_USER_AGENT, REQ_AGENT_FID, HTTP_FIELD_PREFIX_USER_AGENT_SIZE }, + { (const uint8_t*)HTTP_FIELD_PREFIX_USER_AGENT, REQ_AGENT_FID, + HTTP_FIELD_PREFIX_USER_AGENT_SIZE }, }; -static snort::SearchTool* process_http_field_patterns(FieldPattern* patternList, size_t patternListCount) +static snort::SearchTool* process_http_field_patterns(FieldPattern* patternList, + size_t patternListCount) { snort::SearchTool* patternMatcher = new snort::SearchTool("ac_full", true); @@ -719,7 +729,8 @@ static snort::SearchTool* process_http_field_patterns(FieldPattern* patternList, return patternMatcher; } -static void process_patterns(snort::SearchTool& matcher, DetectorHTTPPatterns& patterns, bool last = true) +static void process_patterns(snort::SearchTool& matcher, DetectorHTTPPatterns& patterns, bool + last = true) { for (auto& pat: patterns) matcher.add(pat.pattern, pat.pattern_size, &pat, false); @@ -766,14 +777,14 @@ static int http_field_pattern_match(void* id, void*, int match_end_pos, void* da unsigned fieldOffset = match_end_pos; unsigned remainingLength = pFieldData->length - fieldOffset; - if (!(p = (const uint8_t*)service_strstr(&pFieldData->payload[fieldOffset], remainingLength, crlf, - crlfLen))) + if (!(p = (const uint8_t*)service_strstr(&pFieldData->payload[fieldOffset], remainingLength, + crlf, crlfLen))) { return 1; } - pFieldData->hsession->set_field_offset((HttpFieldIds)target->patternType, fieldOffset); - pFieldData->hsession->set_field_end_offset((HttpFieldIds)target->patternType, (p - pFieldData->payload)); + pFieldData->hsession->set_offset(target->patternType, fieldOffset, p-pFieldData->payload); + return 1; } @@ -784,11 +795,14 @@ void HttpPatternMatchers::get_http_offsets(snort::Packet* pkt, AppIdHttpSession* static const uint8_t crlfcrlf[] = "\r\n\r\n"; static unsigned crlfcrlfLen = sizeof(crlfcrlf) - 1; const uint8_t* headerEnd; - unsigned fieldId; FieldPatternData patternMatchData; - for (fieldId = REQ_AGENT_FID; fieldId <= REQ_COOKIE_FID; fieldId++) - hsession->set_field_offset((HttpFieldIds)fieldId, 0); + for (int fieldId = REQ_AGENT_FID; fieldId <= REQ_COOKIE_FID; fieldId++) + { + pair_t off; + if ( hsession->get_offset(fieldId, off.first, off.second) ) + hsession->set_offset(fieldId, 0, off.second); + } if (!pkt->data || pkt->dsize < MIN_HTTP_REQ_HEADER_SIZE) return; @@ -796,7 +810,8 @@ void HttpPatternMatchers::get_http_offsets(snort::Packet* pkt, AppIdHttpSession* patternMatchData.hsession = hsession; patternMatchData.payload = pkt->data; - if (!(headerEnd = (const uint8_t*)service_strstr(pkt->data, pkt->dsize, crlfcrlf, crlfcrlfLen))) + if (!(headerEnd = (const uint8_t*)service_strstr(pkt->data, pkt->dsize, crlfcrlf, + crlfcrlfLen))) return; headerEnd += crlfcrlfLen; @@ -975,7 +990,8 @@ AppId HttpPatternMatchers::scan_chp(ChpMatchDescriptor& cmd, char** version, cha if ( pt > MAX_KEY_PATTERN ) { // There is no previous attempt to match generated by scan_key_chp() - chp_matchers[pt]->find_all(cmd.buffer[pt], cmd.length[pt], &chp_pattern_match, false, (void*)&cmd); + chp_matchers[pt]->find_all(cmd.buffer[pt], cmd.length[pt], &chp_pattern_match, false, + (void*)&cmd); } if ( cmd.chp_matches[pt].empty() ) @@ -1239,8 +1255,8 @@ void HttpPatternMatchers::identify_user_agent(const char* start, int size, AppId case APP_ID_PICASA: if (dominant_pattern_detected) break; - // fallthrough - case APP_ID_WINDOWS_MEDIA_PLAYER: + // fallthrough + case APP_ID_WINDOWS_MEDIA_PLAYER: case APP_ID_BITTORRENT: buffPtr = continue_buffer_scan(start, end, tmp, match); if (!buffPtr) @@ -1511,7 +1527,7 @@ AppId HttpPatternMatchers::scan_header_x_working_with(const char* data, uint32_t if (size >= (sizeof(HTTP_HEADER_WORKINGWITH_ASPROXY) - 1) && memcmp(data, HTTP_HEADER_WORKINGWITH_ASPROXY, - sizeof(HTTP_HEADER_WORKINGWITH_ASPROXY) - 1) == 0) + sizeof(HTTP_HEADER_WORKINGWITH_ASPROXY) - 1) == 0) { const char* end = data + size; data += sizeof(HTTP_HEADER_WORKINGWITH_ASPROXY) - 1; @@ -1582,7 +1598,7 @@ bool HttpPatternMatchers::get_appid_from_url(char* host, const char* url, char** int host_len; if (!host) { - host = (char *)strchr(url, '/'); + host = (char*)strchr(url, '/'); if (host != nullptr) host_len = host - url; else @@ -1652,8 +1668,8 @@ bool HttpPatternMatchers::get_appid_from_url(char* host, const char* url, char** /* if referred_id feature id disabled, referer will be null */ if ( referer and (referer[0] != '\0') and (!payload_found or - AppInfoManager::get_instance().get_app_info_flags(data->payload_id, - APPINFO_FLAG_REFERRED)) ) + AppInfoManager::get_instance().get_app_info_flags(data->payload_id, + APPINFO_FLAG_REFERRED)) ) { const char* referer_start = referer; size_t ref_len = strlen(referer); @@ -1688,7 +1704,8 @@ bool HttpPatternMatchers::get_appid_from_url(char* host, const char* url, char** patterns[1].pattern = (const uint8_t*)referer_path; patterns[1].patternSize = referer_path_len; patterns[2].pattern = nullptr; - HostUrlDetectorPattern* data = (HostUrlDetectorPattern*)mlmpMatchPatternUrl(matcher, patterns); + HostUrlDetectorPattern* data = (HostUrlDetectorPattern*)mlmpMatchPatternUrl(matcher, + patterns); if ( data != nullptr ) { if ( payload_found ) @@ -1744,7 +1761,8 @@ void HttpPatternMatchers::get_server_vendor_version(const char* data, int len, c if ( subname && subname_len > 0 && subver && *subname ) { snort::AppIdServiceSubtype* sub = - (snort::AppIdServiceSubtype*)snort_calloc(sizeof(snort::AppIdServiceSubtype)); + (snort::AppIdServiceSubtype*)snort_calloc( + sizeof(snort::AppIdServiceSubtype)); char* tmp = (char*)snort_calloc(subname_len + 1); memcpy(tmp, subname, subname_len); tmp[subname_len] = 0; diff --git a/src/network_inspectors/appid/detector_plugins/http_url_patterns.h b/src/network_inspectors/appid/detector_plugins/http_url_patterns.h index 5c636ac9c..7f3e65980 100644 --- a/src/network_inspectors/appid/detector_plugins/http_url_patterns.h +++ b/src/network_inspectors/appid/detector_plugins/http_url_patterns.h @@ -173,9 +173,9 @@ struct CHPApp int num_scans; int key_pattern_count; int key_pattern_length_sum; - int ptype_scan_counts[MAX_HTTP_FIELD_ID]; - int ptype_req_counts[MAX_HTTP_FIELD_ID]; - int ptype_rewrite_insert_used[MAX_HTTP_FIELD_ID]; // boolean + int ptype_scan_counts[NUM_HTTP_FIELDS]; + int ptype_req_counts[NUM_HTTP_FIELDS]; + int ptype_rewrite_insert_used[NUM_HTTP_FIELDS]; // boolean }; struct CHPAction @@ -218,7 +218,7 @@ class ChpMatchDescriptor public: void free_rewrite_buffers() { - for (unsigned i = 0; i < MAX_HTTP_FIELD_ID; i++) + for (unsigned i = 0; i < NUM_HTTP_FIELDS; i++) if (chp_rewritten[i]) { snort_free((void*)chp_rewritten[i]); @@ -232,10 +232,10 @@ public: } HttpFieldIds cur_ptype; - const char* buffer[MAX_HTTP_FIELD_ID] = { nullptr }; - uint16_t length[MAX_HTTP_FIELD_ID] = { 0 }; - const char* chp_rewritten[MAX_HTTP_FIELD_ID] = { nullptr }; - std::list chp_matches[MAX_HTTP_FIELD_ID]; + const char* buffer[NUM_HTTP_FIELDS] = { nullptr }; + uint16_t length[NUM_HTTP_FIELDS] = { 0 }; + const char* chp_rewritten[NUM_HTTP_FIELDS] = { nullptr }; + std::list chp_matches[NUM_HTTP_FIELDS]; CHPMatchTally match_tally; private: @@ -329,7 +329,7 @@ private: snort::SearchTool via_matcher; snort::SearchTool content_type_matcher; snort::SearchTool* field_matcher = nullptr; - snort::SearchTool* chp_matchers[MAX_PATTERN_TYPE + 1] = { nullptr }; + snort::SearchTool* chp_matchers[NUM_HTTP_FIELDS] = { nullptr }; tMlmpTree* host_url_matcher = nullptr; tMlmpTree* rtmp_host_url_matcher = nullptr; diff --git a/src/network_inspectors/appid/detector_plugins/test/detector_plugins_mock.h b/src/network_inspectors/appid/detector_plugins/test/detector_plugins_mock.h index 0050405ca..5fdc08000 100644 --- a/src/network_inspectors/appid/detector_plugins/test/detector_plugins_mock.h +++ b/src/network_inspectors/appid/detector_plugins/test/detector_plugins_mock.h @@ -23,13 +23,13 @@ namespace snort { // Stubs for messages -void ErrorMessage(const char*,...) {} -void WarningMessage(const char*,...) {} -void LogMessage(const char*,...) {} -void ParseWarning(WarningGroup, const char*, ...) {} +void ErrorMessage(const char*,...) { } +void WarningMessage(const char*,...) { } +void LogMessage(const char*,...) { } +void ParseWarning(WarningGroup, const char*, ...) { } // Stubs for appid sessions -FlowData::FlowData(unsigned, Inspector*) {} +FlowData::FlowData(unsigned, Inspector*) { } FlowData::~FlowData() = default; // Stubs for packet @@ -43,13 +43,13 @@ bool Inspector::get_buf(const char*, Packet*, InspectionBuffer&) { return true; class StreamSplitter* Inspector::get_splitter(bool) { return nullptr; } // Stubs for search_tool.cc -SearchTool::SearchTool(const char*, bool) {} +SearchTool::SearchTool(const char*, bool) { } SearchTool::~SearchTool() = default; -void SearchTool::add(const char*, unsigned, int, bool) {} -void SearchTool::add(const char*, unsigned, void*, bool) {} -void SearchTool::add(const uint8_t*, unsigned, int, bool) {} -void SearchTool::add(const uint8_t*, unsigned, void*, bool) {} -void SearchTool::prep() {} +void SearchTool::add(const char*, unsigned, int, bool) { } +void SearchTool::add(const char*, unsigned, void*, bool) { } +void SearchTool::add(const uint8_t*, unsigned, int, bool) { } +void SearchTool::add(const uint8_t*, unsigned, void*, bool) { } +void SearchTool::prep() { } static bool test_find_all_done = false; static bool test_find_all_enabled = false; static MatchedPatterns* mock_mp = nullptr; @@ -72,6 +72,7 @@ char* snort_strndup(const char* src, size_t dst_size) } return dup; } + char* snort_strdup(const char* str) { assert(str); @@ -82,47 +83,52 @@ char* snort_strdup(const char* str) } } -void show_stats(PegCount*, const PegInfo*, unsigned, const char*) {} -void show_stats(PegCount*, const PegInfo*, IndexVec&, const char*) {} -void show_stats(PegCount*, const PegInfo*, IndexVec&, const char*, FILE*) {} +void show_stats(PegCount*, const PegInfo*, unsigned, const char*) { } +void show_stats(PegCount*, const PegInfo*, IndexVec&, const char*) { } +void show_stats(PegCount*, const PegInfo*, IndexVec&, const char*, FILE*) { } class AppIdInspector : public snort::Inspector { public: - AppIdInspector(AppIdModule& ) {} + AppIdInspector(AppIdModule&) { } ~AppIdInspector() override = default; - void eval(Packet*) override {} + void eval(Packet*) override { } bool configure(snort::SnortConfig*) override { return true; } - void show(snort::SnortConfig*) override {} - void tinit() override {} - void tterm() override {} + void show(snort::SnortConfig*) override { } + void tinit() override { } + void tterm() override { } }; // Stubs for modules, config AppIdModuleConfig::~AppIdModuleConfig() = default; AppIdModule::AppIdModule() - : Module("a", "b") {} + : Module("a", "b") { } AppIdModule::~AppIdModule() = default; bool AppIdModule::begin(const char*, int, snort::SnortConfig*) { return false; } + bool AppIdModule::set(const char*, snort::Value&, snort::SnortConfig*) { return false; } + bool AppIdModule::end(const char*, int, snort::SnortConfig*) { return false; } + const Command* AppIdModule::get_commands() const { return nullptr; } + const PegInfo* AppIdModule::get_pegs() const { return nullptr; } + PegCount* AppIdModule::get_counts() const { return nullptr; @@ -136,21 +142,37 @@ snort::ProfileStats* AppIdModule::get_profile() const // Stubs for inspectors unsigned AppIdSession::inspector_id = 0; AppIdSession::AppIdSession(IpProtocol, const SfIp*, uint16_t, AppIdInspector& inspector) - : snort::FlowData(inspector_id, (snort::Inspector*)&inspector), inspector(inspector) {} + : snort::FlowData(inspector_id, (snort::Inspector*)&inspector), inspector(inspector) { } AppIdSession::~AppIdSession() = default; -AppIdHttpSession::AppIdHttpSession(AppIdSession& session) - : asd(session) {} -AppIdHttpSession::~AppIdHttpSession() = default; +AppIdHttpSession::AppIdHttpSession(AppIdSession& asd) + : asd(asd) +{ + http_matchers = HttpPatternMatchers::get_instance(); + + for ( int i = 0; i < NUM_METADATA_FIELDS; i++) + meta_data[i] = nullptr; +} + +AppIdHttpSession::~AppIdHttpSession() +{ + delete xff_addr; + + for ( int i = 0; i < NUM_METADATA_FIELDS; i++) + { + if ( meta_data[i] ) + delete meta_data[i]; + } +} // Stubs for AppIdPegCounts -void AppIdPegCounts::inc_service_count(AppId) {} -void AppIdPegCounts::inc_client_count(AppId) {} -void AppIdPegCounts::inc_user_count(AppId) {} -void AppIdPegCounts::inc_payload_count(AppId) {} +void AppIdPegCounts::inc_service_count(AppId) { } +void AppIdPegCounts::inc_client_count(AppId) { } +void AppIdPegCounts::inc_user_count(AppId) { } +void AppIdPegCounts::inc_payload_count(AppId) { } THREAD_LOCAL AppIdStats appid_stats; -void AppIdModule::sum_stats(bool) {} -void AppIdModule::show_dynamic_stats() {} +void AppIdModule::sum_stats(bool) { } +void AppIdModule::show_dynamic_stats() { } // Stubs for appid_session.cc static bool test_service_strstr_enabled = false; @@ -164,17 +186,13 @@ const uint8_t* service_strstr(const uint8_t* p, unsigned, // Stubs for appid_http_session.cc static bool test_field_offset_set_done = false; -void AppIdHttpSession::set_field_offset(HttpFieldIds, uint16_t) -{ - test_field_offset_set_done = true; -} -void AppIdHttpSession::set_field_end_offset(HttpFieldIds, uint16_t) {} // Stubs for app_info_table.cc AppInfoTableEntry* AppInfoManager::get_app_info_entry(int) { return nullptr; } + AppInfoTableEntry* AppInfoManager::get_app_info_entry(AppId, const AppInfoTable&) { return nullptr; diff --git a/src/network_inspectors/appid/detector_plugins/test/http_url_patterns_test.cc b/src/network_inspectors/appid/detector_plugins/test/http_url_patterns_test.cc index ca65f00cb..df74118e6 100644 --- a/src/network_inspectors/appid/detector_plugins/test/http_url_patterns_test.cc +++ b/src/network_inspectors/appid/detector_plugins/test/http_url_patterns_test.cc @@ -38,7 +38,7 @@ static HttpPatternMatchers* hm = nullptr; static Packet pkt; static const SfIp* sfip = nullptr; static AppIdModule appid_mod; -static AppIdInspector appid_inspector( appid_mod ); +static AppIdInspector appid_inspector(appid_mod); static AppIdSession session(IpProtocol::IP, sfip, 0, appid_inspector); static AppIdHttpSession hsession(session); static ChpMatchDescriptor cmd; @@ -53,8 +53,8 @@ static AppIdModuleConfig mod_config; static AppId service_id = APP_ID_NONE; static AppId client_id = APP_ID_NONE; static DetectorHTTPPattern mpattern; -static const char* my_buffer[MAX_HTTP_FIELD_ID] = { nullptr }; -static uint16_t my_length[MAX_HTTP_FIELD_ID] = { 0 }; +static const char* my_buffer[NUM_HTTP_FIELDS] = { nullptr }; +static uint16_t my_length[NUM_HTTP_FIELDS] = { 0 }; static CHPAction my_match; static void* my_chp_rewritten = nullptr; @@ -76,17 +76,25 @@ TEST(http_url_patterns_tests, http_field_pattern_match) { FieldPatternData fpd; FieldPattern fp; + pair_t off; // verify service_strstr getting called + fp.patternType = REQ_HOST_FID; fpd.payload = (const uint8_t*)"Google"; fpd.length = 6; + fpd.hsession = &hsession; + test_service_strstr_enabled = false; test_field_offset_set_done = false; + hsession.set_offset(fp.patternType, 0, 5); CHECK_EQUAL(1, http_field_pattern_match(&fp, nullptr, 0, &fpd, nullptr)); - CHECK_EQUAL(false, test_field_offset_set_done); + hsession.get_offset(fp.patternType, off.first, off.second); + CHECK_EQUAL(5, off.second); // check offset did not change + test_service_strstr_enabled = true; CHECK_EQUAL(1, http_field_pattern_match(&fp, nullptr, 0, &fpd, nullptr)); - CHECK_EQUAL(true, test_field_offset_set_done); + hsession.get_offset(fp.patternType, off.first, off.second); + CHECK_EQUAL(0, off.second); // if it changed, service_strstr was called } TEST(http_url_patterns_tests, match_query_elements) @@ -128,8 +136,12 @@ TEST(http_url_patterns_tests, get_http_offsets) test_field_offset_set_done = false; pkt.data = (const uint8_t*)"Go"; pkt.dsize = 2; + + pair_t off; + hsession.set_offset(REQ_AGENT_FID, 5, 0); hm->get_http_offsets(&pkt, &hsession); - CHECK_EQUAL(true, test_field_offset_set_done); + hsession.get_offset(REQ_AGENT_FID, off.first, off.second); + CHECK_EQUAL(0, off.first); // find_all is not called for bigger payload when service_strstr returns nullptr test_service_strstr_enabled = false; @@ -152,7 +164,7 @@ TEST(http_url_patterns_tests, rewrite_chp_exist) my_match.action_data = (char*)"exist"; my_match.psize = 0; rewrite_chp(my_buffer[REQ_AGENT_FID], my_length[REQ_AGENT_FID], 0, my_match.psize, - my_match.action_data, (const char**)&my_chp_rewritten, 1); + my_match.action_data, (const char**)&my_chp_rewritten, 1); CHECK((char*)my_chp_rewritten == nullptr); } @@ -162,7 +174,7 @@ TEST(http_url_patterns_tests, rewrite_chp_insert) my_buffer[REQ_AGENT_FID] = (const char*)"existing data"; my_match.action_data = (char*)"new"; rewrite_chp(my_buffer[REQ_AGENT_FID], my_length[REQ_AGENT_FID], 0, my_match.psize, - my_match.action_data, (const char**)&my_chp_rewritten, 1); + my_match.action_data, (const char**)&my_chp_rewritten, 1); STRCMP_EQUAL((const char*)my_chp_rewritten, (const char*)my_match.action_data); snort_free(my_chp_rewritten); my_chp_rewritten = nullptr; @@ -175,8 +187,8 @@ TEST(http_url_patterns_tests, rewrite_chp_same) my_buffer[REQ_AGENT_FID] = (const char*)"some data"; my_match.action_data = (char*)"some data"; rewrite_chp(my_buffer[REQ_AGENT_FID], my_length[REQ_AGENT_FID], 0, my_match.psize, - my_match.action_data, (const char**)&my_chp_rewritten, 0); - CHECK((char *)my_chp_rewritten == nullptr); + my_match.action_data, (const char**)&my_chp_rewritten, 0); + CHECK((char*)my_chp_rewritten == nullptr); } TEST(http_url_patterns_tests, rewrite_chp_replace_null) @@ -187,7 +199,7 @@ TEST(http_url_patterns_tests, rewrite_chp_replace_null) my_match.action_data = nullptr; my_match.psize = 0; rewrite_chp(my_buffer[REQ_AGENT_FID], strlen(my_buffer[REQ_AGENT_FID]), 0, my_match.psize, - my_match.action_data, (const char**)&my_chp_rewritten, 0); + my_match.action_data, (const char**)&my_chp_rewritten, 0); STRCMP_EQUAL((const char*)my_chp_rewritten, my_buffer[REQ_AGENT_FID]); snort_free(my_chp_rewritten); my_chp_rewritten = nullptr; @@ -201,7 +213,7 @@ TEST(http_url_patterns_tests, rewrite_chp_replace_non_null) my_match.action_data = (char*)"new data"; my_match.psize = 1; rewrite_chp(my_buffer[REQ_AGENT_FID], 1, 0, my_match.psize, - my_match.action_data, (const char**)&my_chp_rewritten, 0); + my_match.action_data, (const char**)&my_chp_rewritten, 0); STRCMP_EQUAL((const char*)my_chp_rewritten, (const char*)my_match.action_data); snort_free(my_chp_rewritten); my_chp_rewritten = nullptr; @@ -228,20 +240,21 @@ TEST(http_url_patterns_tests, normalize_userid) TEST(http_url_patterns_tests, scan_header_x_working_with) { // appid is APP_ID_ASPROXY - char *version = snort_strdup("456"); + char* version = snort_strdup("456"); const char* data = "ASProxy/123"; - CHECK(hm->scan_header_x_working_with(data, (uint32_t)strlen(data), (char**)&version) == APP_ID_ASPROXY); + CHECK(hm->scan_header_x_working_with(data, (uint32_t)strlen(data), (char**)&version) == + APP_ID_ASPROXY); STRCMP_EQUAL(version, "123"); snort_free(version); version = nullptr; // appid is APP_ID_NONE const char* data2 = "Not ASProxy format"; - CHECK(hm->scan_header_x_working_with(data2, (uint32_t)strlen(data2), (char**)&version) == APP_ID_NONE); + CHECK(hm->scan_header_x_working_with(data2, (uint32_t)strlen(data2), (char**)&version) == + APP_ID_NONE); CHECK(version == nullptr); } - TEST(http_url_patterns_tests, scan_chp_defer) { // testing DEFER_TO_SIMPLE_DETECT @@ -252,7 +265,8 @@ TEST(http_url_patterns_tests, scan_chp_defer) cmd.chp_matches[RSP_BODY_FID].push_back(mchp); cmd.cur_ptype = RSP_BODY_FID; mod_config.safe_search_enabled = false; - CHECK(hm->scan_chp(cmd, &version, &user, &total_found, &hsession, (const AppIdModuleConfig*)&mod_config) == APP_ID_NONE); + CHECK(hm->scan_chp(cmd, &version, &user, &total_found, &hsession, (const + AppIdModuleConfig*)&mod_config) == APP_ID_NONE); CHECK_EQUAL(true, test_find_all_done); } @@ -267,11 +281,11 @@ TEST(http_url_patterns_tests, scan_chp_alt_appid) cmd.chp_matches[RSP_BODY_FID].push_back(mchp); cmd.cur_ptype = RSP_BODY_FID; mod_config.safe_search_enabled = false; - CHECK(hm->scan_chp(cmd, &version, &user, &total_found, &hsession, (const AppIdModuleConfig*)&mod_config) == APP_ID_NONE); + CHECK(hm->scan_chp(cmd, &version, &user, &total_found, &hsession, (const + AppIdModuleConfig*)&mod_config) == APP_ID_NONE); CHECK_EQUAL(true, test_find_all_done); } - TEST(http_url_patterns_tests, scan_chp_extract_user) { // testing EXTRACT_USER @@ -287,7 +301,8 @@ TEST(http_url_patterns_tests, scan_chp_extract_user) cmd.chp_matches[RSP_BODY_FID].push_back(mchp); cmd.buffer[RSP_BODY_FID] = (const char*)"userid\n\rpassword"; cmd.length[RSP_BODY_FID] = strlen(cmd.buffer[RSP_BODY_FID]); - CHECK(hm->scan_chp(cmd, &version, &user, &total_found, &hsession, (const AppIdModuleConfig*)&mod_config) == APP_ID_NONE); + CHECK(hm->scan_chp(cmd, &version, &user, &total_found, &hsession, (const + AppIdModuleConfig*)&mod_config) == APP_ID_NONE); CHECK_EQUAL(true, test_find_all_done); snort_free(user); user = nullptr; @@ -308,7 +323,8 @@ TEST(http_url_patterns_tests, scan_chp_rewrite_field) cmd.chp_matches[RSP_BODY_FID].push_back(mchp); cmd.buffer[RSP_BODY_FID] = my_chp_data; cmd.length[RSP_BODY_FID] = strlen(cmd.buffer[RSP_BODY_FID]); - CHECK(hm->scan_chp(cmd, &version, &user, &total_found, &hsession, (const AppIdModuleConfig*)&mod_config) == APP_ID_NONE); + CHECK(hm->scan_chp(cmd, &version, &user, &total_found, &hsession, (const + AppIdModuleConfig*)&mod_config) == APP_ID_NONE); CHECK_EQUAL(true, test_find_all_done); snort_free(const_cast(cmd.chp_rewritten[RSP_BODY_FID])); cmd.chp_rewritten[RSP_BODY_FID] = nullptr; @@ -329,7 +345,8 @@ TEST(http_url_patterns_tests, scan_chp_insert_without_action) cmd.chp_matches[RSP_BODY_FID].push_back(mchp); cmd.buffer[RSP_BODY_FID] = my_chp_data; cmd.length[RSP_BODY_FID] = strlen(cmd.buffer[RSP_BODY_FID]); - CHECK(hm->scan_chp(cmd, &version, &user, &total_found, &hsession, (const AppIdModuleConfig*)&mod_config) == APP_ID_NONE); + CHECK(hm->scan_chp(cmd, &version, &user, &total_found, &hsession, (const + AppIdModuleConfig*)&mod_config) == APP_ID_NONE); CHECK_EQUAL(true, test_find_all_done); snort_free(const_cast(cmd.chp_rewritten[RSP_BODY_FID])); cmd.chp_rewritten[RSP_BODY_FID] = nullptr; @@ -350,7 +367,8 @@ TEST(http_url_patterns_tests, scan_chp_insert_with_action) cmd.chp_matches[RSP_BODY_FID].push_back(mchp); cmd.buffer[RSP_BODY_FID] = my_chp_data; cmd.length[RSP_BODY_FID] = strlen(cmd.buffer[RSP_BODY_FID]); - CHECK(hm->scan_chp(cmd, &version, &user, &total_found, &hsession, (const AppIdModuleConfig*)&mod_config) == APP_ID_NONE); + CHECK(hm->scan_chp(cmd, &version, &user, &total_found, &hsession, (const + AppIdModuleConfig*)&mod_config) == APP_ID_NONE); CHECK_EQUAL(true, test_find_all_done); snort_free(const_cast(cmd.chp_rewritten[RSP_BODY_FID])); cmd.chp_rewritten[RSP_BODY_FID] = nullptr; @@ -371,7 +389,8 @@ TEST(http_url_patterns_tests, scan_chp_hold_and_default) mchp.start_match_pos = 0; cmd.buffer[RSP_BODY_FID] = my_chp_data; cmd.length[RSP_BODY_FID] = strlen(cmd.buffer[RSP_BODY_FID]); - CHECK(hm->scan_chp(cmd, &version, &user, &total_found, &hsession, (const AppIdModuleConfig*)&mod_config) == APP_ID_NONE); + CHECK(hm->scan_chp(cmd, &version, &user, &total_found, &hsession, (const + AppIdModuleConfig*)&mod_config) == APP_ID_NONE); CHECK_EQUAL(true, test_find_all_done); // testing FUTURE_APPID_SESSION_SIP (default action) @@ -381,19 +400,27 @@ TEST(http_url_patterns_tests, scan_chp_hold_and_default) chpa.action = FUTURE_APPID_SESSION_SIP; mchp.mpattern = &chpa; cmd.chp_matches[RSP_BODY_FID].push_back(mchp); - CHECK(hm->scan_chp(cmd, &version, &user, &total_found, &hsession, (const AppIdModuleConfig*)&mod_config) == APP_ID_NONE); + CHECK(hm->scan_chp(cmd, &version, &user, &total_found, &hsession, (const + AppIdModuleConfig*)&mod_config) == APP_ID_NONE); CHECK_EQUAL(true, test_find_all_done); } TEST(http_url_patterns_tests, insert_and_process_pattern) { DetectorHTTPPattern url_pat, payload_pat; - DetectorAppUrlPattern* au_pat = (DetectorAppUrlPattern*)snort_calloc(sizeof(DetectorAppUrlPattern)); + DetectorAppUrlPattern* au_pat = (DetectorAppUrlPattern*)snort_calloc( + sizeof(DetectorAppUrlPattern)); // adding to host_payload_patterns - payload_pat.init(nullptr, 6, SINGLE, APP_ID_HTTP, APP_ID_NONE, APP_ID_GOOGLE, APP_ID_NONE); // null pattern test - payload_pat.init((const uint8_t*)"Google", 6, (DHPSequence)10, APP_ID_HTTP, APP_ID_NONE, APP_ID_GOOGLE, APP_ID_NONE); // high seq test - payload_pat.init((const uint8_t*)"Google", 6, SINGLE, APP_ID_HTTP, APP_ID_NONE, APP_ID_GOOGLE, APP_ID_NONE); + payload_pat.init(nullptr, 6, SINGLE, APP_ID_HTTP, APP_ID_NONE, APP_ID_GOOGLE, APP_ID_NONE); // null + // pattern + // test + payload_pat.init((const uint8_t*)"Google", 6, (DHPSequence)10, APP_ID_HTTP, APP_ID_NONE, + APP_ID_GOOGLE, APP_ID_NONE); // high + // seq + // test + payload_pat.init((const uint8_t*)"Google", 6, SINGLE, APP_ID_HTTP, APP_ID_NONE, APP_ID_GOOGLE, + APP_ID_NONE); snort_free(const_cast(payload_pat.pattern)); payload_pat.pattern = nullptr; hm->insert_http_pattern(HTTP_PAYLOAD, payload_pat); @@ -415,14 +442,14 @@ TEST(http_url_patterns_tests, insert_and_process_pattern) CHECK(true); } - TEST(http_url_patterns_tests, identify_user_agent_firefox) { test_find_all_enabled = true; // null buffPtr in continue_buffer_scan for APP_ID_FIREFOX mpattern.client_id = APP_ID_FIREFOX; - mock_mp = (MatchedPatterns*)snort_calloc(sizeof(MatchedPatterns)); // freed by identify_user_agent + mock_mp = (MatchedPatterns*)snort_calloc(sizeof(MatchedPatterns)); // freed by + // identify_user_agent mock_mp->mpattern = &mpattern; mock_mp->after_match_pos = 100; // exceeding size mock_mp->next = nullptr; @@ -507,7 +534,8 @@ TEST(http_url_patterns_tests, identify_user_agent_bittorrent) // invalid version format following after_match_pos for APP_ID_BITTORRENT mpattern.client_id = APP_ID_BITTORRENT; - mock_mp = (MatchedPatterns*)snort_calloc(sizeof(MatchedPatterns)); // freed by identify_user_agent + mock_mp = (MatchedPatterns*)snort_calloc(sizeof(MatchedPatterns)); // freed by + // identify_user_agent mock_mp->mpattern = &mpattern; mock_mp->after_match_pos = 10; mock_mp->next = nullptr; @@ -525,7 +553,8 @@ TEST(http_url_patterns_tests, identify_user_agent_google_desktop) // exceeding after_match_pos for APP_ID_GOOGLE_DESKTOP mpattern.client_id = APP_ID_GOOGLE_DESKTOP; - mock_mp = (MatchedPatterns*)snort_calloc(sizeof(MatchedPatterns)); // freed by identify_user_agent + mock_mp = (MatchedPatterns*)snort_calloc(sizeof(MatchedPatterns)); // freed by + // identify_user_agent mock_mp->mpattern = &mpattern; mock_mp->after_match_pos = 100; // exceeding size mock_mp->next = nullptr; @@ -580,7 +609,8 @@ TEST(http_url_patterns_tests, identify_user_agent_fake_version_appid) // exceeding after_match_pos for FAKE_VERSION_APP_ID test_find_all_enabled = true; mpattern.client_id = FAKE_VERSION_APP_ID; - mock_mp = (MatchedPatterns*)snort_calloc(sizeof(MatchedPatterns)); // freed by identify_user_agent + mock_mp = (MatchedPatterns*)snort_calloc(sizeof(MatchedPatterns)); // freed by + // identify_user_agent mock_mp->mpattern = &mpattern; mock_mp->after_match_pos = 100; // exceeding size mock_mp->next = nullptr; @@ -597,7 +627,8 @@ TEST(http_url_patterns_tests, identify_user_agent_blackberry) // null buffPtr in continue_buffer_scan for APP_ID_BLACKBERRY_BROWSER mpattern.client_id = APP_ID_BLACKBERRY_BROWSER; - mock_mp = (MatchedPatterns*)snort_calloc(sizeof(MatchedPatterns)); // freed by identify_user_agent + mock_mp = (MatchedPatterns*)snort_calloc(sizeof(MatchedPatterns)); // freed by + // identify_user_agent mock_mp->mpattern = &mpattern; mock_mp->after_match_pos = 100; mock_mp->next = nullptr; @@ -657,7 +688,8 @@ TEST(http_url_patterns_tests, identify_user_agent_skypedirect) // skypeDetect test_find_all_enabled = true; mpattern.client_id = APP_ID_SKYPE; - mock_mp = (MatchedPatterns*)snort_calloc(sizeof(MatchedPatterns)); // freed by identify_user_agent + mock_mp = (MatchedPatterns*)snort_calloc(sizeof(MatchedPatterns)); // freed by + // identify_user_agent mock_mp->mpattern = &mpattern; mock_mp->after_match_pos = 5; mock_mp->next = nullptr; @@ -675,3 +707,4 @@ int main(int argc, char** argv) int return_value = CommandLineTestRunner::RunAllTests(argc, argv); return return_value; } + diff --git a/src/network_inspectors/appid/lua_detector_api.cc b/src/network_inspectors/appid/lua_detector_api.cc index 31ba4973c..5cb8475be 100644 --- a/src/network_inspectors/appid/lua_detector_api.cc +++ b/src/network_inspectors/appid/lua_detector_api.cc @@ -1143,7 +1143,7 @@ static inline int get_chp_key_pattern_boolean(lua_State* L, int index) static inline int get_chp_pattern_type(lua_State* L, int index, HttpFieldIds* pattern_type) { *pattern_type = (HttpFieldIds)lua_tointeger(L, index); - if ( *pattern_type > MAX_PATTERN_TYPE ) + if ( *pattern_type >= NUM_HTTP_FIELDS ) { ErrorMessage("LuaDetectorApi:Invalid CHP Action pattern type."); return -1; diff --git a/src/network_inspectors/appid/service_plugins/service_rtmp.cc b/src/network_inspectors/appid/service_plugins/service_rtmp.cc index 8c1b87f63..b36a31077 100644 --- a/src/network_inspectors/appid/service_plugins/service_rtmp.cc +++ b/src/network_inspectors/appid/service_plugins/service_rtmp.cc @@ -95,7 +95,6 @@ RtmpServiceDetector::RtmpServiceDetector(ServiceDiscovery* sd) handler->register_detector(name, this, proto); } - static void rtmp_free(void* ss) /* AppIdFreeFCN */ { ServiceRTMPData* ss_tmp = (ServiceRTMPData*)ss; @@ -636,9 +635,9 @@ success: AppIdHttpSession* hsession = args.asd.get_http_session(); if ( ss->swfUrl ) { - if ( !hsession->get_url() ) + if ( !hsession->get_field(MISC_URL_FID) ) { - hsession->set_url(ss->swfUrl); + hsession->set_field(MISC_URL_FID, new std::string(ss->swfUrl)); args.asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG; } @@ -648,9 +647,9 @@ success: if ( ss->pageUrl ) { - if ( !hsession->get_referer() && - !args.asd.config->mod_config->referred_appId_disabled ) - hsession->set_referer(ss->pageUrl); + if ( !hsession->get_field(REQ_REFERER_FID) && + !args.asd.config->mod_config->referred_appId_disabled ) + hsession->set_field(REQ_REFERER_FID, new std::string(ss->pageUrl)); snort_free(ss->pageUrl); ss->pageUrl = nullptr; diff --git a/src/network_inspectors/appid/test/appid_detector_test.cc b/src/network_inspectors/appid/test/appid_detector_test.cc index 459fd00a4..11cb07249 100644 --- a/src/network_inspectors/appid/test/appid_detector_test.cc +++ b/src/network_inspectors/appid/test/appid_detector_test.cc @@ -71,10 +71,10 @@ TEST(appid_detector_tests, add_info) AppIdDetector* ad = new TestDetector; MockAppIdHttpSession* hsession = (MockAppIdHttpSession*)mock_session->get_http_session(); ad->add_info(*mock_session, info_url); - STRCMP_EQUAL(hsession->get_url(), URL); + STRCMP_EQUAL(hsession->get_cfield(MISC_URL_FID), URL); hsession->reset(); ad->add_info(*mock_session, info_url); - STRCMP_EQUAL(mock_session->get_http_session()->get_url(), info_url); + STRCMP_EQUAL(mock_session->get_http_session()->get_cfield(MISC_URL_FID), info_url); delete ad; } @@ -117,3 +117,4 @@ int main(int argc, char** argv) mock_cleanup_appid_pegs(); return rc; } + diff --git a/src/network_inspectors/appid/test/appid_http_event_test.cc b/src/network_inspectors/appid/test/appid_http_event_test.cc index 6ffebcfcf..3fd01a84a 100644 --- a/src/network_inspectors/appid/test/appid_http_event_test.cc +++ b/src/network_inspectors/appid/test/appid_http_event_test.cc @@ -34,7 +34,6 @@ #include "appid_mock_definitions.h" #include "appid_mock_inspector.h" -#include "appid_mock_http_session.h" #include "appid_mock_session.h" #include @@ -269,23 +268,24 @@ static void run_event_handler(TestData test_data, TestData* expect_data = nullpt hsession->reset(); event_handler.handle(event, flow); LONGS_EQUAL(expect_data->scan_flags, mock_session->scan_flags); - STRCMP_EQUAL(expect_data->host, hsession->get_host()); - STRCMP_EQUAL(expect_data->uri, hsession->get_uri()); - STRCMP_EQUAL(expect_data->content_type, hsession->get_content_type()); - STRCMP_EQUAL(expect_data->cookie, hsession->get_cookie()); - STRCMP_EQUAL(expect_data->location, hsession->get_location()); - STRCMP_EQUAL(expect_data->referer, hsession->get_referer()); - STRCMP_EQUAL(expect_data->server, hsession->get_server()); - STRCMP_EQUAL(expect_data->x_working_with, hsession->get_x_working_with()); - STRCMP_EQUAL(expect_data->useragent, hsession->get_user_agent()); - STRCMP_EQUAL(expect_data->via, hsession->get_via()); - if (nullptr == hsession->get_response_code()) + STRCMP_EQUAL(expect_data->host, hsession->get_cfield(REQ_HOST_FID)); + STRCMP_EQUAL(expect_data->uri, hsession->get_cfield(REQ_URI_FID)); + STRCMP_EQUAL(expect_data->content_type, hsession->get_cfield(RSP_CONTENT_TYPE_FID)); + STRCMP_EQUAL(expect_data->cookie, hsession->get_cfield(REQ_COOKIE_FID)); + STRCMP_EQUAL(expect_data->location, hsession->get_cfield(RSP_LOCATION_FID)); + STRCMP_EQUAL(expect_data->referer, hsession->get_cfield(REQ_REFERER_FID)); + STRCMP_EQUAL(expect_data->server, hsession->get_cfield(MISC_SERVER_FID)); + STRCMP_EQUAL(expect_data->x_working_with, hsession->get_cfield(MISC_XWW_FID)); + STRCMP_EQUAL(expect_data->useragent, hsession->get_cfield(REQ_AGENT_FID)); + STRCMP_EQUAL(expect_data->via, hsession->get_cfield(MISC_VIA_FID)); + if (nullptr == hsession->get_field(MISC_RESP_CODE_FID)) { LONGS_EQUAL(0, expect_data->response_code); } else { - LONGS_EQUAL(expect_data->response_code, strtol(hsession->get_response_code(), nullptr, 10)); + LONGS_EQUAL(expect_data->response_code, strtol(hsession->get_field( + MISC_RESP_CODE_FID)->c_str(), nullptr, 10)); } mock().checkExpectations(); } diff --git a/src/network_inspectors/appid/test/appid_mock_http_session.h b/src/network_inspectors/appid/test/appid_mock_http_session.h index 64b6ddbea..e29551568 100644 --- a/src/network_inspectors/appid/test/appid_mock_http_session.h +++ b/src/network_inspectors/appid/test/appid_mock_http_session.h @@ -23,42 +23,24 @@ #include +typedef AppIdHttpSession::pair_t pair_t; + AppIdHttpSession::AppIdHttpSession(AppIdSession& session) : asd(session) { + for ( int i = 0; i < NUM_METADATA_FIELDS; i++) + meta_data[i] = nullptr; } 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; + + for ( int i = 0; i < NUM_METADATA_FIELDS; i++) + { + if ( meta_data[i] ) + delete meta_data[i]; + } } int AppIdHttpSession::process_http_packet(AppidSessionDirection) { return 0; } @@ -83,103 +65,18 @@ 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(const std::string*& header, const uint8_t* content, int32_t clen) -{ - if (clen <= 0) - return; - - if (header) - delete header; - header=new std::string((const char*)content,clen); -} - -void AppIdHttpSession::update_host(const uint8_t* new_host, int32_t len) -{ - replace_header_data(host, new_host, len); -} - -void AppIdHttpSession::update_uri(const uint8_t* new_uri, int32_t len) -{ - replace_header_data(uri, new_uri, len); -} - void AppIdHttpSession::update_url() { + const std::string* host = meta_data[REQ_HOST_FID]; + const std::string* uri = meta_data[REQ_URI_FID]; if (host and uri) { - if (url) - delete url; - url=new std::string(std::string("http://") + *host + *uri); + if (meta_data[MISC_URL_FID]) + delete meta_data[MISC_URL_FID]; + meta_data[MISC_URL_FID] = new std::string(std::string("http://") + *host + *uri); } } -void AppIdHttpSession::update_useragent(const uint8_t* new_ua, int32_t len) -{ - replace_header_data(useragent, new_ua, len); -} - -void AppIdHttpSession::update_cookie(const uint8_t* new_cookie, int32_t len) -{ - replace_header_data(cookie, new_cookie, len); -} - -void AppIdHttpSession::update_referer(const uint8_t* new_referer, int32_t len) -{ - replace_header_data(referer, new_referer, len); -} - -void AppIdHttpSession::update_x_working_with(const uint8_t* new_xww, int32_t len) -{ - replace_header_data(x_working_with, new_xww, len); -} - -void AppIdHttpSession::update_content_type(const uint8_t* new_content_type, int32_t len) -{ - replace_header_data(content_type, new_content_type, len); -} - -void AppIdHttpSession::update_location(const uint8_t* new_location, int32_t len) -{ - replace_header_data(location, new_location, len); -} - -void AppIdHttpSession::update_server(const uint8_t* new_server, int32_t len) -{ - replace_header_data(server, new_server, len); -} - -void AppIdHttpSession::update_via(const uint8_t* new_via, int32_t len) -{ - replace_header_data(via, new_via, len); -} - -void AppIdHttpSession::update_body(const uint8_t* new_body, int32_t len) -{ - replace_header_data(body, new_body, len); -} - -void AppIdHttpSession::update_req_body(const uint8_t* new_req_body, int32_t len) -{ - replace_header_data(req_body, new_req_body, len); -} - -void AppIdHttpSession::update_response_code(const char* 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 = new std::string(url); // FIXIT-M null terminated? - else - this->url = nullptr; -} - class MockAppIdHttpSession : public AppIdHttpSession { public: @@ -189,82 +86,48 @@ public: SfIp* ip = new SfIp; ip->pton(AF_INET, APPID_UT_XFF_IP_ADDR); xff_addr = ip; - 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; - http_fields[REQ_COOKIE_FID].end_offset = COOKIE_OFFSET + strlen(NEW_COOKIE); + + meta_data[REQ_AGENT_FID] = new std::string(USERAGENT); + meta_data[REQ_HOST_FID] = new std::string(HOST); + meta_data[REQ_REFERER_FID] = new std::string(REFERER); + meta_data[REQ_URI_FID] = new std::string(URI); + meta_data[REQ_COOKIE_FID] = new std::string(COOKIE); + meta_data[REQ_BODY_FID] = new std::string(REQ_BODY); + meta_data[RSP_CONTENT_TYPE_FID] = new std::string(CONTENT_TYPE); + meta_data[RSP_LOCATION_FID] = new std::string(LOCATION); + meta_data[RSP_BODY_FID] = new std::string(RSP_BODY); + meta_data[MISC_VIA_FID] = new std::string(VIA); + meta_data[MISC_RESP_CODE_FID] = new std::string(RESPONSE_CODE); + meta_data[MISC_SERVER_FID] = new std::string(SERVER); + meta_data[MISC_XWW_FID] = new std::string(X_WORKING_WITH); + meta_data[MISC_URL_FID] = new std::string(URL); + + meta_offset[REQ_URI_FID].first = URI_OFFSET; + meta_offset[REQ_URI_FID].second = URI_OFFSET + strlen(URI); + meta_offset[REQ_COOKIE_FID].first = COOKIE_OFFSET; + meta_offset[REQ_COOKIE_FID].second = COOKIE_OFFSET + strlen(NEW_COOKIE); } void init_hsession_new_fields() { - http_fields[REQ_AGENT_FID].field = USERAGENT; - http_fields[REQ_HOST_FID].field = HOST; - http_fields[REQ_REFERER_FID].field = REFERER; - http_fields[REQ_URI_FID].field = URI; - http_fields[REQ_COOKIE_FID].field = NEW_COOKIE; - http_fields[REQ_BODY_FID].field = REQ_BODY; - http_fields[RSP_CONTENT_TYPE_FID].field = CONTENT_TYPE; - http_fields[RSP_LOCATION_FID].field = LOCATION; - http_fields[RSP_BODY_FID].field = RSP_BODY; + set_field(REQ_AGENT_FID, new std::string(USERAGENT)); + set_field(REQ_HOST_FID, new std::string(HOST)); + set_field(REQ_REFERER_FID, new std::string(REFERER)); + set_field(REQ_URI_FID, new std::string(URI)); + set_field(REQ_COOKIE_FID, new std::string(COOKIE)); + set_field(REQ_BODY_FID, new std::string(REQ_BODY)); + set_field(RSP_CONTENT_TYPE_FID, new std::string(CONTENT_TYPE)); + set_field(RSP_LOCATION_FID, new std::string(LOCATION)); + set_field(RSP_BODY_FID, new std::string(RSP_BODY)); } void reset() { - 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; + for ( int i = 0; i < NUM_METADATA_FIELDS; i++) + { + delete meta_data[i]; + meta_data[i] = nullptr; + } } static AppIdHttpSession* init_http_session(AppIdSession& asd) diff --git a/src/network_inspectors/appid/tp_appid_utils.cc b/src/network_inspectors/appid/tp_appid_utils.cc index e185b56c3..561f9861e 100644 --- a/src/network_inspectors/appid/tp_appid_utils.cc +++ b/src/network_inspectors/appid/tp_appid_utils.cc @@ -50,6 +50,8 @@ using namespace std; using namespace snort; +typedef AppIdHttpSession::pair_t pair_t; + THREAD_LOCAL ProfileStats tpLibPerfStats; THREAD_LOCAL ProfileStats tpPerfStats; @@ -110,77 +112,75 @@ static inline void process_http_session(AppIdSession& asd, if (spdyRequestScheme && spdyRequestHost && spdyRequestPath ) { - static const char httpsScheme[] = "https"; - static const char httpScheme[] = "http"; - std::string url; - + std::string* url; if (asd.get_session_flags(APPID_SESSION_DECRYPTED) - && - memcmp(spdyRequestScheme->c_str(), httpScheme, - sizeof(httpScheme) - 1) == 0) + && *spdyRequestScheme == "http") { - url = httpsScheme; + url = new std::string("http://" + *spdyRequestHost + *spdyRequestPath); } else { - url = *spdyRequestScheme; + url = new std::string("https://" + *spdyRequestHost + *spdyRequestPath); } - if (hsession->get_url()) + if ( hsession->get_field(MISC_URL_FID) ) hsession->set_chp_finished(false); - url += "://" + *spdyRequestHost + *spdyRequestPath; - hsession->set_url(url.c_str()); + hsession->set_field(MISC_URL_FID, url); asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG; } if (spdyRequestHost) { - if (hsession->get_host()) + if (hsession->get_field(REQ_HOST_FID)) hsession->set_chp_finished(false); - 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, + hsession->set_field(REQ_HOST_FID, spdyRequestHost); + hsession->set_offset(REQ_HOST_FID, + attribute_data.spdy_request_host_begin(), attribute_data.spdy_request_host_end()); if (appidDebug->is_active()) LogMessage("AppIdDbg %s SPDY host (%u-%u) is %s\n", appidDebug->get_debug_session(), - hsession->get_field_offset(REQ_HOST_FID), - hsession->get_field_end_offset(REQ_HOST_FID), hsession->get_host()); + attribute_data.spdy_request_host_begin(), + attribute_data.spdy_request_host_end(), + hsession->get_field(REQ_HOST_FID)->c_str()); asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG; } if (spdyRequestPath) { - if (hsession->get_uri()) + if ( hsession->get_field(REQ_URI_FID) ) hsession->set_chp_finished(false); - 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()); + hsession->set_field(REQ_URI_FID, spdyRequestPath); + hsession->set_offset(REQ_URI_FID, + attribute_data.spdy_request_path_begin(), + attribute_data.spdy_request_path_end()); if (appidDebug->is_active()) LogMessage("AppIdDbg %s SPDY URI (%u-%u) is %s\n", appidDebug->get_debug_session(), - hsession->get_field_offset(REQ_URI_FID), - hsession->get_field_end_offset(REQ_URI_FID), hsession->get_uri()); + attribute_data.spdy_request_path_begin(), + attribute_data.spdy_request_path_end(), + hsession->get_field(REQ_URI_FID)->c_str()); } } else { if ( (field=attribute_data.http_request_host(own)) != nullptr ) { - if (hsession->get_host()) + if ( hsession->get_field(REQ_HOST_FID) ) if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT)) hsession->set_chp_finished(false); - 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()); + hsession->set_field(REQ_HOST_FID, field); + hsession->set_offset(REQ_HOST_FID, + attribute_data.http_request_host_begin(), + attribute_data.http_request_host_end()); if (appidDebug->is_active()) LogMessage("AppIdDbg %s HTTP host (%u-%u) is %s\n", - appidDebug->get_debug_session(), hsession->get_field_offset(REQ_HOST_FID), - hsession->get_field_end_offset(REQ_HOST_FID), field->c_str()); + appidDebug->get_debug_session(), + attribute_data.http_request_host_begin(), + attribute_data.http_request_host_end(), field->c_str() ); asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG; } @@ -188,7 +188,8 @@ static inline void process_http_session(AppIdSession& asd, { static const char httpScheme[] = "http://"; - if (hsession->get_url() and !asd.get_session_flags(APPID_SESSION_APP_REINSPECT)) + if (hsession->get_field(MISC_URL_FID) and !asd.get_session_flags( + APPID_SESSION_APP_REINSPECT)) hsession->set_chp_finished(false); // Change http to https if session was decrypted. @@ -201,58 +202,64 @@ static inline void process_http_session(AppIdSession& asd, // In all other cases field can be const string*. field->insert(4, 1, 's'); } - hsession->update_url(field); - + hsession->set_field(MISC_URL_FID, field); asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG; } if ( (field=attribute_data.http_request_uri(own)) != nullptr) { - if (hsession->get_uri()) + if ( hsession->get_field(REQ_URI_FID) ) if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT)) hsession->set_chp_finished(false); - 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()); + hsession->set_field(REQ_URI_FID, field); + hsession->set_offset(REQ_URI_FID, + attribute_data.http_request_uri_begin(), + attribute_data.http_request_uri_end()); if (appidDebug->is_active()) LogMessage("AppIdDbg %s URI (%u-%u) is %s\n", appidDebug->get_debug_session(), - hsession->get_field_offset(REQ_URI_FID), - hsession->get_field_end_offset(REQ_URI_FID), hsession->get_uri()); + attribute_data.http_request_uri_begin(), + attribute_data.http_request_uri_end(), + hsession->get_cfield(REQ_URI_FID)); } } // FIXIT-M: except for request/response, these cases are duplicate. if ( (field=attribute_data.http_request_via(own)) != nullptr ) { - if (hsession->get_via()) + if ( hsession->get_field(MISC_VIA_FID) ) if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT)) hsession->set_chp_finished(false); - hsession->update_via(field); + hsession->set_field(MISC_VIA_FID, field); asd.scan_flags |= SCAN_HTTP_VIA_FLAG; } else if ( (field=attribute_data.http_response_via(own)) != nullptr ) { - if (hsession->get_via()) + if ( hsession->get_field(MISC_VIA_FID) ) if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT)) hsession->set_chp_finished(false); - hsession->update_via(field); + hsession->set_field(MISC_VIA_FID, field); asd.scan_flags |= SCAN_HTTP_VIA_FLAG; } if ( (field=attribute_data.http_request_user_agent(own)) != nullptr ) { - if (hsession->get_user_agent()) + if (hsession->get_field(REQ_AGENT_FID) ) if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT)) hsession->set_chp_finished(false); - hsession->update_useragent(field); + hsession->set_field(REQ_AGENT_FID, field); + hsession->set_offset(REQ_AGENT_FID, + attribute_data.http_request_user_agent_begin(), + attribute_data.http_request_user_agent_end()); if (appidDebug->is_active()) LogMessage("AppIdDbg %s User Agent (%u-%u) is %s\n", - appidDebug->get_debug_session(), hsession->get_field_offset(REQ_AGENT_FID), - hsession->get_field_end_offset(REQ_AGENT_FID), hsession->get_user_agent()); + appidDebug->get_debug_session(), + attribute_data.http_request_user_agent_begin(), + attribute_data.http_request_user_agent_end(), + field->c_str()); asd.scan_flags |= SCAN_HTTP_USER_AGENT_FLAG; } @@ -276,11 +283,11 @@ static inline void process_http_session(AppIdSession& asd, if (appidDebug->is_active()) LogMessage("AppIdDbg %s HTTP response code is %s\n", appidDebug->get_debug_session(), field->c_str()); - if (hsession->get_response_code()) + if ( hsession->get_field(MISC_RESP_CODE_FID) ) if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT)) hsession->set_chp_finished(false); - hsession->update_response_code(field); + hsession->set_field(MISC_RESP_CODE_FID, field); } // Check to see if we've got an upgrade to HTTP/2 (if enabled). @@ -293,8 +300,9 @@ static inline void process_http_session(AppIdSession& asd, appidDebug->get_debug_session(),field->c_str()); if (asd.config->mod_config->http2_detection_enabled) - if ( hsession->get_response_code() - && (strncmp(hsession->get_response_code(), "101", 3) == 0) ) + { + const std::string* rc = hsession->get_field(MISC_RESP_CODE_FID); + if ( rc && *rc == "101" ) if (strncmp(field->c_str(), "h2c", 3) == 0) { if (appidDebug->is_active()) @@ -302,62 +310,60 @@ static inline void process_http_session(AppIdSession& asd, appidDebug->get_debug_session()); asd.is_http2 = true; } + } } if ( (field=attribute_data.http_request_referer(own)) != nullptr ) { - if (hsession->get_referer()) + if ( hsession->get_field(REQ_REFERER_FID) ) if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT)) hsession->set_chp_finished(false); - 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()); + hsession->set_field(REQ_REFERER_FID, field); + hsession->set_offset(REQ_REFERER_FID, + attribute_data.http_request_referer_begin(), + attribute_data.http_request_referer_end()); if (appidDebug->is_active()) - LogMessage("AppIdDbg %s Referrer (%u-%u) is %s\n", appidDebug->get_debug_session(), - hsession->get_field_offset(REQ_REFERER_FID), - hsession->get_field_end_offset(REQ_REFERER_FID), - hsession->get_referer()); + LogMessage("AppIdDbg %s Referer (%u-%u) is %s\n", appidDebug->get_debug_session(), + attribute_data.http_request_referer_begin(), + attribute_data.http_request_referer_end(), + hsession->get_cfield(REQ_REFERER_FID) ); } if ( (field=attribute_data.http_request_cookie(own)) != nullptr ) { - if (hsession->get_cookie()) + if ( hsession->get_field(REQ_COOKIE_FID) ) if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT)) hsession->set_chp_finished(false); - 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 - // attribute_data.httpRequestCookie = nullptr; - // attribute_data.httpRequestCookieOffset = 0; - // attribute_data.httpRequestCookieEndOffset = 0; + hsession->set_field(REQ_COOKIE_FID, field); + hsession->set_offset(REQ_COOKIE_FID, + attribute_data.http_request_cookie_begin(), + attribute_data.http_request_cookie_end()); if (appidDebug->is_active()) LogMessage("AppIdDbg %s Cookie (%u-%u) is %s\n", appidDebug->get_debug_session(), - hsession->get_field_offset(REQ_COOKIE_FID), - hsession->get_field_offset(REQ_COOKIE_FID), - hsession->get_cookie()); + attribute_data.http_request_cookie_begin(), + attribute_data.http_request_cookie_end(), + hsession->get_cfield(REQ_COOKIE_FID)); } if ( (field=attribute_data.http_response_content(own)) != nullptr ) { - if (hsession->get_content_type()) + if ( hsession->get_field(RSP_CONTENT_TYPE_FID) ) if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT)) hsession->set_chp_finished(false); - hsession->update_content_type(field); + hsession->set_field(RSP_CONTENT_TYPE_FID, field); asd.scan_flags |= SCAN_HTTP_CONTENT_TYPE_FLAG; } if (hsession->get_ptype_scan_count(RSP_LOCATION_FID) && (field=attribute_data.http_response_location(own)) != nullptr) { - if (hsession->get_location()) + if ( hsession->get_field(RSP_LOCATION_FID) ) if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT)) hsession->set_chp_finished(false); - - hsession->update_location(field); + hsession->set_field(RSP_LOCATION_FID, field); } if ( (field=attribute_data.http_request_body(own)) != nullptr ) @@ -365,20 +371,19 @@ static inline void process_http_session(AppIdSession& asd, if (appidDebug->is_active()) LogMessage("AppIdDbg %s Got a request body %s\n", appidDebug->get_debug_session(), field->c_str()); - if (hsession->get_req_body()) + if ( hsession->get_field(REQ_BODY_FID) ) if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT)) hsession->set_chp_finished(false); - hsession->update_req_body(field); + hsession->set_field(REQ_BODY_FID, field); } if (hsession->get_ptype_scan_count(RSP_BODY_FID) && (field=attribute_data.http_response_body(own)) != nullptr) { - if (hsession->get_body()) + if (hsession->get_field(RSP_BODY_FID) ) if (!asd.get_session_flags(APPID_SESSION_APP_REINSPECT)) hsession->set_chp_finished(false); - - hsession->update_body(field); + hsession->set_field(RSP_BODY_FID, field); } if (attribute_data.numXffFields) @@ -393,13 +398,13 @@ static inline void process_http_session(AppIdSession& asd, if ( (field=attribute_data.http_response_server(own)) != nullptr) { - hsession->update_server(field); + hsession->set_field(MISC_SERVER_FID, field); asd.scan_flags |= SCAN_HTTP_VENDOR_FLAG; } if ( (field=attribute_data.http_request_x_working_with(own)) != nullptr ) { - hsession->update_x_working_with(field); + hsession->set_field(MISC_XWW_FID, field); asd.scan_flags |= SCAN_HTTP_XWORKINGWITH_FLAG; } } @@ -416,38 +421,39 @@ static inline void process_rtmp(AppIdSession& asd, const string* field=0; - if (!hsession->get_url()) + if (!hsession->get_field(MISC_URL_FID)) { if ( (field=attribute_data.http_request_url(own)) != nullptr ) { - // hsession->set_url(field->c_str()); - hsession->update_url(field); + hsession->set_field(MISC_URL_FID, field); asd.scan_flags |= SCAN_HTTP_HOST_URL_FLAG; } } - if ( !asd.config->mod_config->referred_appId_disabled && !hsession->get_referer() ) + if ( !asd.config->mod_config->referred_appId_disabled && + !hsession->get_field(REQ_REFERER_FID) ) { if ( (field=attribute_data.http_request_referer(own)) != nullptr ) { - hsession->update_referer(field); + hsession->set_field(REQ_REFERER_FID, field); } } - if (hsession->get_url() || (confidence == 100 && + if (hsession->get_field(MISC_URL_FID) || (confidence == 100 && asd.session_packet_count > asd.config->mod_config->rtmp_max_packets)) { - if (hsession->get_url()) + const std::string* url; + if ( (url = hsession->get_field(MISC_URL_FID)) != nullptr ) { HttpPatternMatchers* http_matchers = HttpPatternMatchers::get_instance(); - - if ( ( ( http_matchers->get_appid_from_url(nullptr, hsession->get_url(), - nullptr, hsession->get_referer(), &client_id, &serviceAppId, + const char* referer = hsession->get_cfield(REQ_REFERER_FID); + if ( ( ( http_matchers->get_appid_from_url(nullptr, url->c_str(), + nullptr, referer, &client_id, &serviceAppId, &payload_id, &referred_payload_app_id, 1) ) || - ( http_matchers->get_appid_from_url(nullptr, hsession->get_url(), nullptr, - hsession->get_referer(), &client_id, &serviceAppId, &payload_id, - &referred_payload_app_id, 0) ) ) == 1 ) + ( http_matchers->get_appid_from_url(nullptr, url->c_str(), + nullptr, referer, &client_id, &serviceAppId, + &payload_id, &referred_payload_app_id, 0) ) ) == 1 ) { // do not overwrite a previously-set client or service if (client_id <= APP_ID_NONE) @@ -563,12 +569,14 @@ static inline void check_terminate_tp_module(AppIdSession& asd, uint16_t tpPktCo if ((tpPktCount >= asd.config->mod_config->max_tp_flow_depth) || (asd.get_session_flags(APPID_SESSION_HTTP_SESSION | APPID_SESSION_APP_REINSPECT) == (APPID_SESSION_HTTP_SESSION | APPID_SESSION_APP_REINSPECT) && - hsession->get_uri() && (!hsession->get_chp_candidate() || hsession->is_chp_finished()))) + hsession->get_field(REQ_URI_FID) && + (!hsession->get_chp_candidate() || hsession->is_chp_finished()))) { if (asd.get_tp_app_id() == APP_ID_NONE) asd.set_tp_app_id(APP_ID_UNKNOWN); - if ( asd.service_disco_state == APPID_DISCO_STATE_FINISHED && asd.payload.get_id() == APP_ID_NONE ) + if ( asd.service_disco_state == APPID_DISCO_STATE_FINISHED && asd.payload.get_id() == + APP_ID_NONE ) asd.payload.set_id(APP_ID_UNKNOWN); if (asd.tpsession) @@ -604,7 +612,8 @@ bool do_tp_discovery(AppIdSession& asd, IpProtocol protocol, Profile tpPerfStats_profile_context(tpPerfStats); //restart inspection by 3rd party - if (!asd.tp_reinspect_by_initiator && (direction == APP_ID_FROM_INITIATOR) && check_reinspect(p, asd)) + if (!asd.tp_reinspect_by_initiator && (direction == APP_ID_FROM_INITIATOR) && + check_reinspect(p, asd)) { asd.tp_reinspect_by_initiator = true; asd.set_session_flags(APPID_SESSION_APP_REINSPECT); @@ -637,7 +646,8 @@ bool do_tp_discovery(AppIdSession& asd, IpProtocol protocol, isTpAppidDiscoveryDone = true; - // First SSL decrypted packet is now being inspected. Reset the flag so that SSL decrypted + // First SSL decrypted packet is now being inspected. Reset the flag so that SSL + // decrypted // traffic gets processed like regular traffic from next packet onwards if (asd.get_session_flags(APPID_SESSION_APP_REINSPECT_SSL)) asd.clear_session_flags(APPID_SESSION_APP_REINSPECT_SSL); @@ -720,16 +730,17 @@ bool do_tp_discovery(AppIdSession& asd, IpProtocol protocol, asd.set_tp_payload_app_id(tp_app_id); // FIXIT-H commented out this part because it will never get executed - // need to make this function par with snort2x code, need to implement setTPAppIdData() and CheckDetectorCallback() + // need to make this function par with snort2x code, need to implement + // setTPAppIdData() and CheckDetectorCallback() // functions mainly. Set APP_ID_HTTP to asd's tp_session_id var from below tp_app_id = APP_ID_HTTP; // Handle HTTP tunneling and SSL possibly then being used in that tunnel - /* if (tp_app_id == APP_ID_HTTP_TUNNEL) - asd.set_payload_appid_data(APP_ID_HTTP_TUNNEL, NULL); - else if ((asd.payload.get_id() == APP_ID_HTTP_TUNNEL) && (tp_app_id == - APP_ID_SSL)) - asd.set_payload_appid_data(APP_ID_HTTP_SSL_TUNNEL, NULL);*/ + /* if (tp_app_id == APP_ID_HTTP_TUNNEL) + asd.set_payload_appid_data(APP_ID_HTTP_TUNNEL, NULL); + else if ((asd.payload.get_id() == APP_ID_HTTP_TUNNEL) && (tp_app_id == + APP_ID_SSL)) + asd.set_payload_appid_data(APP_ID_HTTP_SSL_TUNNEL, NULL);*/ hsession->process_http_packet(direction); @@ -816,7 +827,7 @@ bool do_tp_discovery(AppIdSession& asd, IpProtocol protocol, } if ( asd.tp_reinspect_by_initiator && check_reinspect(p, asd) ) { - if(isTpAppidDiscoveryDone) + if (isTpAppidDiscoveryDone) asd.clear_session_flags(APPID_SESSION_APP_REINSPECT); if (direction == APP_ID_FROM_RESPONDER) asd.tp_reinspect_by_initiator = false; //toggle at OK response