From: Michael Altizer (mialtize) Date: Fri, 16 Oct 2020 00:02:51 +0000 (+0000) Subject: Merge pull request #2483 in SNORT/snort3 from ~SUNIMUKH/snort3:vrf_ph2 to master X-Git-Tag: 3.0.3-3~15 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=03b04163db2745958eb45b00101124160df8b783;p=thirdparty%2Fsnort3.git Merge pull request #2483 in SNORT/snort3 from ~SUNIMUKH/snort3:vrf_ph2 to master Squashed commit of the following: commit a6066ad3964cd8f9e9287421bf3e74784e8606d5 Author: Sunirmal Mukherjee Date: Fri Sep 18 05:34:39 2020 -0400 packet: Added two new apis to parse ingress/egress group from packet's daq pkt_hdr commit 4be4fe1d00366a6783c0983721e3664aa49d95ca Author: Sunirmal Mukherjee Date: Mon Sep 14 10:03:31 2020 -0400 appid: Added service group and asid in AppIdServiceStateKey commit be8a7e982bed5463972190d148280e69e2a27238 Author: Sunirmal Mukherjee Date: Mon Sep 14 09:59:01 2020 -0400 port_scan: Added group and asid in PS_HASH_KEY commit 4de20e74a208b9a21db3cb53edfff35f85f4d340 Author: Sunirmal Mukherjee Date: Mon Sep 14 09:57:54 2020 -0400 dce_rpc: Added ingress/egress group and asid in SmbFlowKey, Smb2SidHashKey to identify a smb session uniquely commit 857248ede6fe26bc02cd3fd8b5e1e5a0c4c6b4a2 Author: Sunirmal Mukherjee Date: Mon Sep 14 09:56:43 2020 -0400 file_api: Added ingress/egress group and asid in FileHashKey --- diff --git a/src/file_api/file_cache.cc b/src/file_api/file_cache.cc index 0038a9425..bd6ffdc61 100644 --- a/src/file_api/file_cache.cc +++ b/src/file_api/file_cache.cc @@ -23,6 +23,7 @@ #include "file_cache.h" +#include "flow/flow_key.h" #include "hash/hash_defs.h" #include "hash/xhash.h" #include "log/messages.h" @@ -199,8 +200,11 @@ FileContext* FileCache::get_file(Flow* flow, uint64_t file_id, bool to_create, FileHashKey hashKey; hashKey.dip = flow->client_ip; hashKey.sip = flow->server_ip; - hashKey.padding = 0; + hashKey.dgroup = flow->client_group; + hashKey.sgroup = flow->server_group; hashKey.file_id = file_id; + hashKey.asid = flow->key->addressSpaceId; + hashKey.padding[0] = hashKey.padding[1] = hashKey.padding[2] = 0; FileContext* file = find(hashKey, timeout); if (to_create and !file) file = add(hashKey, timeout); diff --git a/src/file_api/file_cache.h b/src/file_api/file_cache.h index 4c56cf10d..44484a205 100644 --- a/src/file_api/file_cache.h +++ b/src/file_api/file_cache.h @@ -38,9 +38,12 @@ PADDING_GUARD_BEGIN struct FileHashKey { snort::SfIp sip; + int16_t sgroup; snort::SfIp dip; - uint32_t padding; + int16_t dgroup; uint64_t file_id; + uint16_t asid; + uint16_t padding[3]; }; PADDING_GUARD_END diff --git a/src/flow/test/ha_test.cc b/src/flow/test/ha_test.cc index 8fd5de850..d39433d3b 100644 --- a/src/flow/test/ha_test.cc +++ b/src/flow/test/ha_test.cc @@ -49,6 +49,7 @@ static const FlowKey s_test_key = 14, PktType::TCP, 14, + 0, 0 }; diff --git a/src/network_inspectors/appid/appid_api.cc b/src/network_inspectors/appid/appid_api.cc index 74ac5b31f..82877ae89 100644 --- a/src/network_inspectors/appid/appid_api.cc +++ b/src/network_inspectors/appid/appid_api.cc @@ -149,6 +149,7 @@ uint32_t AppIdApi::produce_ha_state(const Flow& flow, uint8_t* buf) else appHA->appId[6] = asd->get_client_id(); appHA->appId[7] = asd->misc_app_id; + appHA->asid = asd->asid; } else memset(appHA, 0, sizeof(*appHA)); @@ -170,7 +171,8 @@ uint32_t AppIdApi::consume_ha_state(Flow& flow, const uint8_t* buf, uint8_t, IpP AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME, true); if (inspector) { - asd = new AppIdSession(proto, ip, port, *inspector, inspector->get_ctxt().get_odp_ctxt()); + asd = new AppIdSession(proto, ip, port, *inspector, + inspector->get_ctxt().get_odp_ctxt(), appHA->asid); flow.set_flow_data(asd); asd->set_service_id(appHA->appId[1], asd->get_odp_ctxt()); if (asd->get_service_id() == APP_ID_FTP_CONTROL) diff --git a/src/network_inspectors/appid/appid_api.h b/src/network_inspectors/appid/appid_api.h index 41fcfdcfa..2e49a1887 100644 --- a/src/network_inspectors/appid/appid_api.h +++ b/src/network_inspectors/appid/appid_api.h @@ -40,6 +40,7 @@ namespace snort struct AppIdSessionHA { uint16_t flags; + uint16_t asid; AppId appId[APPID_HA_SESSION_APP_NUM_MAX]; }; diff --git a/src/network_inspectors/appid/appid_debug.cc b/src/network_inspectors/appid/appid_debug.cc index da2f31b4a..8034d61a7 100644 --- a/src/network_inspectors/appid/appid_debug.cc +++ b/src/network_inspectors/appid/appid_debug.cc @@ -36,7 +36,8 @@ THREAD_LOCAL AppIdDebug* appidDebug = nullptr; void AppIdDebug::activate(const uint32_t* ip1, const uint32_t* ip2, uint16_t port1, uint16_t port2, IpProtocol protocol, const int version, uint16_t address_space_id, - const AppIdSession* session, bool log_all_sessions) + const AppIdSession* session, bool log_all_sessions, int16_t group1, int16_t group2, + bool inter_group_flow) { if (!( log_all_sessions or ( info.proto_match(protocol) and @@ -52,6 +53,8 @@ void AppIdDebug::activate(const uint32_t* ip1, const uint32_t* ip2, uint16_t por const ip::snort_in6_addr* dip; uint16_t sport = 0; uint16_t dport = 0; + int16_t sgroup; + int16_t dgroup; char sipstr[INET6_ADDRSTRLEN]; char dipstr[INET6_ADDRSTRLEN]; @@ -61,6 +64,8 @@ void AppIdDebug::activate(const uint32_t* ip1, const uint32_t* ip2, uint16_t por dip = (const ip::snort_in6_addr*)ip2; sport = port1; dport = port2; + sgroup = group1; + dgroup = group2; } else if (session->initiator_port) { @@ -70,6 +75,8 @@ void AppIdDebug::activate(const uint32_t* ip1, const uint32_t* ip2, uint16_t por dip = (const ip::snort_in6_addr*)ip2; sport = port1; dport = port2; + sgroup = group1; + dgroup = group2; } else { @@ -77,6 +84,8 @@ void AppIdDebug::activate(const uint32_t* ip1, const uint32_t* ip2, uint16_t por dip = (const ip::snort_in6_addr*)ip1; sport = port2; dport = port1; + sgroup = group2; + dgroup = group1; } } else if (memcmp(session->get_initiator_ip().get_ip6_ptr(), @@ -86,6 +95,8 @@ void AppIdDebug::activate(const uint32_t* ip1, const uint32_t* ip2, uint16_t por dip = (const ip::snort_in6_addr*)ip2; sport = port1; dport = port2; + sgroup = group1; + dgroup = group2; } else { @@ -93,13 +104,20 @@ void AppIdDebug::activate(const uint32_t* ip1, const uint32_t* ip2, uint16_t por dip = (const ip::snort_in6_addr*)ip1; sport = port2; dport = port1; + sgroup = group2; + dgroup = group1; } snort_inet_ntop(af, &sip->u6_addr32[(af == AF_INET)? 3 : 0], sipstr, sizeof(sipstr)); snort_inet_ntop(af, &dip->u6_addr32[(af == AF_INET)? 3 : 0], dipstr, sizeof(dipstr)); - snprintf(debug_session, sizeof(debug_session), "%s %hu -> %s %hu %hhu AS=%hu ID=%u", + char gr_buf[32] = {0}; + if (inter_group_flow) + snprintf(gr_buf, sizeof(gr_buf), " GR=%hd-%hd", sgroup, dgroup); + + snprintf(debug_session, sizeof(debug_session), + "%s %hu -> %s %hu %hhu AS=%hu ID=%u%s", sipstr, sport, dipstr, dport, static_cast(protocol), - address_space_id, get_instance_id()); + address_space_id, get_instance_id(), gr_buf); } void AppIdDebug::activate(const Flow *flow, const AppIdSession* session, bool log_all_sessions) @@ -115,7 +133,8 @@ void AppIdDebug::activate(const Flow *flow, const AppIdSession* session, bool lo // (e.g., IPv4 src and IPv6 dst, or vice-versa). Once it is supported, we need to pass // two key->version here to create the proper debug_session string. activate(key->ip_l, key->ip_h, key->port_l, key->port_h, (IpProtocol)(key->ip_protocol), - key->version, key->addressSpaceId, session, log_all_sessions); + key->version, key->addressSpaceId, session, log_all_sessions, + key->group_l, key->group_h, key->flags.group_used); } void AppIdDebug::set_constraints(const char *desc, diff --git a/src/network_inspectors/appid/appid_debug.h b/src/network_inspectors/appid/appid_debug.h index ac8740293..c435d21a8 100644 --- a/src/network_inspectors/appid/appid_debug.h +++ b/src/network_inspectors/appid/appid_debug.h @@ -24,6 +24,8 @@ #include +#include + #include "protocols/ipv6.h" #include "protocols/protocol_ids.h" #include "main/thread.h" @@ -35,9 +37,9 @@ namespace snort class Flow; } -// %s %u -> %s %u %u AS=%u ID=%u -// IPv6 Port -> IPv6 Port Proto AS=ASNum ID=InstanceNum -#define APPID_DEBUG_SESSION_ID_SIZE ((39+1+5+1+2+1+39+1+5+1+3+1+2+1+10+1+2+1+10)+1) +// %s %u -> %s %u %u AS=%u ID=%u [GR=%hd-%hd] +// IPv6 Port -> IPv6 Port Proto AS=ASNum ID=InstanceNum [GR=SrcGroupNum-DstGroupNum] +#define APPID_DEBUG_SESSION_ID_SIZE ((39+1+5+1+2+1+39+1+5+1+3+1+2+1+10+1+2+1+10+32)+1) struct AppIdDebugSessionConstraints { @@ -83,7 +85,8 @@ public: void activate(const uint32_t* ip1, const uint32_t* ip2, uint16_t port1, uint16_t port2, IpProtocol protocol, const int version, uint16_t address_space_id, - const AppIdSession* session, bool log_all_sessions); + const AppIdSession* session, bool log_all_sessions, int16_t group1 = DAQ_PKTHDR_UNKNOWN, + int16_t group2 = DAQ_PKTHDR_UNKNOWN, bool inter_group_flow = false); void activate(const snort::Flow *flow, const AppIdSession* session, bool log_all_sessions); void set_constraints(const char *desc, const AppIdDebugSessionConstraints* constraints); diff --git a/src/network_inspectors/appid/appid_discovery.cc b/src/network_inspectors/appid/appid_discovery.cc index cc9d484af..9a6706579 100644 --- a/src/network_inspectors/appid/appid_discovery.cc +++ b/src/network_inspectors/appid/appid_discovery.cc @@ -497,19 +497,18 @@ bool AppIdDiscovery::do_pre_discovery(Packet* p, AppIdSession*& asd, AppIdInspec { uint16_t port = 0; const SfIp* ip = nullptr; + int16_t group; asd->set_session_flags(APPID_SESSION_SYN_RST); - if (asd->service_ip.is_set()) - { - ip = &asd->service_ip; - port = asd->service_port; - } + if (asd->is_service_ip_set()) + std::tie(ip, port, group) = asd->get_service_info(); else { ip = p->ptrs.ip_api.get_src(); port = p->ptrs.sp; + group = p->get_ingress_group(); } - AppIdServiceState::check_reset(*asd, ip, port); + AppIdServiceState::check_reset(*asd, ip, port, group, asd->asid); return false; } asd->previous_tcp_flags = p->ptrs.tcph->th_flags; diff --git a/src/network_inspectors/appid/appid_session.cc b/src/network_inspectors/appid/appid_session.cc index 699da59de..71a79e62b 100644 --- a/src/network_inspectors/appid/appid_session.cc +++ b/src/network_inspectors/appid/appid_session.cc @@ -84,7 +84,8 @@ AppIdSession* AppIdSession::allocate_session(const Packet* p, IpProtocol proto, (p->ptrs.sp != p->ptrs.dp)) port = (direction == APP_ID_FROM_INITIATOR) ? p->ptrs.sp : p->ptrs.dp; - AppIdSession* asd = new AppIdSession(proto, ip, port, *inspector, odp_context); + AppIdSession* asd = new AppIdSession(proto, ip, port, *inspector, odp_context, + p->pkth->address_space_id); asd->flow = p->flow; asd->stats.first_packet_second = p->pkth->ts.tv_sec; asd->snort_protocol_id = asd->config.snort_proto_ids[PROTO_INDEX_UNSYNCHRONIZED]; @@ -93,14 +94,14 @@ AppIdSession* AppIdSession::allocate_session(const Packet* p, IpProtocol proto, } AppIdSession::AppIdSession(IpProtocol proto, const SfIp* ip, uint16_t port, - AppIdInspector& inspector, OdpContext& odp_ctxt) + AppIdInspector& inspector, OdpContext& odp_ctxt, uint16_t asid) : FlowData(inspector_id, &inspector), config(inspector.get_ctxt().config), - protocol(proto), api(*(new AppIdSessionApi(this, *ip))), - odp_ctxt(odp_ctxt), tp_appid_ctxt(inspector.get_ctxt().get_tp_appid_ctxt()) + initiator_port(port), asid(asid), protocol(proto), + api(*(new AppIdSessionApi(this, *ip))), odp_ctxt(odp_ctxt), + odp_ctxt_version(odp_ctxt.get_version()), + tp_appid_ctxt(inspector.get_ctxt().get_tp_appid_ctxt()) { service_ip.clear(); - initiator_port = port; - odp_ctxt_version = odp_ctxt.get_version(); appid_stats.total_sessions++; } @@ -118,7 +119,8 @@ AppIdSession::~AppIdSession() APPID_SESSION_OOO) and flow) { ServiceDiscoveryState* sds = - AppIdServiceState::get(&service_ip, protocol, service_port, is_decrypted()); + AppIdServiceState::get(&service_ip, protocol, service_port, service_group, + asid, is_decrypted()); if (sds) { if (flow->server_ip.fast_eq6(service_ip)) @@ -190,7 +192,7 @@ AppIdSession* AppIdSession::create_future_session(const Packet* ctrlPkt, const S // FIXIT-RC - port parameter passed in as 0 since we may not know client port, verify AppIdSession* asd = new AppIdSession(proto, cliIp, 0, *inspector, - inspector->get_ctxt().get_odp_ctxt()); + inspector->get_ctxt().get_odp_ctxt(), ctrlPkt->pkth->address_space_id); if (Stream::set_snort_protocol_id_expected(ctrlPkt, type, proto, cliIp, cliPort, srvIp, srvPort, snort_protocol_id, asd, swap_app_direction)) diff --git a/src/network_inspectors/appid/appid_session.h b/src/network_inspectors/appid/appid_session.h index b6364058a..7d62d1ad7 100644 --- a/src/network_inspectors/appid/appid_session.h +++ b/src/network_inspectors/appid/appid_session.h @@ -25,8 +25,10 @@ #include #include #include +#include #include +#include #include "pub_sub/appid_events.h" #include "app_info_table.h" @@ -233,8 +235,8 @@ private: class AppIdSession : public snort::FlowData { public: - AppIdSession(IpProtocol, const snort::SfIp*, uint16_t port, - AppIdInspector&, OdpContext&); + AppIdSession(IpProtocol, const snort::SfIp*, uint16_t port, AppIdInspector&, + OdpContext&, uint16_t asid = 0); ~AppIdSession() override; static AppIdSession* allocate_session(const snort::Packet*, IpProtocol, @@ -251,13 +253,12 @@ public: std::unordered_map flow_data; uint64_t flags = 0; uint16_t initiator_port = 0; + uint16_t asid = 0; uint16_t session_packet_count = 0; uint16_t init_pkts_without_reply = 0; uint64_t init_bytes_without_reply = 0; - snort::SfIp service_ip; - uint16_t service_port = 0; IpProtocol protocol = IpProtocol::PROTO_NOT_SET; uint8_t previous_tcp_flags = 0; @@ -563,6 +564,28 @@ public: return tp_appid_ctxt; } + void set_service_info(const snort::SfIp& ip, uint16_t port, int16_t group = DAQ_PKTHDR_UNKNOWN) + { + service_ip = ip; + service_port = port; + service_group = group; + } + + std::tuple get_service_info() const + { + return std::make_tuple(&service_ip, service_port, service_group); + } + + uint16_t get_service_port() const + { + return service_port; + } + + bool is_service_ip_set() const + { + return service_ip.is_set(); + } + private: uint16_t prev_http2_raw_packet = 0; @@ -576,6 +599,10 @@ private: AppId tp_app_id = APP_ID_NONE; AppId tp_payload_app_id = APP_ID_NONE; + snort::SfIp service_ip; + uint16_t service_port = 0; + int16_t service_group = DAQ_PKTHDR_UNKNOWN; + uint16_t my_inferred_svcs_ver = 0; snort::AppIdSessionApi& api; static uint16_t inferred_svcs_ver; 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 0889e28fa..861ef9e51 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 @@ -151,7 +151,7 @@ AppIdConfig stub_config; AppIdContext stub_ctxt(stub_config); OdpContext stub_odp_ctxt(stub_config, nullptr); AppIdSession::AppIdSession(IpProtocol, const SfIp* ip, uint16_t, AppIdInspector& inspector, - OdpContext&) : snort::FlowData(inspector_id, (snort::Inspector*)&inspector), config(stub_config), + OdpContext&, uint16_t) : snort::FlowData(inspector_id, (snort::Inspector*)&inspector), config(stub_config), api(*(new AppIdSessionApi(this, *ip))), odp_ctxt(stub_odp_ctxt) { } AppIdSession::~AppIdSession() = default; AppIdHttpSession::AppIdHttpSession(AppIdSession& asd, uint32_t http2_stream_id) diff --git a/src/network_inspectors/appid/service_plugins/service_detector.cc b/src/network_inspectors/appid/service_plugins/service_detector.cc index c6b5024bf..7bd7c8f06 100644 --- a/src/network_inspectors/appid/service_plugins/service_detector.cc +++ b/src/network_inspectors/appid/service_plugins/service_detector.cc @@ -70,13 +70,12 @@ int ServiceDetector::service_inprocess(AppIdSession& asd, const Packet* pkt, App asd.get_session_flags(APPID_SESSION_IGNORE_HOST | APPID_SESSION_UDP_REVERSED)) return APPID_SUCCESS; - if (!asd.service_ip.is_set()) + if (!asd.is_service_ip_set()) { - asd.service_ip = *(pkt->ptrs.ip_api.get_src()); - if (!asd.service_port) - asd.service_port = pkt->ptrs.sp; + uint16_t port = asd.get_service_port(); + asd.set_service_info(*(pkt->ptrs.ip_api.get_src()), + port ? port : pkt->ptrs.sp, pkt->get_ingress_group()); } - return APPID_SUCCESS; } @@ -86,6 +85,7 @@ int ServiceDetector::update_service_data(AppIdSession& asd, const Packet* pkt, { uint16_t port = 0; const SfIp* ip = nullptr; + int16_t group; asd.service_detector = this; asd.set_service_vendor(vendor, change_bits); @@ -104,14 +104,16 @@ int ServiceDetector::update_service_data(AppIdSession& asd, const Packet* pkt, { ip = pkt->ptrs.ip_api.get_dst(); port = pkt->ptrs.dp; + group = pkt->get_egress_group(); } else { ip = pkt->ptrs.ip_api.get_src(); port = pkt->ptrs.sp; + group = pkt->get_ingress_group(); } - if (asd.service_port) - port = asd.service_port; + if (asd.get_service_port()) + port = asd.get_service_port(); } else { @@ -119,17 +121,20 @@ int ServiceDetector::update_service_data(AppIdSession& asd, const Packet* pkt, { ip = pkt->ptrs.ip_api.get_src(); port = pkt->ptrs.sp; + group = pkt->get_ingress_group(); } else { ip = pkt->ptrs.ip_api.get_dst(); port = pkt->ptrs.dp; + group = pkt->get_egress_group(); } } - asd.service_ip = *ip; - asd.service_port = port; - ServiceDiscoveryState* sds = AppIdServiceState::add(ip, asd.protocol, port, asd.is_decrypted()); + asd.set_service_info(*ip, port, group); + + ServiceDiscoveryState* sds = AppIdServiceState::add(ip, asd.protocol, port, + group, asd.asid, asd.is_decrypted()); sds->set_service_id_valid(this); return APPID_SUCCESS; diff --git a/src/network_inspectors/appid/service_plugins/service_discovery.cc b/src/network_inspectors/appid/service_plugins/service_discovery.cc index 790479c77..c6c284914 100644 --- a/src/network_inspectors/appid/service_plugins/service_discovery.cc +++ b/src/network_inspectors/appid/service_plugins/service_discovery.cc @@ -363,7 +363,8 @@ void ServiceDiscovery::get_next_service(const Packet* p, const AppidSessionDirec { asd.tried_reverse_service = true; ServiceDiscoveryState* rsds = AppIdServiceState::get(p->ptrs.ip_api.get_src(), - proto, p->ptrs.sp, asd.is_decrypted()); + proto, p->ptrs.sp, p->get_ingress_group(), p->pkth->address_space_id, + asd.is_decrypted()); std::unordered_map>::iterator urs_iterator; if ( rsds && rsds->get_service() ) asd.service_candidates.emplace_back(rsds->get_service()); @@ -397,34 +398,34 @@ int ServiceDiscovery::identify_service(AppIdSession& asd, Packet* p, bool got_brute_force = false; const SfIp* ip; uint16_t port; + int16_t group; /* Get packet info. */ auto proto = asd.protocol; - if ( asd.service_ip.is_set() ) - { - ip = &asd.service_ip; - port = asd.service_port; - } + if ( asd.is_service_ip_set() ) + std::tie(ip, port, group) = asd.get_service_info(); else { if ( dir == APP_ID_FROM_RESPONDER ) { ip = p->ptrs.ip_api.get_src(); port = p->ptrs.sp; + group = p->get_ingress_group(); } else { ip = p->ptrs.ip_api.get_dst(); port = p->ptrs.dp; + group = p->get_egress_group(); } - asd.service_ip = *ip; - asd.service_port = port; + asd.set_service_info(*ip, port, group); } if ( asd.service_search_state == SESSION_SERVICE_SEARCH_STATE::START ) { asd.service_search_state = SESSION_SERVICE_SEARCH_STATE::PORT; - sds = AppIdServiceState::add(ip, proto, port, asd.is_decrypted(), true); + sds = AppIdServiceState::add(ip, proto, port, group, asd.asid, + asd.is_decrypted(), true); sds->set_reset_time(0); ServiceState sds_state = sds->get_state(); @@ -524,7 +525,8 @@ int ServiceDiscovery::identify_service(AppIdSession& asd, Packet* p, !asd.service_detector and ( dir == APP_ID_FROM_RESPONDER ) ) ) { if (!sds) - sds = AppIdServiceState::add(ip, proto, port, asd.is_decrypted(), true); + sds = AppIdServiceState::add(ip, proto, port, group, asd.asid, + asd.is_decrypted(), true); // Don't log this if fail service is not due to empty list if (appidDebug->is_active() and !(got_fail_service and asd.service_detector)) LogMessage("AppIdDbg %s No service %s\n", appidDebug->get_debug_session(), @@ -545,7 +547,8 @@ int ServiceDiscovery::identify_service(AppIdSession& asd, Packet* p, tmp_ip = p->ptrs.ip_api.get_src(); if (!sds) - sds = AppIdServiceState::add(ip, proto, port, asd.is_decrypted(), true); + sds = AppIdServiceState::add(ip, proto, port, group, asd.asid, + asd.is_decrypted(), true); if (got_incompatible_service) sds->update_service_incompatiable(tmp_ip); @@ -753,16 +756,18 @@ int ServiceDiscovery::incompatible_data(AppIdSession& asd, const Packet* pkt, Ap } const SfIp* ip = pkt->ptrs.ip_api.get_src(); - uint16_t port = asd.service_port ? asd.service_port : pkt->ptrs.sp; + int16_t group = pkt->get_ingress_group(); + uint16_t port = asd.get_service_port(); + if (!port) + port = pkt->ptrs.sp; + ServiceDiscoveryState* sds = AppIdServiceState::add(ip, asd.protocol, port, - asd.is_decrypted()); // do not touch here + group, pkt->pkth->address_space_id, asd.is_decrypted()); // do not touch here sds->set_service(service); sds->set_reset_time(0); - if ( !asd.service_ip.is_set() ) - { - asd.service_ip = *ip; - asd.service_port = port; - } + if ( !asd.is_service_ip_set() ) + asd.set_service_info(*ip, port, group); + return APPID_SUCCESS; } @@ -796,16 +801,19 @@ int ServiceDiscovery::fail_service(AppIdSession& asd, const Packet* pkt, AppidSe } const SfIp* ip = pkt->ptrs.ip_api.get_src(); - uint16_t port = asd.service_port ? asd.service_port : pkt->ptrs.sp; - if (!asd.service_ip.is_set()) - { - asd.service_ip = *ip; - asd.service_port = port; - } + uint16_t port = asd.get_service_port(); + int16_t group = pkt->get_ingress_group(); + + if (!port) + port = pkt->ptrs.sp; + + if (!asd.is_service_ip_set()) + asd.set_service_info(*ip, port, group); if ( !sds ) { - sds = AppIdServiceState::add(ip, asd.protocol, port, asd.is_decrypted()); + sds = AppIdServiceState::add(ip, asd.protocol, port, group, + asd.asid, asd.is_decrypted()); sds->set_service(service); } sds->set_reset_time(0); diff --git a/src/network_inspectors/appid/service_plugins/test/service_plugin_mock.h b/src/network_inspectors/appid/service_plugins/test/service_plugin_mock.h index bb7ec22bf..3b45180b3 100644 --- a/src/network_inspectors/appid/service_plugins/test/service_plugin_mock.h +++ b/src/network_inspectors/appid/service_plugins/test/service_plugin_mock.h @@ -174,7 +174,7 @@ AppIdContext stub_ctxt(stub_config); static OdpContext stub_odp_ctxt(stub_config, nullptr); OdpContext* AppIdContext::odp_ctxt = &stub_odp_ctxt; AppIdSession::AppIdSession(IpProtocol, const SfIp* ip, uint16_t, AppIdInspector& inspector, - OdpContext&) : snort::FlowData(inspector_id, (snort::Inspector*)&inspector), + OdpContext&, uint16_t) : snort::FlowData(inspector_id, (snort::Inspector*)&inspector), config(stub_config), api(*(new AppIdSessionApi(this, *ip))), odp_ctxt(stub_odp_ctxt) { } AppIdSession::~AppIdSession() = default; void AppIdSession::free_flow_data() @@ -201,7 +201,8 @@ bool AppInfoManager::configured() { return true; } -ServiceDiscoveryState* AppIdServiceState::add(SfIp const*, IpProtocol, unsigned short, bool, bool) +ServiceDiscoveryState* AppIdServiceState::add(SfIp const*, IpProtocol, + unsigned short, int16_t, uint16_t, bool, bool) { return nullptr; } diff --git a/src/network_inspectors/appid/service_state.cc b/src/network_inspectors/appid/service_state.cc index e5947ee59..419acc5a0 100644 --- a/src/network_inspectors/appid/service_state.cc +++ b/src/network_inspectors/appid/service_state.cc @@ -213,20 +213,23 @@ void AppIdServiceState::clean() } ServiceDiscoveryState* AppIdServiceState::add(const SfIp* ip, IpProtocol proto, uint16_t port, - bool decrypted, bool do_touch) + int16_t group, uint16_t asid, bool decrypted, bool do_touch) { - return service_state_cache->add( AppIdServiceStateKey(ip, proto, port, decrypted), do_touch ); + return service_state_cache->add( AppIdServiceStateKey(ip, proto, port, group, + asid, decrypted), do_touch ); } ServiceDiscoveryState* AppIdServiceState::get(const SfIp* ip, IpProtocol proto, uint16_t port, - bool decrypted, bool do_touch) + int16_t group, uint16_t asid, bool decrypted, bool do_touch) { - return service_state_cache->get( AppIdServiceStateKey(ip, proto, port, decrypted), do_touch); + return service_state_cache->get( AppIdServiceStateKey(ip, proto, port, group, + asid, decrypted), do_touch); } -void AppIdServiceState::remove(const SfIp* ip, IpProtocol proto, uint16_t port, bool decrypted) +void AppIdServiceState::remove(const SfIp* ip, IpProtocol proto, uint16_t port, + int16_t group, uint16_t asid, bool decrypted) { - AppIdServiceStateKey ssk(ip, proto, port, decrypted); + AppIdServiceStateKey ssk(ip, proto, port, group, asid, decrypted); Map_t::iterator it = service_state_cache->find(ssk); if ( !service_state_cache->remove(it) ) @@ -239,17 +242,19 @@ void AppIdServiceState::remove(const SfIp* ip, IpProtocol proto, uint16_t port, } } -void AppIdServiceState::check_reset(AppIdSession& asd, const SfIp* ip, uint16_t port) +void AppIdServiceState::check_reset(AppIdSession& asd, const SfIp* ip, uint16_t port, + int16_t group, uint16_t asid) { ServiceDiscoveryState* sds = AppIdServiceState::get(ip, IpProtocol::TCP, port, - asd.is_decrypted()); + group, asid, asd.is_decrypted()); if ( sds ) { if ( !sds->get_reset_time() ) sds->set_reset_time(packet_time() ); else if ( ( packet_time() - sds->get_reset_time() ) >= 60 ) { - AppIdServiceState::remove(ip, IpProtocol::TCP, port, asd.is_decrypted()); + AppIdServiceState::remove(ip, IpProtocol::TCP, port, group, + asid, asd.is_decrypted()); // FIXIT-RC - Remove if this flag not used anywhere asd.set_session_flags(APPID_SESSION_SERVICE_DELETED); } diff --git a/src/network_inspectors/appid/service_state.h b/src/network_inspectors/appid/service_state.h index bf09e86f0..a29ef4d11 100644 --- a/src/network_inspectors/appid/service_state.h +++ b/src/network_inspectors/appid/service_state.h @@ -148,10 +148,14 @@ class AppIdServiceState public: static bool initialize(size_t memcap); static void clean(); - static ServiceDiscoveryState* add(const snort::SfIp*, IpProtocol, uint16_t port, bool decrypted, bool do_touch = false); - static ServiceDiscoveryState* get(const snort::SfIp*, IpProtocol, uint16_t port, bool decrypted, bool do_touch = false); - static void remove(const snort::SfIp*, IpProtocol, uint16_t port, bool decrypted); - static void check_reset(AppIdSession& asd, const snort::SfIp* ip, uint16_t port); + static ServiceDiscoveryState* add(const snort::SfIp*, IpProtocol, uint16_t port, + int16_t group, uint16_t asid, bool decrypted, bool do_touch = false); + static ServiceDiscoveryState* get(const snort::SfIp*, IpProtocol, uint16_t port, + int16_t group, uint16_t asid, bool decrypted, bool do_touch = false); + static void remove(const snort::SfIp*, IpProtocol, uint16_t port, + int16_t group, uint16_t asid, bool decrypted); + static void check_reset(AppIdSession& asd, const snort::SfIp* ip, uint16_t port, + int16_t group, uint16_t asid); static bool prune(size_t max_memory = 0, size_t num_items = -1u); }; @@ -160,24 +164,10 @@ PADDING_GUARD_BEGIN class AppIdServiceStateKey { public: - AppIdServiceStateKey() - { - ip.clear(); - port = 0; - level = 0; - proto = IpProtocol::PROTO_NOT_SET; - padding[0] = padding[1] = padding[2] = 0; - } - - AppIdServiceStateKey(const snort::SfIp* ip_in, - IpProtocol proto_in, uint16_t port_in, bool decrypted) - { - ip = *ip_in; - port = port_in; - level = decrypted != 0; - proto = proto_in; - padding[0] = padding[1] = padding[2] = 0; - } + AppIdServiceStateKey(const snort::SfIp* ip, + IpProtocol proto, uint16_t port, int16_t group, uint16_t asid, bool decrypted) : + ip(*ip), port(port), group(group), asid(asid), decrypted(decrypted), proto(proto) + { } bool operator<(const AppIdServiceStateKey& right) const { @@ -187,9 +177,10 @@ public: private: snort::SfIp ip; uint16_t port; - uint32_t level; + int16_t group; + uint16_t asid; + bool decrypted; IpProtocol proto; - uint8_t padding[3]; }; PADDING_GUARD_END diff --git a/src/network_inspectors/appid/test/appid_debug_test.cc b/src/network_inspectors/appid/test/appid_debug_test.cc index 5c23d2fc6..5c9592b08 100644 --- a/src/network_inspectors/appid/test/appid_debug_test.cc +++ b/src/network_inspectors/appid/test/appid_debug_test.cc @@ -61,9 +61,9 @@ OdpContext::~OdpContext() { } AppIdConfig stub_config; AppIdContext stub_ctxt(stub_config); OdpContext stub_odp_ctxt(stub_config, nullptr); -AppIdSession::AppIdSession(IpProtocol, const SfIp* ip, uint16_t, AppIdInspector&, OdpContext&) - : FlowData(0), config(stub_config), api(*(new AppIdSessionApi(this, *ip))), - odp_ctxt(stub_odp_ctxt) { } +AppIdSession::AppIdSession(IpProtocol, const SfIp* ip, uint16_t, AppIdInspector&, + OdpContext&, uint16_t) : FlowData(0), config(stub_config), + api(*(new AppIdSessionApi(this, *ip))), odp_ctxt(stub_odp_ctxt) { } AppIdSession::~AppIdSession() = default; // Utility functions diff --git a/src/network_inspectors/appid/test/appid_discovery_test.cc b/src/network_inspectors/appid/test/appid_discovery_test.cc index 7d6c064ee..9cad119ea 100644 --- a/src/network_inspectors/appid/test/appid_discovery_test.cc +++ b/src/network_inspectors/appid/test/appid_discovery_test.cc @@ -260,7 +260,8 @@ HostPortVal* HostPortCache::find(const SfIp*, uint16_t, IpProtocol, const OdpCon { return nullptr; } -void AppIdServiceState::check_reset(AppIdSession&, const SfIp*, uint16_t) {} +void AppIdServiceState::check_reset(AppIdSession&, const SfIp*, uint16_t, + int16_t, uint16_t) {} int dns_host_scan_hostname(const uint8_t*, size_t, AppId*, AppId*) { return 0; diff --git a/src/network_inspectors/appid/test/appid_http_session_test.cc b/src/network_inspectors/appid/test/appid_http_session_test.cc index b64de9c0f..b02f3ad76 100644 --- a/src/network_inspectors/appid/test/appid_http_session_test.cc +++ b/src/network_inspectors/appid/test/appid_http_session_test.cc @@ -108,8 +108,8 @@ static OdpContext stub_odp_ctxt(stub_config, nullptr); OdpContext* AppIdContext::odp_ctxt = &stub_odp_ctxt; // AppIdSession mock functions -AppIdSession::AppIdSession(IpProtocol, const SfIp* ip, uint16_t, AppIdInspector& inspector, OdpContext&) - : FlowData(inspector_id, &inspector), config(stub_config), +AppIdSession::AppIdSession(IpProtocol, const SfIp* ip, uint16_t, AppIdInspector& inspector, + OdpContext&, uint16_t) : FlowData(inspector_id, &inspector), config(stub_config), api(*(new AppIdSessionApi(this, *ip))), odp_ctxt(stub_odp_ctxt) {} @@ -150,7 +150,8 @@ bool AppIdSession::is_tp_appid_available() const // AppIdDebug mock functions void AppIdDebug::activate(const uint32_t*, const uint32_t*, uint16_t, - uint16_t, IpProtocol, const int, uint16_t, const AppIdSession*, bool) + uint16_t, IpProtocol, const int, uint16_t, const AppIdSession*, bool, + int16_t, int16_t, bool) { } diff --git a/src/network_inspectors/appid/test/appid_mock_definitions.h b/src/network_inspectors/appid/test/appid_mock_definitions.h index e0e6cca6f..46e4eec01 100644 --- a/src/network_inspectors/appid/test/appid_mock_definitions.h +++ b/src/network_inspectors/appid/test/appid_mock_definitions.h @@ -117,12 +117,14 @@ bool AppInfoManager::configured() { return false; } // Stubs for service_state.h -ServiceDiscoveryState* AppIdServiceState::get(SfIp const*, IpProtocol, unsigned short, bool, bool) +ServiceDiscoveryState* AppIdServiceState::get(SfIp const*, IpProtocol, + unsigned short, int16_t, uint16_t, bool, bool) { return nullptr; } -ServiceDiscoveryState* AppIdServiceState::add(SfIp const*, IpProtocol, unsigned short, bool, bool) +ServiceDiscoveryState* AppIdServiceState::add(SfIp const*, IpProtocol, + unsigned short, int16_t, uint16_t, bool, bool) { return nullptr; } diff --git a/src/network_inspectors/appid/test/appid_mock_session.h b/src/network_inspectors/appid/test/appid_mock_session.h index dcf295630..803da1b83 100644 --- a/src/network_inspectors/appid/test/appid_mock_session.h +++ b/src/network_inspectors/appid/test/appid_mock_session.h @@ -80,7 +80,7 @@ static AppIdContext stub_ctxt(stub_config); static OdpContext stub_odp_ctxt(stub_config, nullptr); OdpContext* AppIdContext::odp_ctxt = &stub_odp_ctxt; AppIdSession::AppIdSession(IpProtocol proto, const SfIp* ip, uint16_t, AppIdInspector& inspector, - OdpContext&) : FlowData(inspector_id, &inspector), config(stub_config), + OdpContext&, uint16_t) : FlowData(inspector_id, &inspector), config(stub_config), protocol(proto), api(*(new AppIdSessionApi(this, *ip))), odp_ctxt(stub_odp_ctxt) { odp_ctxt_version = odp_ctxt.get_version(); diff --git a/src/network_inspectors/appid/test/service_state_test.cc b/src/network_inspectors/appid/test/service_state_test.cc index cf6864707..ed16c4519 100644 --- a/src/network_inspectors/appid/test/service_state_test.cc +++ b/src/network_inspectors/appid/test/service_state_test.cc @@ -88,9 +88,9 @@ OdpContext::~OdpContext() { } AppIdConfig stub_config; AppIdContext stub_ctxt(stub_config); OdpContext stub_odp_ctxt(stub_config, nullptr); -AppIdSession::AppIdSession(IpProtocol, const SfIp* ip, uint16_t, AppIdInspector&, OdpContext&) - : FlowData(0), config(stub_config), api(*(new AppIdSessionApi(this, *ip))), - odp_ctxt(stub_odp_ctxt) { } +AppIdSession::AppIdSession(IpProtocol, const SfIp* ip, uint16_t, AppIdInspector&, + OdpContext&, uint16_t) : FlowData(0), config(stub_config), + api(*(new AppIdSessionApi(this, *ip))), odp_ctxt(stub_odp_ctxt) { } AppIdSession::~AppIdSession() = default; AppIdDiscovery::~AppIdDiscovery() {} void ClientDiscovery::initialize() { } @@ -210,8 +210,8 @@ TEST(service_state_tests, appid_service_state_key_comparison_test) IpProtocol proto = IpProtocol::TCP; uint16_t port=3000; - AppIdServiceStateKey A(&ip4, proto, port, 0); - AppIdServiceStateKey B(&ip6, proto, port, 0); + AppIdServiceStateKey A(&ip4, proto, port, 0, DAQ_PKTHDR_UNKNOWN, 0); + AppIdServiceStateKey B(&ip6, proto, port, 0, DAQ_PKTHDR_UNKNOWN, 0); // We must never be in a situation where !( Aptrs.ip_api.get_dst(); - asd.service_port = p->ptrs.dp; - } + asd.set_service_info(*(p->ptrs.ip_api.get_dst()), p->ptrs.dp, + p->get_egress_group()); else - { - asd.service_ip = *p->ptrs.ip_api.get_src(); - asd.service_port = p->ptrs.sp; - } + asd.set_service_info(*(p->ptrs.ip_api.get_src()), p->ptrs.sp, + p->get_ingress_group()); } } else if (asd.get_session_flags(APPID_SESSION_SSL_SESSION) && asd.tsession) diff --git a/src/network_inspectors/port_scan/ps_detect.cc b/src/network_inspectors/port_scan/ps_detect.cc index 3335bb399..28441a80c 100644 --- a/src/network_inspectors/port_scan/ps_detect.cc +++ b/src/network_inspectors/port_scan/ps_detect.cc @@ -55,6 +55,8 @@ struct PS_HASH_KEY int protocol; SfIp scanner; SfIp scanned; + int16_t group; + uint16_t asid; }; PADDING_GUARD_END @@ -323,6 +325,7 @@ bool PortScan::ps_tracker_lookup( return false; ps_pkt->proto = key.protocol; + key.asid = p->pkth->address_space_id; /* ** Let's lookup the host that is being scanned, taking into account @@ -334,9 +337,15 @@ bool PortScan::ps_tracker_lookup( key.scanner.clear(); if (ps_pkt->reverse_pkt) + { key.scanned = *p->ptrs.ip_api.get_src(); + key.group = p->get_ingress_group(); + } else + { key.scanned = *p->ptrs.ip_api.get_dst(); + key.group = p->get_egress_group(); + } *scanned = ps_tracker_get(&key); } @@ -347,9 +356,15 @@ bool PortScan::ps_tracker_lookup( key.scanned.clear(); if (ps_pkt->reverse_pkt) + { key.scanner = *p->ptrs.ip_api.get_dst(); + key.group = p->get_egress_group(); + } else + { key.scanner = *p->ptrs.ip_api.get_src(); + key.group = p->get_ingress_group(); + } *scanner = ps_tracker_get(&key); } diff --git a/src/protocols/packet.h b/src/protocols/packet.h index 2ce539704..345c47d90 100644 --- a/src/protocols/packet.h +++ b/src/protocols/packet.h @@ -332,6 +332,22 @@ struct SO_PUBLIC Packet uint16_t get_flow_vlan_id() const; + int16_t get_ingress_group() const + { + if (is_inter_group_flow()) + return pkth->ingress_group; + + return DAQ_PKTHDR_UNKNOWN; + } + + int16_t get_egress_group() const + { + if (is_inter_group_flow()) + return pkth->egress_group; + + return DAQ_PKTHDR_UNKNOWN; + } + private: bool allocated; }; diff --git a/src/service_inspectors/dce_rpc/dce_smb2.cc b/src/service_inspectors/dce_rpc/dce_smb2.cc index f324ad9b3..e9218b75a 100644 --- a/src/service_inspectors/dce_rpc/dce_smb2.cc +++ b/src/service_inspectors/dce_rpc/dce_smb2.cc @@ -68,6 +68,8 @@ static inline SmbFlowKey get_flow_key(void) key.mplsLabel = flow_key->mplsLabel; key.port_l = flow_key->port_l; key.port_h = flow_key->port_h; + key.group_l = flow_key->group_l; + key.group_h = flow_key->group_h; key.vlan_tag = flow_key->vlan_tag; key.addressSpaceId = flow_key->addressSpaceId; key.ip_protocol = flow_key->ip_protocol; diff --git a/src/service_inspectors/dce_rpc/dce_smb2.h b/src/service_inspectors/dce_rpc/dce_smb2.h index b8f5e3202..8caa9f383 100644 --- a/src/service_inspectors/dce_rpc/dce_smb2.h +++ b/src/service_inspectors/dce_rpc/dce_smb2.h @@ -231,7 +231,10 @@ struct Smb2SidHashKey uint32_t cip[4]; uint32_t sip[4]; uint64_t sid; - uint64_t padding; + int16_t cgroup; + int16_t sgroup; + uint16_t asid; + uint16_t padding; bool operator== (const Smb2SidHashKey &other) const { @@ -243,7 +246,10 @@ struct Smb2SidHashKey sip[0] == other.sip[0] and sip[1] == other.sip[1] and sip[2] == other.sip[2] and - sip[3] == other.sip[3]); + sip[3] == other.sip[3] and + cgroup == other.cgroup and + sgroup == other.sgroup and + asid == other.asid); } }; @@ -254,6 +260,8 @@ struct SmbFlowKey uint32_t mplsLabel; uint16_t port_l; /* Low Port - 0 if ICMP */ uint16_t port_h; /* High Port - 0 if ICMP */ + int16_t group_l; + int16_t group_h; uint16_t vlan_tag; uint16_t addressSpaceId; uint8_t ip_protocol; @@ -274,6 +282,8 @@ struct SmbFlowKey mplsLabel == other.mplsLabel and port_l == other.port_l and port_h == other.port_h and + group_l == other.group_l and + group_h == other.group_h and vlan_tag == other.vlan_tag and addressSpaceId == other.addressSpaceId and ip_protocol == other.ip_protocol and @@ -290,7 +300,7 @@ struct SmbKeyHash { size_t operator() (const SmbFlowKey& key) const { - return do_hash((const uint32_t*)&key); + return do_hash_flow_key((const uint32_t*)&key); } size_t operator() (const Smb2SidHashKey& key) const @@ -310,6 +320,18 @@ private: return c; } + size_t do_hash_flow_key(const uint32_t* d) const + { + uint32_t a, b, c; + a = b = c = SMB_KEY_HASH_HARDENER; + a += d[0]; b += d[1]; c += d[2]; mix(a, b, c); + a += d[3]; b += d[4]; c += d[5]; mix(a, b, c); + a += d[6]; b += d[7]; c += d[8]; mix(a, b, c); + a += d[9]; b += d[10]; c += d[11]; mix(a, b, c); + a += d[12]; finalize(a, b, c); + return c; + } + inline uint32_t rot(uint32_t x, unsigned k) const { return (x << k) | (x >> (32 - k)); } diff --git a/src/service_inspectors/dce_rpc/dce_smb2_utils.cc b/src/service_inspectors/dce_rpc/dce_smb2_utils.cc index efd95c14f..0666ca1bd 100644 --- a/src/service_inspectors/dce_rpc/dce_smb2_utils.cc +++ b/src/service_inspectors/dce_rpc/dce_smb2_utils.cc @@ -27,6 +27,7 @@ #include "dce_smb_utils.h" #include "dce_smb2_utils.h" #include "detection/detection_util.h" +#include "flow/flow_key.h" #include "main/snort_debug.h" using namespace snort; @@ -41,6 +42,9 @@ Smb2SidHashKey get_key(uint64_t sid) memcpy(key.cip, flow->client_ip.get_ip6_ptr(), 4*sizeof(uint32_t)); memcpy(key.sip, flow->server_ip.get_ip6_ptr(), 4*sizeof(uint32_t)); key.sid = sid; + key.cgroup = flow->client_group; + key.sgroup = flow->server_group; + key.asid = flow->key->addressSpaceId; key.padding = 0; return key; }