From: Shravan Rangarajuvenkata (shrarang) Date: Wed, 1 Apr 2020 15:36:11 +0000 (+0000) Subject: Merge pull request #2110 in SNORT/snort3 from ~OZAIKA/snort3:http2_get_header to... X-Git-Tag: 3.0.1-2~47 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9593d6095022faa30a0e8a677b617ab33561cebd;p=thirdparty%2Fsnort3.git Merge pull request #2110 in SNORT/snort3 from ~OZAIKA/snort3:http2_get_header to master Squashed commit of the following: commit 42d9ee1fa66cbfd4eda0f057b83a3b09fb3c3115 Author: Oleksii Zaika Date: Thu Mar 26 08:25:11 2020 -0400 appid: detect payload for first http2 stream --- diff --git a/src/network_inspectors/appid/app_info_table.h b/src/network_inspectors/appid/app_info_table.h index fae13486d..ca053d694 100644 --- a/src/network_inspectors/appid/app_info_table.h +++ b/src/network_inspectors/appid/app_info_table.h @@ -60,10 +60,8 @@ enum AppInfoFlags APPINFO_FLAG_PERSISTENT = (1<<10), APPINFO_FLAG_TP_CLIENT = (1<<11), APPINFO_FLAG_DEFER_PAYLOAD = (1<<12), - APPINFO_FLAG_SEARCH_ENGINE = (1<<13), - APPINFO_FLAG_SUPPORTED_SEARCH = (1<<14), - APPINFO_FLAG_CLIENT_DETECTOR_CALLBACK = (1<<15), - APPINFO_FLAG_SERVICE_DETECTOR_CALLBACK = (1<<16) + APPINFO_FLAG_CLIENT_DETECTOR_CALLBACK = (1<<13), + APPINFO_FLAG_SERVICE_DETECTOR_CALLBACK = (1<<14) }; class AppInfoTableEntry diff --git a/src/network_inspectors/appid/appid_discovery.cc b/src/network_inspectors/appid/appid_discovery.cc index 79ca46af3..e9fe0f34a 100644 --- a/src/network_inspectors/appid/appid_discovery.cc +++ b/src/network_inspectors/appid/appid_discovery.cc @@ -245,32 +245,12 @@ static bool set_network_attributes(AppIdSession* asd, Packet* p, IpProtocol& pro return true; } -static bool is_packet_ignored(AppIdSession* asd, Packet* p, AppidSessionDirection direction) +static bool is_packet_ignored(Packet* p) { if ( p->is_rebuilt() and !p->flow->is_proxied()) { - // 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 ) - { - AppIdHttpSession* hsession = asd->get_http_session(); - if ( direction == APP_ID_FROM_INITIATOR && hsession && hsession->is_rebuilt_offsets() ) - { - asd->ctxt.get_odp_ctxt().get_http_matchers().get_http_offsets(p, hsession); - if (appidDebug->is_active()) - { - 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(), - uri_start, uri_end, cookie_start, cookie_end); - } - } - appid_stats.ignored_packets++; - return true; - } + appid_stats.ignored_packets++; + return true; } return false; @@ -485,7 +465,7 @@ bool AppIdDiscovery::do_pre_discovery(Packet* p, AppIdSession** p_asd, AppIdInsp appidDebug->activate(p->flow, asd, inspector.get_ctxt().config.log_all_sessions); - if ( is_packet_ignored(asd, p, direction) ) + if ( is_packet_ignored(p) ) return false; uint64_t flow_flags; @@ -932,32 +912,6 @@ void AppIdDiscovery::do_post_discovery(Packet* p, AppIdSession& asd, asd.set_session_flags(APPID_SESSION_CONTINUE); } - // Set the field that the Firewall queries to see if we have a search engine - if (asd.search_support_type == UNKNOWN_SEARCH_ENGINE && payload_id > APP_ID_NONE) - { - uint flags = asd.ctxt.get_odp_ctxt().get_app_info_mgr().get_app_info_flags(payload_id, - APPINFO_FLAG_SEARCH_ENGINE | APPINFO_FLAG_SUPPORTED_SEARCH); - asd.search_support_type = - (flags & APPINFO_FLAG_SEARCH_ENGINE) ? - ((flags & APPINFO_FLAG_SUPPORTED_SEARCH) ? SUPPORTED_SEARCH_ENGINE : - UNSUPPORTED_SEARCH_ENGINE ) - : NOT_A_SEARCH_ENGINE; - if (appidDebug->is_active()) - { - const char* typeString; - const char *app_name = asd.ctxt.get_odp_ctxt().get_app_info_mgr().get_app_name(payload_id); - switch ( asd.search_support_type ) - { - case NOT_A_SEARCH_ENGINE: typeString = "NOT_A_SEARCH_ENGINE"; break; - case SUPPORTED_SEARCH_ENGINE: typeString = "SUPPORTED_SEARCH_ENGINE"; break; - case UNSUPPORTED_SEARCH_ENGINE: typeString = "UNSUPPORTED_SEARCH_ENGINE"; break; - default: typeString = "unknown"; break; - } - LogMessage("AppIdDbg %s Application: %s (%d) (safe)search_support_type=%s\n", - appidDebug->get_debug_session(), app_name ? app_name : "unknown", payload_id, typeString); - } - } - if ( service_id != APP_ID_NONE ) { if ( payload_id != asd.past_indicator and payload_id != APP_ID_NONE) diff --git a/src/network_inspectors/appid/appid_http_session.cc b/src/network_inspectors/appid/appid_http_session.cc index 54e0afdb7..d64670dc3 100644 --- a/src/network_inspectors/appid/appid_http_session.cc +++ b/src/network_inspectors/appid/appid_http_session.cc @@ -38,19 +38,6 @@ using namespace snort; -static const char* httpFieldName[ NUM_HTTP_FIELDS ] = // for use in debug messages -{ - "useragent", - "host", - "referer", - "uri", - "cookie", - "req_body", - "content_type", - "location", - "body", -}; - AppIdHttpSession::AppIdHttpSession(AppIdSession& asd) : asd(asd) { @@ -170,7 +157,7 @@ void AppIdHttpSession::set_tun_dest() free(url ); } -int AppIdHttpSession::initial_chp_sweep(ChpMatchDescriptor& cmd, HttpPatternMatchers& http_matchers) +bool AppIdHttpSession::initial_chp_sweep(ChpMatchDescriptor& cmd, HttpPatternMatchers& http_matchers) { CHPApp* cah = nullptr; @@ -186,7 +173,7 @@ int AppIdHttpSession::initial_chp_sweep(ChpMatchDescriptor& cmd, HttpPatternMatc if (cmd.match_tally.empty()) { free_chp_matches(cmd, MAX_KEY_PATTERN); - return 0; + return false; } int longest = 0; @@ -206,7 +193,7 @@ int AppIdHttpSession::initial_chp_sweep(ChpMatchDescriptor& cmd, HttpPatternMatc if ( !cah ) { free_chp_matches(cmd, MAX_KEY_PATTERN); - return 0; + return false; } /*************************************************************** @@ -248,7 +235,7 @@ int AppIdHttpSession::initial_chp_sweep(ChpMatchDescriptor& cmd, HttpPatternMatc asd.tpsession->clear_attr(TP_ATTR_COPY_RESPONSE_BODY); } - return 1; + return true; } void AppIdHttpSession::init_chp_match_descriptor(ChpMatchDescriptor& cmd) @@ -283,154 +270,133 @@ void AppIdHttpSession::process_chp_buffers(AppidChangeBits& change_bits, HttpPat chp_finished = true; // this is a failure case. } - if ( !chp_finished && chp_candidate ) - { - char* user = nullptr; - char* version = nullptr; + if (chp_finished or !chp_candidate) + return; - for (unsigned i = 0; i < NUM_HTTP_FIELDS; i++) - { - if ( !ptype_scan_counts[i] ) - continue; + char* user = nullptr; + char* version = nullptr; - if ( cmd.buffer[i] && cmd.length[i] ) - { - int num_found = 0; - cmd.cur_ptype = (HttpFieldIds)i; - AppId ret = http_matchers.scan_chp(cmd, &version, &user, &num_found, this, - asd.ctxt); - total_found += num_found; - if (!ret || num_found < ptype_req_counts[i]) - { - // No match at all or the required matches for the field was NOT made - if (!num_matches) - { - // num_matches == 0 means: all must succeed - // give up early - chp_candidate = 0; - break; - } - } - } - else if ( !num_matches ) - { - // num_matches == 0 means: all must succeed give up early - chp_candidate = 0; - break; - } + for (unsigned i = 0; i < NUM_HTTP_FIELDS; i++) + { + if ( !ptype_scan_counts[i] ) + continue; - // Decrement the expected scan count toward 0. - ptype_scan_counts[i] = 0; - num_scans--; - // if we have reached the end of the list of scans (which have something to do), then - // num_scans == 0 - if (num_scans == 0) + if ( cmd.buffer[i] && cmd.length[i] ) + { + int num_found = 0; + cmd.cur_ptype = (HttpFieldIds)i; + AppId ret = http_matchers.scan_chp(cmd, &version, &user, &num_found, this, asd.ctxt); + total_found += num_found; + if (!ret || num_found < ptype_req_counts[i]) { - // we finished the last scan - // either the num_matches value was zero and we failed early-on or we need to check - // for the min. - if (num_matches && - total_found < num_matches) + // No match at all or the required matches for the field was NOT made + if (!num_matches) { - // There was a minimum scans match count (num_matches != 0) - // And we did not reach that minimum + // num_matches == 0 means: all must succeed + // give up early chp_candidate = 0; break; } - // All required matches were met. - chp_finished = true; - break; } } - - // pass the index of last chp_matcher, not the length the array! - free_chp_matches(cmd, NUM_HTTP_FIELDS-1); - - if ( !chp_candidate ) + else if ( !num_matches ) { - chp_finished = true; - if ( version ) - { - snort_free(version); - version = nullptr; - } + // num_matches == 0 means: all must succeed give up early + chp_candidate = 0; + break; + } - if ( user ) + // Decrement the expected scan count toward 0. + ptype_scan_counts[i] = 0; + num_scans--; + // if we have reached the end of the list of scans (which have something to do), then + // num_scans == 0 + if (num_scans == 0) + { + // we finished the last scan + // either the num_matches value was zero and we failed early-on or we need to check + // for the min. + if (num_matches && total_found < num_matches) { - snort_free(user); - user = nullptr; + // There was a minimum scans match count (num_matches != 0) + // And we did not reach that minimum + chp_candidate = 0; + break; } + // All required matches were met. + chp_finished = true; + break; + } + } - cmd.free_rewrite_buffers(); - memset(ptype_scan_counts, 0, sizeof(ptype_scan_counts)); + // pass the index of last chp_matcher, not the length the array! + free_chp_matches(cmd, NUM_HTTP_FIELDS-1); - // Make it possible for other detectors to run. - skip_simple_detect = false; - return; + if ( !chp_candidate ) + { + chp_finished = true; + if ( version ) + { + snort_free(version); + version = nullptr; } - if (chp_candidate && chp_finished) + if ( user ) { - AppId chp_final = chp_alt_candidate ? chp_alt_candidate - : CHP_APPIDINSTANCE_TO_ID(chp_candidate); + snort_free(user); + user = nullptr; + } - if (app_type_flags & APP_TYPE_SERVICE) - asd.set_service_appid_data(chp_final, change_bits, version); + memset(ptype_scan_counts, 0, sizeof(ptype_scan_counts)); - if (app_type_flags & APP_TYPE_CLIENT) - asd.set_client_appid_data(chp_final, change_bits, version); + // Make it possible for other detectors to run. + skip_simple_detect = false; + return; + } - if ( app_type_flags & APP_TYPE_PAYLOAD ) - asd.set_payload_appid_data(chp_final, change_bits, version); + if (chp_finished) + { + AppId chp_final = chp_alt_candidate ? chp_alt_candidate + : CHP_APPIDINSTANCE_TO_ID(chp_candidate); - if ( version ) - { - snort_free(version); - version = nullptr; - } + if (app_type_flags & APP_TYPE_SERVICE) + asd.set_service_appid_data(chp_final, change_bits, version); - if ( user ) - { - if (app_type_flags & APP_TYPE_SERVICE) - asd.client.update_user(chp_final, user); - else - asd.client.update_user(asd.service.get_id(), user); - user = nullptr; - asd.set_session_flags(APPID_SESSION_LOGIN_SUCCEEDED); - } + if (app_type_flags & APP_TYPE_CLIENT) + asd.set_client_appid_data(chp_final, change_bits, version); - for (unsigned i = 0; i < NUM_HTTP_FIELDS; i++) - if ( cmd.chp_rewritten[i] ) - { - if (appidDebug->is_active()) - LogMessage("AppIdDbg %s Rewritten %s: %s\n", - appidDebug->get_debug_session(), - httpFieldName[i], cmd.chp_rewritten[i]); - - set_field((HttpFieldIds)i, (const uint8_t*)cmd.chp_rewritten[i], - strlen(cmd.chp_rewritten[i]), change_bits); - delete [] cmd.chp_rewritten[i]; - cmd.chp_rewritten[i] = nullptr; - } + if ( app_type_flags & APP_TYPE_PAYLOAD ) + asd.set_payload_appid_data(chp_final, change_bits, version); - chp_candidate = 0; - //if we're doing safesearch rewrites, we want to continue to hold the flow - if (!rebuilt_offsets) - chp_hold_flow = 0; - asd.scan_flags &= ~SCAN_HTTP_VIA_FLAG; - asd.scan_flags &= ~SCAN_HTTP_USER_AGENT_FLAG; - asd.scan_flags &= ~SCAN_HTTP_HOST_URL_FLAG; - memset(ptype_scan_counts, 0, sizeof(ptype_scan_counts)); + if ( version ) + { + snort_free(version); + version = nullptr; } - else /* if we have a candidate, but we're not finished */ + + if ( user ) { - if ( user ) - { - snort_free(user); - user = nullptr; - } + if (app_type_flags & APP_TYPE_SERVICE) + asd.client.update_user(chp_final, user); + else + asd.client.update_user(asd.service.get_id(), user); + user = nullptr; + asd.set_session_flags(APPID_SESSION_LOGIN_SUCCEEDED); + } - cmd.free_rewrite_buffers(); + chp_candidate = 0; + chp_hold_flow = 0; + asd.scan_flags &= ~SCAN_HTTP_VIA_FLAG; + asd.scan_flags &= ~SCAN_HTTP_USER_AGENT_FLAG; + asd.scan_flags &= ~SCAN_HTTP_HOST_URL_FLAG; + memset(ptype_scan_counts, 0, sizeof(ptype_scan_counts)); + } + else /* if we have a candidate, but we're not finished */ + { + if ( user ) + { + snort_free(user); + user = nullptr; } } } diff --git a/src/network_inspectors/appid/appid_http_session.h b/src/network_inspectors/appid/appid_http_session.h index 416ac7426..59ec8d8ca 100644 --- a/src/network_inspectors/appid/appid_http_session.h +++ b/src/network_inspectors/appid/appid_http_session.h @@ -159,12 +159,6 @@ public: void set_is_webdav(bool webdav) { is_webdav = webdav; } - bool is_rebuilt_offsets() const - { return rebuilt_offsets; } - - void set_rebuilt_offsets(bool use_rebuilt_offsets = false) - { rebuilt_offsets = use_rebuilt_offsets; } - AppId get_chp_candidate() const { return chp_candidate; } @@ -215,7 +209,7 @@ public: protected: void init_chp_match_descriptor(ChpMatchDescriptor& cmd); - int initial_chp_sweep(ChpMatchDescriptor&, HttpPatternMatchers&); + bool initial_chp_sweep(ChpMatchDescriptor&, HttpPatternMatchers&); void process_chp_buffers(AppidChangeBits&, HttpPatternMatchers&); void free_chp_matches(ChpMatchDescriptor& cmd, unsigned max_matches); void set_http_change_bits(AppidChangeBits& change_bits, HttpFieldIds id); @@ -241,7 +235,6 @@ protected: unsigned app_type_flags = 0; int num_matches = 0; int num_scans = 0; - bool rebuilt_offsets = false; bool skip_simple_detect = false; snort::SfIp* xff_addr = nullptr; const char** xffPrecedence = nullptr; diff --git a/src/network_inspectors/appid/appid_session.h b/src/network_inspectors/appid/appid_session.h index bd41420fe..d68c70ada 100644 --- a/src/network_inspectors/appid/appid_session.h +++ b/src/network_inspectors/appid/appid_session.h @@ -275,7 +275,6 @@ public: AppId past_forecast = APP_ID_NONE; bool is_http2 = false; - snort::SEARCH_SUPPORT_TYPE search_support_type = snort::UNKNOWN_SEARCH_ENGINE; bool in_expected_cache = false; static unsigned inspector_id; static std::mutex inferred_svcs_lock; diff --git a/src/network_inspectors/appid/appid_session_api.cc b/src/network_inspectors/appid/appid_session_api.cc index d95c2b142..340be1745 100644 --- a/src/network_inspectors/appid/appid_session_api.cc +++ b/src/network_inspectors/appid/appid_session_api.cc @@ -242,12 +242,6 @@ const char* AppIdSessionApi::get_netbios_name() return asd->netbios_name; } -SEARCH_SUPPORT_TYPE AppIdSessionApi::get_http_search() -{ - return (asd->search_support_type != UNKNOWN_SEARCH_ENGINE) ? - asd->search_support_type : NOT_A_SEARCH_ENGINE; -} - AppIdDnsSession* AppIdSessionApi::get_dns_session() { return asd->get_dns_session(); diff --git a/src/network_inspectors/appid/appid_session_api.h b/src/network_inspectors/appid/appid_session_api.h index ff4a6d6bb..cc38c51fd 100644 --- a/src/network_inspectors/appid/appid_session_api.h +++ b/src/network_inspectors/appid/appid_session_api.h @@ -143,15 +143,6 @@ struct FpSMBData uint32_t flags; }; -enum SEARCH_SUPPORT_TYPE -{ - NOT_A_SEARCH_ENGINE, - SUPPORTED_SEARCH_ENGINE, - UNSUPPORTED_SEARCH_ENGINE, - UNKNOWN_SEARCH_ENGINE, -}; - - class SO_PUBLIC AppIdSessionApi { public: @@ -180,7 +171,6 @@ public: SfIp* get_initiator_ip(); AppIdDnsSession* get_dns_session(); AppIdHttpSession* get_http_session(); - SEARCH_SUPPORT_TYPE get_http_search(); char* get_tls_host(); DHCPData* get_dhcp_fp_data(); void free_dhcp_fp_data(DHCPData*); 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 9b8d74eb4..f8bc420d7 100644 --- a/src/network_inspectors/appid/detector_plugins/http_url_patterns.cc +++ b/src/network_inspectors/appid/detector_plugins/http_url_patterns.cc @@ -413,8 +413,6 @@ void HttpPatternMatchers::remove_http_patterns_for_id(AppId id) { // Walk the list of all the patterns we have inserted, searching for this appIdInstance and // free them. - // The purpose is for the 14 and 15 to be used together to only set the - // APPINFO_FLAG_SEARCH_ENGINE flag // If the reserved pattern is not used, it is a mixed use case and should just behave normally. CHPListElement* chpa = nullptr; CHPListElement* prev_chpa = nullptr; @@ -823,52 +821,6 @@ static inline void free_matched_patterns(MatchedPatterns* mp) } } -static void rewrite_chp(const char* buf, int bs, int start, int psize, char* adata, - const char** outbuf, int insert) -{ - int maxs, bufcont, as; - char* copyPtr; - - // special behavior for insert vs. rewrite - if (insert) - { - // we don't want to insert a string that is already present - if (!adata || strcasestr((const char*)buf, adata)) - return; - - start += psize; - bufcont = start; - as = strlen(adata); - maxs = bs+as; - } - else - { - if (adata) - { - // we also don't want to replace a string with an identical one. - if (!strncmp(buf+start,adata,psize)) - return; - - as = strlen(adata); - } - else - as = 0; - - bufcont = start+psize; - maxs = bs+(as-psize); - } - - *outbuf = copyPtr = (char*)snort_calloc(maxs + 1); - memcpy(copyPtr, buf, start); - copyPtr += start; - if (adata) - { - memcpy(copyPtr, adata, as); - copyPtr += as; - } - memcpy(copyPtr, buf+bufcont, bs-bufcont); -} - static char* normalize_userid(char* user) { int percent_count = 0; @@ -975,8 +927,6 @@ void HttpPatternMatchers::scan_key_chp(ChpMatchDescriptor& cmd) AppId HttpPatternMatchers::scan_chp(ChpMatchDescriptor& cmd, char** version, char** user, int* total_found, AppIdHttpSession* hsession, const AppIdContext& ctxt) { - MatchedCHPAction* insert_sweep2 = nullptr; - bool inhibit_modify = false; AppId ret = APP_ID_NONE; unsigned pt = cmd.cur_ptype; @@ -1014,8 +964,6 @@ AppId HttpPatternMatchers::scan_chp(ChpMatchDescriptor& cmd, char** version, cha break; case ALTERNATE_APPID: // an "optional" action that doesn't count towards totals - case REWRITE_FIELD: // handled when the action completes successfully - case INSERT_FIELD: // handled when the action completes successfully break; } if ( !ret ) @@ -1041,39 +989,6 @@ AppId HttpPatternMatchers::scan_chp(ChpMatchDescriptor& cmd, char** version, cha *user = normalize_userid(*user); } break; - case REWRITE_FIELD: - if ( !inhibit_modify && !cmd.chp_rewritten[pt] ) - { - // The field supports rewrites, and a rewrite hasn't happened. - rewrite_chp(cmd.buffer[pt], cmd.length[pt], tmp.start_match_pos, match->psize, - match->action_data, &cmd.chp_rewritten[pt], 0); - (*total_found)++; - inhibit_modify = true; - } - break; - case INSERT_FIELD: - if ( !inhibit_modify && !insert_sweep2 ) - { - if (match->action_data) - { - // because this insert is the first one we have come across - // we only need to remember this ONE for later. - insert_sweep2 = &tmp; - } - else - { - // This is an attempt to "insert nothing"; call it a match - // The side effect is to set the inhibit_modify true - - // Note that an attempt to "rewrite with identical string" - // is NOT equivalent to an "insert nothing" because of case- - // insensitive pattern matching - - inhibit_modify = true; - (*total_found)++; - } - } - break; case ALTERNATE_APPID: hsession->set_chp_alt_candidate(strtol(match->action_data, nullptr, 10)); @@ -1084,12 +999,6 @@ AppId HttpPatternMatchers::scan_chp(ChpMatchDescriptor& cmd, char** version, cha hsession->set_chp_hold_flow(true); break; - case GET_OFFSETS_FROM_REBUILT: - hsession->set_rebuilt_offsets(true); - hsession->set_chp_hold_flow(true); - break; - - case SEARCH_UNSUPPORTED: case NO_ACTION: hsession->set_skip_simple_detect(true); break; @@ -1098,17 +1007,6 @@ AppId HttpPatternMatchers::scan_chp(ChpMatchDescriptor& cmd, char** version, cha } } - // non-nullptr insert_sweep2 indicates the insert action we will use. - if ( !inhibit_modify && insert_sweep2 && !cmd.chp_rewritten[pt] ) - { - // We will take the first INSERT_FIELD with an action string, - // which was decided with the setting of insert_sweep2. - rewrite_chp(cmd.buffer[pt], cmd.length[pt], insert_sweep2->start_match_pos, - insert_sweep2->mpattern->psize, insert_sweep2->mpattern->action_data, - &cmd.chp_rewritten[pt], 1); // insert - (*total_found)++; - } - cmd.chp_matches[pt].clear(); return ret; } 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 98aaabc77..b7bfb06cc 100644 --- a/src/network_inspectors/appid/detector_plugins/http_url_patterns.h +++ b/src/network_inspectors/appid/detector_plugins/http_url_patterns.h @@ -217,16 +217,6 @@ typedef std::vector CHPMatchTally; class ChpMatchDescriptor { public: - void free_rewrite_buffers() - { - for (unsigned i = 0; i < NUM_HTTP_FIELDS; i++) - if (chp_rewritten[i]) - { - snort_free((void*)chp_rewritten[i]); - chp_rewritten[i] = nullptr; - } - } - void sort_chp_matches() { chp_matches[cur_ptype].sort(ChpMatchDescriptor::comp_chp_actions); @@ -235,7 +225,6 @@ public: HttpFieldIds cur_ptype; 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; 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 5df4890f7..09fcddaef 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 @@ -59,7 +59,6 @@ static DetectorHTTPPattern mpattern; 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; void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { } AppIdDiscovery::AppIdDiscovery() { } @@ -179,68 +178,6 @@ TEST(http_url_patterns_tests, get_http_offsets) CHECK_EQUAL(true, test_find_all_done); } -TEST(http_url_patterns_tests, rewrite_chp_exist) -{ - // don't insert a string that is already present - my_buffer[REQ_AGENT_FID] = (const char*)"existing data"; - 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); - CHECK((char*)my_chp_rewritten == nullptr); -} - -TEST(http_url_patterns_tests, rewrite_chp_insert) -{ - // insert a string in my_chp_rewritten - 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); - STRCMP_EQUAL((const char*)my_chp_rewritten, (const char*)my_match.action_data); - snort_free(my_chp_rewritten); - my_chp_rewritten = nullptr; -} - -TEST(http_url_patterns_tests, rewrite_chp_same) -{ - // don't replace if they are same - my_chp_rewritten = nullptr; - 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); -} - -TEST(http_url_patterns_tests, rewrite_chp_replace_null) -{ - // replace null action data in my_chp_rewritten - my_chp_rewritten = nullptr; - my_buffer[REQ_AGENT_FID] = (const char*)"existing data"; - 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); - STRCMP_EQUAL((const char*)my_chp_rewritten, my_buffer[REQ_AGENT_FID]); - snort_free(my_chp_rewritten); - my_chp_rewritten = nullptr; -} - -TEST(http_url_patterns_tests, rewrite_chp_replace_non_null) -{ - // replace non-null action data in my_chp_rewritten - my_chp_rewritten = nullptr; - my_buffer[REQ_AGENT_FID] = (const char*)"existing data"; - 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); - STRCMP_EQUAL((const char*)my_chp_rewritten, (const char*)my_match.action_data); - snort_free(my_chp_rewritten); - my_chp_rewritten = nullptr; -} - TEST(http_url_patterns_tests, normalize_userid) { // no change @@ -324,66 +261,6 @@ TEST(http_url_patterns_tests, scan_chp_extract_user) user = nullptr; } -TEST(http_url_patterns_tests, scan_chp_rewrite_field) -{ - // testing REWRITE_FIELD - test_find_all_done = false; - cmd_test.cur_ptype = RSP_BODY_FID; - chpa_test.action_data = my_action_data; - chpa_test.appIdInstance = APP_ID_NONE; - chpa_test.action = REWRITE_FIELD; - chpa_test.psize = 1; - mchp.mpattern = &chpa_test; - mchp.start_match_pos = 0; - cmd_test.chp_matches[RSP_BODY_FID].emplace_back(mchp); - cmd_test.buffer[RSP_BODY_FID] = my_chp_data; - cmd_test.length[RSP_BODY_FID] = strlen(cmd_test.buffer[RSP_BODY_FID]); - CHECK(hm->scan_chp(cmd_test, &version, &user, &total_found, &hsession, ctxt) == APP_ID_NONE); - CHECK_EQUAL(true, test_find_all_done); - snort_free(const_cast(cmd_test.chp_rewritten[RSP_BODY_FID])); - cmd_test.chp_rewritten[RSP_BODY_FID] = nullptr; -} - -TEST(http_url_patterns_tests, scan_chp_insert_without_action) -{ - // testing INSERT_FIELD without action_data - test_find_all_done = false; - cmd_test.cur_ptype = RSP_BODY_FID; - chpa_test.action_data = nullptr; - chpa_test.appIdInstance = APP_ID_NONE; - chpa_test.action = INSERT_FIELD; - chpa_test.psize = 1; - mchp.mpattern = &chpa_test; - mchp.start_match_pos = 0; - cmd_test.chp_matches[RSP_BODY_FID].emplace_back(mchp); - cmd_test.buffer[RSP_BODY_FID] = my_chp_data; - cmd_test.length[RSP_BODY_FID] = strlen(cmd_test.buffer[RSP_BODY_FID]); - CHECK(hm->scan_chp(cmd_test, &version, &user, &total_found, &hsession, ctxt) == APP_ID_NONE); - CHECK_EQUAL(true, test_find_all_done); - snort_free(const_cast(cmd_test.chp_rewritten[RSP_BODY_FID])); - cmd_test.chp_rewritten[RSP_BODY_FID] = nullptr; -} - -TEST(http_url_patterns_tests, scan_chp_insert_with_action) -{ - // testing INSERT_FIELD with action_data - test_find_all_done = false; - cmd_test.cur_ptype = RSP_BODY_FID; - chpa_test.action_data = my_action_data; - chpa_test.appIdInstance = APP_ID_NONE; - chpa_test.action = INSERT_FIELD; - chpa_test.psize = 1; - mchp.mpattern = &chpa_test; - mchp.start_match_pos = 0; - cmd_test.chp_matches[RSP_BODY_FID].emplace_back(mchp); - cmd_test.buffer[RSP_BODY_FID] = my_chp_data; - cmd_test.length[RSP_BODY_FID] = strlen(cmd_test.buffer[RSP_BODY_FID]); - CHECK(hm->scan_chp(cmd_test, &version, &user, &total_found, &hsession, ctxt) == APP_ID_NONE); - CHECK_EQUAL(true, test_find_all_done); - snort_free(const_cast(cmd_test.chp_rewritten[RSP_BODY_FID])); - cmd_test.chp_rewritten[RSP_BODY_FID] = nullptr; -} - TEST(http_url_patterns_tests, scan_chp_hold_and_default) { // testing HOLD_FLOW diff --git a/src/network_inspectors/appid/lua_detector_api.cc b/src/network_inspectors/appid/lua_detector_api.cc index 7911089b7..7eabfc532 100644 --- a/src/network_inspectors/appid/lua_detector_api.cc +++ b/src/network_inspectors/appid/lua_detector_api.cc @@ -1441,16 +1441,29 @@ static inline int get_chp_pattern_data_and_size(lua_State* L, int index, char** return 0; } -static inline int get_chp_action_type(lua_State* L, int index, ActionType* action_type) +static inline int get_chp_action_type(lua_State* L, int index, ActionType& action_type) { - *action_type = (ActionType)lua_tointeger(L, index); - if (*action_type < NO_ACTION || *action_type > MAX_ACTION_TYPE) + action_type = (ActionType)lua_tointeger(L, index); + if (action_type < NO_ACTION || action_type > MAX_ACTION_TYPE) { WarningMessage( "LuaDetectorApi:Unsupported CHP Action type: %d, possible version mismatch.", - *action_type); + action_type); return -1; } + + switch (action_type) + { + case REWRITE_FIELD: + case INSERT_FIELD: + case SEARCH_UNSUPPORTED: + case GET_OFFSETS_FROM_REBUILT: + // Valid action types but not supported, silently ignore + return -1; + default: + break; + } + return 0; } @@ -1498,40 +1511,7 @@ static int add_chp_pattern_action(AppId appIdInstance, int isKeyPattern, HttpFie unsigned precedence = chpapp->ptype_scan_counts[patternType]++; // at runtime we'll want to know how many of each type of pattern we are looking for. - if (actionType == REWRITE_FIELD || actionType == INSERT_FIELD) - { - if (!odp_ctxt.get_app_info_mgr().get_app_info_flags(CHP_APPIDINSTANCE_TO_ID(appIdInstance), - APPINFO_FLAG_SUPPORTED_SEARCH)) - { - ErrorMessage( - "LuaDetectorApi: CHP action type, %d, requires previous use of action type, %d, (see appId %d, pattern=\"%s\").\n", - actionType, GET_OFFSETS_FROM_REBUILT, - CHP_APPIDINSTANCE_TO_ID(appIdInstance), patternData); - snort_free(patternData); - if (optionalActionData) - snort_free(optionalActionData); - return 0; - } - switch (patternType) - { - // permitted pattern type (modifiable HTTP/SPDY request field) - case REQ_AGENT_FID: - case REQ_HOST_FID: - case REQ_REFERER_FID: - case REQ_URI_FID: - case REQ_COOKIE_FID: - break; - default: - ErrorMessage( - "LuaDetectorApi: CHP action type, %d, on unsupported pattern type, %d, (see appId %d, pattern=\"%s\").\n", - actionType, patternType, CHP_APPIDINSTANCE_TO_ID(appIdInstance), patternData); - snort_free(patternData); - if (optionalActionData) - snort_free(optionalActionData); - return 0; - } - } - else if (actionType != ALTERNATE_APPID && actionType != DEFER_TO_SIMPLE_DETECT) + if (actionType != ALTERNATE_APPID && actionType != DEFER_TO_SIMPLE_DETECT) chpapp->ptype_req_counts[patternType]++; CHPListElement* chpa = (CHPListElement*)snort_calloc(sizeof(CHPListElement)); @@ -1546,16 +1526,7 @@ static int add_chp_pattern_action(AppId appIdInstance, int isKeyPattern, HttpFie chpa->chp_action.chpapp = chpapp; // link this struct to the Glossary entry odp_ctxt.get_http_matchers().insert_chp_pattern(chpa); - /* Set the safe-search bits in the appId entry */ - if (actionType == GET_OFFSETS_FROM_REBUILT) - odp_ctxt.get_app_info_mgr().set_app_info_flags(CHP_APPIDINSTANCE_TO_ID(appIdInstance), - APPINFO_FLAG_SEARCH_ENGINE | - APPINFO_FLAG_SUPPORTED_SEARCH); - else if (actionType == SEARCH_UNSUPPORTED) - odp_ctxt.get_app_info_mgr().set_app_info_flags(CHP_APPIDINSTANCE_TO_ID(appIdInstance), - APPINFO_FLAG_SEARCH_ENGINE); - else if (actionType == DEFER_TO_SIMPLE_DETECT && strcmp(patternData,"") == - 0) + if (actionType == DEFER_TO_SIMPLE_DETECT && strcmp(patternData,"") == 0) odp_ctxt.get_http_matchers().remove_http_patterns_for_id(appIdInstance); return 0; @@ -1591,7 +1562,7 @@ static int detector_add_chp_action(lua_State* L) return 0; // Parameter 5 - if (get_chp_action_type(L, ++index, &action)) + if (get_chp_action_type(L, ++index, action)) { snort_free(pattern); return 0; @@ -1681,7 +1652,7 @@ static int detector_add_chp_multi_action(lua_State* L) return 0; // Parameter 5 - if (get_chp_action_type(L, ++index, &action)) + if (get_chp_action_type(L, ++index, action)) { snort_free(pattern); return 0; diff --git a/src/network_inspectors/appid/test/appid_mock_session.h b/src/network_inspectors/appid/test/appid_mock_session.h index c42e5e785..96fa00a47 100644 --- a/src/network_inspectors/appid/test/appid_mock_session.h +++ b/src/network_inspectors/appid/test/appid_mock_session.h @@ -92,8 +92,6 @@ AppIdSession::AppIdSession(IpProtocol proto, const SfIp*, uint16_t, AppIdInspect service.set_version(APPID_UT_SERVICE_VERSION, change_bits); subtype = &APPID_UT_SERVICE_SUBTYPE; - search_support_type = UNKNOWN_SEARCH_ENGINE; - tsession = new TlsSession; service_ip.pton(AF_INET, APPID_UT_SERVICE_IP_ADDR); diff --git a/src/network_inspectors/appid/test/appid_session_api_test.cc b/src/network_inspectors/appid/test/appid_session_api_test.cc index 973378618..599e2f1d9 100644 --- a/src/network_inspectors/appid/test/appid_session_api_test.cc +++ b/src/network_inspectors/appid/test/appid_session_api_test.cc @@ -116,21 +116,6 @@ TEST(appid_session_api, get_service_port) } -TEST(appid_session_api, get_http_search) -{ - SEARCH_SUPPORT_TYPE val = appid_session_api->get_http_search(); - CHECK_TRUE(val == NOT_A_SEARCH_ENGINE); - mock_session->search_support_type = SUPPORTED_SEARCH_ENGINE; - val = appid_session_api->get_http_search(); - CHECK_TRUE(val == SUPPORTED_SEARCH_ENGINE); - mock_session->search_support_type = UNSUPPORTED_SEARCH_ENGINE; - val = appid_session_api->get_http_search(); - CHECK_TRUE(val == UNSUPPORTED_SEARCH_ENGINE); - mock_session->search_support_type = NOT_A_SEARCH_ENGINE; - val = appid_session_api->get_http_search(); - CHECK_TRUE(val == NOT_A_SEARCH_ENGINE); -} - TEST(appid_session_api, get_tls_host) { AppidChangeBits change_bits; diff --git a/src/pub_sub/http_events.cc b/src/pub_sub/http_events.cc index a54edfa34..8e23eb976 100644 --- a/src/pub_sub/http_events.cc +++ b/src/pub_sub/http_events.cc @@ -60,8 +60,13 @@ const uint8_t* HttpEvent::get_cookie(int32_t& length) const uint8_t* HttpEvent::get_host(int32_t& length) { - return get_header(HttpEnums::HTTP_BUFFER_HEADER, HttpEnums::HEAD_HOST, - length); + // Use Host header when available + const uint8_t* host_header = get_header(HttpEnums::HTTP_BUFFER_HEADER, + HttpEnums::HEAD_HOST, length); + if (length > 0) + return host_header; + // Otherwise use authority + return get_header(HttpEnums::HTTP_BUFFER_URI, HttpEnums::UC_HOST, length); } const uint8_t* HttpEvent::get_location(int32_t& length)