]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #4347: extractor: add support for referrer, origin, trans_depth
authorMaya Dagon (mdagon) <mdagon@cisco.com>
Wed, 3 Jul 2024 11:54:49 +0000 (11:54 +0000)
committerOleksii Shumeiko -X (oshumeik - SOFTSERVE INC at Cisco) <oshumeik@cisco.com>
Wed, 3 Jul 2024 11:54:49 +0000 (11:54 +0000)
Merge in SNORT/snort3 from ~MDAGON/snort3:fields to master

Squashed commit of the following:

commit ffe8836418d5ae42ccf17fd6c2a96893b8ff0709
Author: maya dagon <mdagon@cisco.com>
Date:   Thu Jun 6 13:11:10 2024 -0400

    extractor: support trans_depth, origin and referrer fields

commit 94b3c973e63f0c6e075b38f5d1d06cd152733c96
Author: maya dagon <mdagon@cisco.com>
Date:   Wed Jun 5 13:09:43 2024 -0400

    http_inspect: add origin header

commit 16ba900087769c5c5e9b587ed501dfdbdd294c90
Author: maya dagon <mdagon@cisco.com>
Date:   Fri May 31 14:43:41 2024 -0400

    extractor: support referrer field

src/network_inspectors/extractor/dev_notes.txt
src/network_inspectors/extractor/extractor_http_event_handler.cc
src/network_inspectors/extractor/extractor_service.cc
src/pub_sub/http_transaction_end_event.cc
src/pub_sub/http_transaction_end_event.h
src/service_inspectors/http_inspect/http_enum.h
src/service_inspectors/http_inspect/http_normalized_header.cc
src/service_inspectors/http_inspect/http_tables.cc
src/service_inspectors/http_inspect/http_transaction.cc

index a60ba928e2211524c88be2da0d9dfea66849a3bd..5f40acbbd95ad569a066e31c2df981cc50aa0967 100644 (file)
@@ -42,7 +42,10 @@ The following fields are supported for HTTP:
  * host
  * uri
  * user_agent
+ * referrer
+ * origin
  * version
  * status_code
  * status_msg
+ * trans_depth
 
index a133cfe05fd840abf4fe87bc30734a7d904288fd..4b3e27111a8bdc6dae7e6c8343dcf047dddc4194 100644 (file)
@@ -42,9 +42,12 @@ Value* get_method(DataEvent*, Packet*, Flow*);
 Value* get_host(DataEvent*, Packet*, Flow*);
 Value* get_user_agent(DataEvent*, Packet*, Flow*);
 Value* get_uri(DataEvent*, Packet*, Flow*);
+Value* get_referrer(DataEvent*, Packet*, Flow*);
+Value* get_origin(DataEvent*, Packet*, Flow*);
 Value* get_version(DataEvent*, Packet*, Flow*);
 Value* get_stat_code(DataEvent*, Packet*, Flow*);
 Value* get_stat_msg(DataEvent*, Packet*, Flow*);
+Value* get_trans_depth(DataEvent*, Packet*, Flow*);
 
 // Common
 Value* get_timestamp(DataEvent*, Packet*, Flow*);
@@ -92,6 +95,22 @@ Value* get_uri(DataEvent* event, Packet*, Flow*)
     return new Value(str.c_str());
 }
 
+Value* get_referrer(DataEvent* event, Packet*, Flow*)
+{
+    const Field& field = ((HttpTransactionEndEvent*)event)->get_referer_hdr();
+    std::string str;
+    field_to_string(field, str);
+    return new Value(str.c_str());
+}
+
+Value* get_origin(DataEvent* event, Packet*, Flow*)
+{
+    const Field& field = ((HttpTransactionEndEvent*)event)->get_origin_hdr();
+    std::string str;
+    field_to_string(field, str);
+    return new Value(str.c_str());
+}
+
 Value* get_version(DataEvent* event, Packet*, Flow*)
 {
     HttpEnums::VersionId version = ((HttpTransactionEndEvent*)event)->get_version();
@@ -119,6 +138,12 @@ Value* get_stat_msg(DataEvent* event, Packet*, Flow*)
     return new Value(str.c_str());
 }
 
+Value* get_trans_depth(DataEvent* event, Packet*, Flow*)
+{
+    const uint64_t trans_depth = ((HttpTransactionEndEvent*)event)->get_trans_depth();
+    return new Value(trans_depth);
+}
+
 Value* get_timestamp(DataEvent*, Packet* p, Flow*)
 {
     char u_sec[8];
@@ -173,9 +198,12 @@ static std::map<std::string, GetFunc> event_getters =
     {"host", get_host},
     {"uri", get_uri},
     {"user_agent", get_user_agent},
+    {"referrer", get_referrer},
+    {"origin", get_origin},
     {"version", get_version},
     {"status_code", get_stat_code},
     {"status_msg", get_stat_msg},
+    {"trans_depth", get_trans_depth}
 };
 
 void HttpExtractorEventHandler::handle(DataEvent& event, Flow* flow)
index 68ed292e3aa34bf3609989ec9da7951acafe5282..11c0ebc76cbbfe321509dbba78195f6412615b06 100644 (file)
@@ -150,9 +150,12 @@ ServiceBlueprint HttpExtractorService::blueprint =
       "host",
       "uri",
       "user_agent",
+      "referrer",
+      "origin",
       "version",
       "status_code",
       "status_msg",
+      "trans_depth"
     },
 };
 
index 78c972746ab5e5b02ddf0daa7d96a10230274770..0aa8e6829658f4791f25a269edf7a6e4fc53c238 100644 (file)
@@ -35,13 +35,33 @@ using namespace snort;
 HttpTransactionEndEvent::HttpTransactionEndEvent(const HttpTransaction* const trans)
     : transaction(trans) { }
 
-const Field& HttpTransactionEndEvent::get_host_hdr() const
+const Field& HttpTransactionEndEvent::get_client_header(uint64_t sub_id) const
 {
     HttpMsgHeader* headers = transaction->get_header(HttpCommon::SRC_CLIENT);
     if (headers == nullptr)
         return Field::FIELD_NULL;
 
-    return headers->get_classic_buffer(HttpEnums::HTTP_BUFFER_HEADER, HttpEnums::HEAD_HOST, 0);
+    return headers->get_classic_buffer(HttpEnums::HTTP_BUFFER_HEADER, sub_id, 0);
+}
+
+const Field& HttpTransactionEndEvent::get_host_hdr() const
+{
+    return get_client_header(HttpEnums::HEAD_HOST);
+}
+
+const Field& HttpTransactionEndEvent::get_user_agent() const
+{
+    return get_client_header(HttpEnums::HEAD_USER_AGENT);
+}
+
+const Field& HttpTransactionEndEvent::get_referer_hdr() const
+{
+    return get_client_header(HttpEnums::HEAD_REFERER);
+}
+
+const Field& HttpTransactionEndEvent::get_origin_hdr() const
+{
+    return get_client_header(HttpEnums::HEAD_ORIGIN);
 }
 
 const Field& HttpTransactionEndEvent::get_uri() const
@@ -76,15 +96,6 @@ const Field& HttpTransactionEndEvent::get_stat_msg() const
     return transaction->get_status()->get_reason_phrase();
 }
 
-const Field& HttpTransactionEndEvent::get_user_agent() const
-{
-    HttpMsgHeader* headers = transaction->get_header(HttpCommon::SRC_CLIENT);
-    if (headers == nullptr)
-        return Field::FIELD_NULL;
-
-    return headers->get_classic_buffer(HttpEnums::HTTP_BUFFER_HEADER, HttpEnums::HEAD_USER_AGENT, 0);
-}
-
 HttpEnums::VersionId HttpTransactionEndEvent::get_version() const
 {
     auto status = transaction->get_status();
@@ -92,3 +103,13 @@ HttpEnums::VersionId HttpTransactionEndEvent::get_version() const
         return HttpEnums::VERS__NOT_PRESENT;
     return status ? status->get_version_id() : transaction->get_request()->get_version_id();
 }
+
+uint64_t HttpTransactionEndEvent::get_trans_depth() const
+{
+    if (transaction->get_request() != nullptr)
+        return transaction->get_request()->get_transaction_id();
+    if (transaction->get_status() != nullptr)
+        return transaction->get_status()->get_transaction_id();
+
+    return 0;
+}
index 7cd4a056d1f516c2763d849b166401bb92041402..9fe6d4bc61e365d84639bda2fc1e9c76be62b118 100644 (file)
@@ -45,9 +45,14 @@ public:
     const Field& get_stat_code() const;
     const Field& get_stat_msg() const;
     const Field& get_user_agent() const;
+    const Field& get_referer_hdr() const;
+    const Field& get_origin_hdr() const;
     HttpEnums::VersionId get_version() const;
+    uint64_t get_trans_depth() const;
 
 private:
+    const Field& get_client_header(uint64_t sub_id) const;
+
     const HttpTransaction* const transaction;
 };
 }
index 457d80e018fd1295ccc6b661f8fec51e9d93f809..b9d3d85da10d45decec0b1036b6ef41298e5b366 100755 (executable)
@@ -155,7 +155,7 @@ enum HeaderId { HEAD__NOT_COMPUTE=-14, HEAD__PROBLEMATIC=-12, HEAD__NOT_PRESENT=
     HEAD_CONTENT_TYPE, HEAD_EXPIRES, HEAD_LAST_MODIFIED, HEAD_X_FORWARDED_FOR, HEAD_TRUE_CLIENT_IP,
     HEAD_X_WORKING_WITH, HEAD_CONTENT_TRANSFER_ENCODING, HEAD_MIME_VERSION, HEAD_PROXY_AGENT,
     HEAD_CONTENT_DISPOSITION, HEAD_HTTP2_SETTINGS, HEAD_RESTRICT_ACCESS_TO_TENANTS,
-    HEAD_RESTRICT_ACCESS_CONTEXT, HEAD__MAX_VALUE };
+    HEAD_RESTRICT_ACCESS_CONTEXT, HEAD_ORIGIN, HEAD__MAX_VALUE };
 
 // All the infractions we might find while parsing and analyzing a message
 enum Infraction
index a3febef1a96afde2a60f286694ebb4a5e14a7b18..37d2c5321d109f3e57c7f8d925b74b9c58347ca0 100644 (file)
@@ -165,6 +165,7 @@ const NormalizedHeader::HeaderNormalizer* const NormalizedHeader::header_norms[H
     &NORMALIZER_TOKEN_LIST, // HEAD_HTTP2_SETTINGS
     &NORMALIZER_BASIC,      // HEAD_RESTRICT_ACCESS_TO_TENANTS
     &NORMALIZER_BASIC,      // HEAD_RESTRICT_ACCESS_CONTEXT
+    &NORMALIZER_URI,        // HEAD_ORIGIN
     &NORMALIZER_BASIC,      // HEAD__MAX_VALUE
     &NORMALIZER_BASIC,      // HEAD_CUSTOM_XFF_HEADER
     &NORMALIZER_BASIC,      // HEAD_CUSTOM_XFF_HEADER
index be7827e933115d855e0e0fb802ff003a2bbe475e..f49a83955fc8d418b5dcea628326b4fd707f6bb3 100755 (executable)
@@ -142,6 +142,7 @@ const StrCode HttpMsgHeadShared::header_list[] =
     { HEAD_HTTP2_SETTINGS,             "http2-settings" },
     { HEAD_RESTRICT_ACCESS_TO_TENANTS, "restrict-access-to-tenants" },
     { HEAD_RESTRICT_ACCESS_CONTEXT,    "restrict-access-context" },
+    { HEAD_ORIGIN,                     "origin" },
     { 0,                               nullptr }
 };
 
index 29743754809256c1c07b39039ef48534ca615dbb..71e040adce59b8bc71602c409a08de11039b3ccd 100644 (file)
@@ -53,7 +53,8 @@ static void delete_section_list(HttpMsgSection* section_list)
     }
 }
 
-HttpTransaction::HttpTransaction(HttpFlowData* session_data_, snort::Flow* const f): session_data(session_data_), flow(f)
+HttpTransaction::HttpTransaction(HttpFlowData* session_data_, snort::Flow* const f)
+    : session_data(session_data_), flow(f)
 {
     infractions[0] = nullptr;
     infractions[1] = nullptr;