]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
new http refactoring and cleanup
authorRuss Combs <rucombs@cisco.com>
Tue, 7 Apr 2015 18:43:58 +0000 (14:43 -0400)
committerRuss Combs <rucombs@cisco.com>
Tue, 7 Apr 2015 18:43:58 +0000 (14:43 -0400)
29 files changed:
ChangeLog
src/detection/detection_util.h
src/service_inspectors/nhttp_inspect/nhttp_enum.h
src/service_inspectors/nhttp_inspect/nhttp_event_gen.h
src/service_inspectors/nhttp_inspect/nhttp_field.cc
src/service_inspectors/nhttp_inspect/nhttp_infractions.h
src/service_inspectors/nhttp_inspect/nhttp_inspect.cc
src/service_inspectors/nhttp_inspect/nhttp_inspect.h
src/service_inspectors/nhttp_inspect/nhttp_msg_body.cc
src/service_inspectors/nhttp_inspect/nhttp_msg_body.h
src/service_inspectors/nhttp_inspect/nhttp_msg_head_shared.cc
src/service_inspectors/nhttp_inspect/nhttp_msg_header.cc
src/service_inspectors/nhttp_inspect/nhttp_msg_header.h
src/service_inspectors/nhttp_inspect/nhttp_msg_request.cc
src/service_inspectors/nhttp_inspect/nhttp_msg_request.h
src/service_inspectors/nhttp_inspect/nhttp_msg_section.cc
src/service_inspectors/nhttp_inspect/nhttp_msg_section.h
src/service_inspectors/nhttp_inspect/nhttp_msg_start.cc
src/service_inspectors/nhttp_inspect/nhttp_msg_status.cc
src/service_inspectors/nhttp_inspect/nhttp_msg_status.h
src/service_inspectors/nhttp_inspect/nhttp_msg_trailer.cc
src/service_inspectors/nhttp_inspect/nhttp_msg_trailer.h
src/service_inspectors/nhttp_inspect/nhttp_normalizers.cc
src/service_inspectors/nhttp_inspect/nhttp_splitter.cc
src/service_inspectors/nhttp_inspect/nhttp_stream_splitter.cc
src/service_inspectors/nhttp_inspect/nhttp_transaction.cc
src/service_inspectors/nhttp_inspect/nhttp_transaction.h
src/service_inspectors/nhttp_inspect/nhttp_uri.cc
src/service_inspectors/nhttp_inspect/nhttp_uri_norm.cc

index f5e7b5990db2e34717a72488dd6aa98d3ed7f1e6..98674fa33713398f4b7bceab5b65548b321c6073 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,7 @@
 Pending - build 145
 
--- merge in new http changes: events from splitter plus additional
-   refactoring and cleanup
+-- new http refactoring and cleanup
+-- new http changes - events from splitter
 -- fix dns assertion; remove unused variables
 
 15/03/31 - build 144
index 60279b8f59a20edff871f87680967080ed751448..7538ccd2ecee20a0dcc4d151408594e390d7d234 100644 (file)
@@ -36,6 +36,8 @@
 #include "detect.h"
 #include "snort.h"
 #include "snort_debug.h"
+// FIXIT-L temporary
+#include "service_inspectors/nhttp_inspect/nhttp_inspect.h"
 
 #define DECODE_BLEN 65535
 
@@ -84,6 +86,8 @@ extern SO_PUBLIC THREAD_LOCAL DataPointer g_file_data;
 static inline void ClearHttpBuffers(void)
 {
     http_mask = 0;
+    // FIXIT-L temporary
+    NHttpInspect::latest_section = nullptr;
 }
 
 static inline uint32_t GetHttpBufferMask(void)
index 701240ff8a2f9bc7df32696ff720d4ad45586055..77e200681c51a8b4882a41ad6eec3600c2c75b11 100644 (file)
@@ -29,132 +29,111 @@ static const int DATABLOCKSIZE = 16384;
 static const uint32_t NHTTP_GID = 219;
 
 // Field status codes for when no valid value is present in length or integer value. Positive
-// values are actual length
-// or field value.
-typedef enum { STAT_NOSOURCE=-6, STAT_NOTCONFIGURED=-5, STAT_NOTCOMPUTE=-4, STAT_INSUFMEMORY=-3,
-               STAT_PROBLEMATIC=-2,
-               STAT_NOTPRESENT=-1, STAT_EMPTYSTRING=0, STAT_OTHER=1 } StatusCode;
+// values are actual length or field value.
+enum StatusCode { STAT_NOSOURCE=-6, STAT_NOTCONFIGURED=-5, STAT_NOTCOMPUTE=-4, STAT_INSUFMEMORY=-3,
+    STAT_PROBLEMATIC=-2, STAT_NOTPRESENT=-1, STAT_EMPTYSTRING=0, STAT_OTHER=1 };
 
 // Message originator--client or server
-typedef enum { SRC__NOTCOMPUTE=-4, SRC_CLIENT=0, SRC_SERVER=1 } SourceId;
+enum SourceId { SRC__NOTCOMPUTE=-4, SRC_CLIENT=0, SRC_SERVER=1 };
 
 // Type of message section
-typedef enum { SEC_DISCARD = -10, SEC_CLOSED = -9, SEC_ABORT = -8, SEC__NOTCOMPUTE=-4,
-               SEC__NOTPRESENT=-1,
-               SEC_REQUEST = 2, SEC_STATUS, SEC_HEADER, SEC_BODY, SEC_CHUNK,
-               SEC_TRAILER } SectionType;
+enum SectionType { SEC_DISCARD = -10, SEC_CLOSED = -9, SEC_ABORT = -8, SEC__NOTCOMPUTE=-4,
+    SEC__NOTPRESENT=-1, SEC_REQUEST = 2, SEC_STATUS, SEC_HEADER, SEC_BODY, SEC_CHUNK,
+    SEC_TRAILER };
 
 // Result of scanning by splitter
-typedef enum { SCAN_NOTFOUND, SCAN_FOUND, SCAN_DISCARD, SCAN_DISCARD_CONTINUE,
-               SCAN_ABORT } ScanResult;
+enum ScanResult { SCAN_NOTFOUND, SCAN_FOUND, SCAN_DISCARD, SCAN_DISCARD_CONTINUE, SCAN_ABORT };
 
 // Result of processing a message section--what needs to happen next
-typedef enum { RES_INSPECT, RES_IGNORE, RES_AGGREGATE } ProcessResult;
+enum ProcessResult { RES_INSPECT, RES_IGNORE, RES_AGGREGATE };
 
 // List of possible HTTP versions. Version 0.9 omitted because 0.9 predates creation of the
-// HTTP/X.Y token. There would
-// never be a message with "HTTP/0.9"
-typedef enum { VERS__NOSOURCE=-6, VERS__NOTCOMPUTE=-4, VERS__PROBLEMATIC=-2, VERS__NOTPRESENT=-1,
-               VERS__OTHER=1,
-               VERS_1_0, VERS_1_1, VERS_2_0 } VersionId;
+// HTTP/X.Y token. There would never be a message with "HTTP/0.9"
+enum VersionId { VERS__NOSOURCE=-6, VERS__NOTCOMPUTE=-4, VERS__PROBLEMATIC=-2, VERS__NOTPRESENT=-1,
+    VERS__OTHER=1, VERS_1_0, VERS_1_1, VERS_2_0 };
 
 // Every request method we have ever heard of
-typedef enum { METH__NOSOURCE=-6, METH__NOTCOMPUTE=-4, METH__INSUFMEMORY=-3, METH__PROBLEMATIC=-2,
-               METH__NOTPRESENT=-1,
-               METH__OTHER=1, METH_OPTIONS, METH_GET, METH_HEAD, METH_POST, METH_PUT, METH_DELETE,
-               METH_TRACE, METH_CONNECT,
-               METH_PROPFIND, METH_PROPPATCH, METH_MKCOL, METH_COPY, METH_MOVE, METH_LOCK,
-               METH_UNLOCK, METH_VERSION_CONTROL,
-               METH_REPORT, METH_CHECKOUT, METH_CHECKIN, METH_UNCHECKOUT, METH_MKWORKSPACE,
-               METH_UPDATE, METH_LABEL, METH_MERGE,
-               METH_BASELINE_CONTROL, METH_MKACTIVITY, METH_ORDERPATCH, METH_ACL, METH_PATCH,
-               METH_SEARCH, METH_BCOPY, METH_BDELETE,
-               METH_BMOVE, METH_BPROPFIND, METH_BPROPPATCH, METH_NOTIFY, METH_POLL, METH_SUBSCRIBE,
-               METH_UNSUBSCRIBE,
-               METH_X_MS_ENUMATTS, METH_BIND, METH_LINK, METH_MKCALENDAR, METH_MKREDIRECTREF,
-               METH_REBIND, METH_UNBIND, METH_UNLINK,
-               METH_UPDATEREDIRECTREF } MethodId;
+enum MethodId { METH__NOSOURCE=-6, METH__NOTCOMPUTE=-4, METH__INSUFMEMORY=-3, METH__PROBLEMATIC=-2,
+    METH__NOTPRESENT=-1, METH__OTHER=1, METH_OPTIONS, METH_GET, METH_HEAD, METH_POST, METH_PUT,
+    METH_DELETE, METH_TRACE, METH_CONNECT, METH_PROPFIND, METH_PROPPATCH, METH_MKCOL, METH_COPY,
+    METH_MOVE, METH_LOCK, METH_UNLOCK, METH_VERSION_CONTROL, METH_REPORT, METH_CHECKOUT,
+    METH_CHECKIN, METH_UNCHECKOUT, METH_MKWORKSPACE, METH_UPDATE, METH_LABEL, METH_MERGE,
+    METH_BASELINE_CONTROL, METH_MKACTIVITY, METH_ORDERPATCH, METH_ACL, METH_PATCH, METH_SEARCH,
+    METH_BCOPY, METH_BDELETE, METH_BMOVE, METH_BPROPFIND, METH_BPROPPATCH, METH_NOTIFY, METH_POLL,
+    METH_SUBSCRIBE, METH_UNSUBSCRIBE, METH_X_MS_ENUMATTS, METH_BIND, METH_LINK, METH_MKCALENDAR,
+    METH_MKREDIRECTREF, METH_REBIND, METH_UNBIND, METH_UNLINK, METH_UPDATEREDIRECTREF };
 
 // URI formats
-typedef enum { URI__NOSOURCE=-6, URI__NOTCOMPUTE=-4, URI__PROBLEMATIC=-2, URI_ASTERISK = 2,
-               URI_AUTHORITY, URI_ABSPATH,
-               URI_ABSOLUTE } UriType;
+enum UriType { URI__NOSOURCE=-6, URI__NOTCOMPUTE=-4, URI__PROBLEMATIC=-2, URI_ASTERISK = 2,
+    URI_AUTHORITY, URI_ABSPATH, URI_ABSOLUTE };
 
 // URI schemes
-typedef enum { SCH__NOSOURCE=-6, SCH__NOTCOMPUTE=-4, SCH__INSUFMEMORY=-3, SCH__NOTPRESENT=-1,
-               SCH_OTHER = 1, SCH_HTTP,
-               SCH_HTTPS, SCH_FTP, SCH_GOPHER, SCH_FILE } SchemeId;
+enum SchemeId { SCH__NOSOURCE=-6, SCH__NOTCOMPUTE=-4, SCH__INSUFMEMORY=-3, SCH__NOTPRESENT=-1,
+    SCH_OTHER = 1, SCH_HTTP, SCH_HTTPS, SCH_FTP, SCH_GOPHER, SCH_FILE };
 
 // Every header we have ever heard of
-typedef enum { HEAD__NOTCOMPUTE=-4, HEAD__INSUFMEMORY=-3, HEAD__PROBLEMATIC=-2, HEAD__NOTPRESENT=
-                   -1, HEAD__OTHER=1,
-               HEAD_CACHE_CONTROL, HEAD_CONNECTION, HEAD_DATE, HEAD_PRAGMA, HEAD_TRAILER,
-               HEAD_COOKIE, HEAD_SET_COOKIE,
-               HEAD_TRANSFER_ENCODING, HEAD_UPGRADE, HEAD_VIA, HEAD_WARNING, HEAD_ACCEPT,
-               HEAD_ACCEPT_CHARSET, HEAD_ACCEPT_ENCODING,
-               HEAD_ACCEPT_LANGUAGE, HEAD_AUTHORIZATION, HEAD_EXPECT, HEAD_FROM, HEAD_HOST,
-               HEAD_IF_MATCH, HEAD_IF_MODIFIED_SINCE,
-               HEAD_IF_NONE_MATCH, HEAD_IF_RANGE, HEAD_IF_UNMODIFIED_SINCE, HEAD_MAX_FORWARDS,
-               HEAD_PROXY_AUTHORIZATION, HEAD_RANGE,
-               HEAD_REFERER, HEAD_TE, HEAD_USER_AGENT, HEAD_ACCEPT_RANGES, HEAD_AGE, HEAD_ETAG,
-               HEAD_LOCATION, HEAD_PROXY_AUTHENTICATE,
-               HEAD_RETRY_AFTER, HEAD_SERVER, HEAD_VARY, HEAD_WWW_AUTHENTICATE, HEAD_ALLOW,
-               HEAD_CONTENT_ENCODING, HEAD_CONTENT_LANGUAGE,
-               HEAD_CONTENT_LENGTH, HEAD_CONTENT_LOCATION, HEAD_CONTENT_MD5, HEAD_CONTENT_RANGE,
-               HEAD_CONTENT_TYPE, HEAD_EXPIRES,
-               HEAD_LAST_MODIFIED, HEAD_X_FORWARDED_FOR, HEAD_TRUE_CLIENT_IP,
-               HEAD__MAXVALUE } HeaderId;
+enum HeaderId { HEAD__NOTCOMPUTE=-4, HEAD__INSUFMEMORY=-3, HEAD__PROBLEMATIC=-2,
+    HEAD__NOTPRESENT=-1, HEAD__OTHER=1, HEAD_CACHE_CONTROL, HEAD_CONNECTION, HEAD_DATE,
+    HEAD_PRAGMA, HEAD_TRAILER, HEAD_COOKIE, HEAD_SET_COOKIE, HEAD_TRANSFER_ENCODING, HEAD_UPGRADE,
+    HEAD_VIA, HEAD_WARNING, HEAD_ACCEPT, HEAD_ACCEPT_CHARSET, HEAD_ACCEPT_ENCODING,
+    HEAD_ACCEPT_LANGUAGE, HEAD_AUTHORIZATION, HEAD_EXPECT, HEAD_FROM, HEAD_HOST, HEAD_IF_MATCH,
+    HEAD_IF_MODIFIED_SINCE, HEAD_IF_NONE_MATCH, HEAD_IF_RANGE, HEAD_IF_UNMODIFIED_SINCE,
+    HEAD_MAX_FORWARDS, HEAD_PROXY_AUTHORIZATION, HEAD_RANGE, HEAD_REFERER, HEAD_TE,
+    HEAD_USER_AGENT, HEAD_ACCEPT_RANGES, HEAD_AGE, HEAD_ETAG, HEAD_LOCATION,
+    HEAD_PROXY_AUTHENTICATE, HEAD_RETRY_AFTER, HEAD_SERVER, HEAD_VARY, HEAD_WWW_AUTHENTICATE,
+    HEAD_ALLOW, HEAD_CONTENT_ENCODING, HEAD_CONTENT_LANGUAGE, HEAD_CONTENT_LENGTH,
+    HEAD_CONTENT_LOCATION, HEAD_CONTENT_MD5, HEAD_CONTENT_RANGE, HEAD_CONTENT_TYPE, HEAD_EXPIRES,
+    HEAD_LAST_MODIFIED, HEAD_X_FORWARDED_FOR, HEAD_TRUE_CLIENT_IP, HEAD__MAXVALUE };
 
 // All the infractions we might find while parsing and analyzing a message
-typedef enum
+enum Infraction
 {
     INF_TRUNCATED = 0,
-    INF_HEADTOOLONG,
-    INF_BADREQLINE,
-    INF_BADSTATLINE,
-    INF_TOOMANYHEADERS,
-    INF_BADHEADER,
-    INF_BADSTATCODE,
-    INF_UNKNOWNVERSION,
-    INF_BADVERSION,
-    INF_NOSCRATCH,
-    INF_BADHEADERREPS,
-    INF_BADHEADERDATA,
+    INF_HEAD_TOO_LONG,
+    INF_BAD_REQ_LINE,
+    INF_BAD_STAT_LINE,
+    INF_TOO_MANY_HEADERS,
+    INF_BAD_HEADER,
+    INF_BAD_STAT_CODE,
+    INF_UNKNOWN_VERSION,
+    INF_BAD_VERSION,
+    INF_NO_SCRATCH,
+    INF_BAD_HEADER_REPS,
+    INF_BAD_HEADER_DATA,
     INF_FIXIT_L_UNUSED,
-    INF_BADCHUNKSIZE,
-    INF_BADPHRASE,
-    INF_BADURI,
-    INF_BADPORT,
-    INF_URINEEDNORM,
-    INF_URIPERCENTNORMAL,
-    INF_URIPERCENTASCII,
-    INF_URIPERCENTUTF8,
-    INF_URIPERCENTUCODE,
-    INF_URIPERCENTOTHER,
-    INF_URIBADCHAR,
-    INF_URI8BITCHAR,
-    INF_URIMULTISLASH,
-    INF_URIBACKSLASH,
-    INF_URISLASHDOT,
-    INF_URISLASHDOTDOT,
-    INF_URIROOTTRAV,
-    INF_TOOMUCHLEADINGWS,
-    INF_ENDLESSHEADER,
-    INF_LFWITHOUTCR,
-} Infraction;
+    INF_BAD_CHUNK_SIZE,
+    INF_BAD_PHRASE,
+    INF_BAD_URI,
+    INF_BAD_PORT,
+    INF_URI_NEED_NORM,
+    INF_URI_PERCENT_NORMAL,
+    INF_URI_PERCENT_ASCII,
+    INF_URI_PERCENT_UTF8,
+    INF_URI_PERCENT_UCODE,
+    INF_URI_PERCENT_OTHER,
+    INF_URI_BAD_CHAR,
+    INF_URI_8BIT_CHAR,
+    INF_URI_MULTISLASH,
+    INF_URI_BACKSLASH,
+    INF_URI_SLASH_DOT,
+    INF_URI_SLASH_DOT_DOT,
+    INF_URI_ROOT_TRAV,
+    INF_TOO_MUCH_LEADING_WS,
+    INF_ENDLESS_HEADER,
+    INF_LF_WITHOUT_CR,
+};
 
 // Formats for output from a header normalization function
-typedef enum { NORM_NULL, NORM_FIELD, NORM_INT64, NORM_ENUM64, NORM_ENUM64LIST } NormFormat;
+enum NormFormat { NORM_NULL, NORM_FIELD, NORM_INT64, NORM_ENUM64, NORM_ENUM64LIST };
 
 // Types of character for URI scanning
-typedef enum { CHAR_NORMAL=2, CHAR_PERCENT, CHAR_PATH, CHAR_INVALID, CHAR_EIGHTBIT } CharAction;
+enum CharAction { CHAR_NORMAL=2, CHAR_PERCENT, CHAR_PATH, CHAR_INVALID, CHAR_EIGHTBIT };
 
 // Transfer codings
-typedef enum { TRANSCODE__OTHER=1, TRANSCODE_CHUNKED, TRANSCODE_IDENTITY, TRANSCODE_GZIP,
-               TRANSCODE_COMPRESS,
-               TRANSCODE_DEFLATE } Transcoding;
+enum Transcoding { TRANSCODE__OTHER=1, TRANSCODE_CHUNKED, TRANSCODE_IDENTITY, TRANSCODE_GZIP,
+    TRANSCODE_COMPRESS, TRANSCODE_DEFLATE };
 
-typedef enum
+enum EventSid
 {   // FIXIT-L limit 64 before code changes required
     EVENT_ASCII = 1,
     EVENT_DOUBLE_DECODE,
@@ -209,7 +188,7 @@ typedef enum
     EVENT_PDF_PARSE_FAILURE,
     EVENT_LOSS_OF_SYNC,
     EVENT_MAXVALUE
-} EventSid;
+};
 
 extern const int8_t as_hex[256];
 } // end namespace NHttpEnums
index 2aa9f407ab989d1f38725223fd42b44f4e8af550..c4914be0e9199d37d21b9c3dfedcf9af251e551d 100644 (file)
@@ -36,7 +36,7 @@ public:
     void reset() { events_generated = 0; }
     void create_event(NHttpEnums::EventSid sid)
     {
-        assert((sid > 0) && (sid <= 64));
+        assert(((int)sid > 0) && ((int)sid <= 64));
         if ((events_generated & (((uint64_t)1) << (sid-1))) == 0)
         {
             SnortEventqAdd(NHttpEnums::NHTTP_GID, (uint32_t)sid);
index 54cbfbfe3f3985cd5eba5d01a32ee224dd08ff44..4e5a5ea87b5bbe680da1f8064f0d0094741e84cc 100644 (file)
@@ -40,8 +40,8 @@ void Field::print(FILE* output, const char* name, bool int_vals) const
         fprintf(output, "\n");
         return;
     }
-    const int32_t print_length = (length <= 1200) ? length : 1200;    // Limit the amount of data
-                                                                      // printed
+    // Limit the amount of data printed
+    const int32_t print_length = (length <= 1200) ? length : 1200;
     for (int k=0; k < print_length; k++)
     {
         if ((start[k] >= 0x20) && (start[k] <= 0x7E))
index a4636fd0de8e6d6d5b5200c5adfc3b6c87c93afc..eabab65afb6d45a3895463aec495e8e57503c282 100644 (file)
@@ -30,7 +30,8 @@ class NHttpInfractions
 {
 public:
     NHttpInfractions() { }
-    NHttpInfractions(int inf) : infractions(((uint64_t)1) << inf) { assert((inf >= 0) && (inf < 64)); }
+    NHttpInfractions(int inf) : infractions(((uint64_t)1) << inf)
+      { assert((inf >= 0) && (inf < 64)); }
     void reset() { infractions = 0; }
     bool none_found() const { return infractions == 0; }
     NHttpInfractions& operator+=(const NHttpInfractions& rhs)
@@ -41,8 +42,8 @@ public:
         { return (lhs.infractions & rhs.infractions) != 0; }
 
     // The following method is for convenience of debug and test output only! The 64-bit
-    // implementation will not be big enough forever and this interface cannot be all over the
-    // code.
+    // implementation will not be big enough forever and this interface cannot be all over
+    // the code.
     uint64_t get_raw() const { return infractions; }
 
 private:
index 4538be2164e25c7aaa33a545cc4333e952ac3a5d..1b353561de5f2291ff06f679d96f0a21795d7159 100644 (file)
@@ -31,6 +31,7 @@
 #include "nhttp_msg_chunk.h"
 #include "nhttp_msg_trailer.h"
 #include "nhttp_test_manager.h"
+#include "nhttp_field.h"
 #include "nhttp_inspect.h"
 
 using namespace NHttpEnums;
@@ -47,6 +48,8 @@ NHttpInspect::NHttpInspect(bool test_input, bool test_output)
     }
 }
 
+THREAD_LOCAL NHttpMsgSection* NHttpInspect::latest_section = nullptr;
+
 bool NHttpInspect::get_buf(InspectionBuffer::Type ibt, Packet*, InspectionBuffer& b)
 {
     switch ( ibt )
@@ -67,15 +70,16 @@ bool NHttpInspect::get_buf(InspectionBuffer::Type ibt, Packet*, InspectionBuffer
 
 bool NHttpInspect::get_buf(unsigned id, Packet*, InspectionBuffer& b)
 {
-    const HttpBuffer* h = GetHttpBuffer((HTTP_BUFFER)id);
+    if (latest_section == nullptr)
+        return false;
 
-    if (!h)
-    {
+    const Field& legacy = latest_section->get_legacy(id);
+
+    if (legacy.length <= 0)
         return false;
-    }
 
-    b.data = h->buf;
-    b.len = h->length;
+    b.data = legacy.start;
+    b.len = legacy.length;
     return true;
 }
 
@@ -86,27 +90,25 @@ ProcessResult NHttpInspect::process(const uint8_t* data, const uint16_t dsize, F
         NHttpFlowData::nhttp_flow_id);
     assert(session_data != nullptr);
 
-    NHttpMsgSection* msg_section = nullptr;
-
     switch (session_data->section_type[source_id])
     {
     case SEC_REQUEST:
-        msg_section = new NHttpMsgRequest(data, dsize, session_data, source_id, buf_owner);
+        latest_section = new NHttpMsgRequest(data, dsize, session_data, source_id, buf_owner);
         break;
     case SEC_STATUS:
-        msg_section = new NHttpMsgStatus(data, dsize, session_data, source_id, buf_owner);
+        latest_section = new NHttpMsgStatus(data, dsize, session_data, source_id, buf_owner);
         break;
     case SEC_HEADER:
-        msg_section = new NHttpMsgHeader(data, dsize, session_data, source_id, buf_owner);
+        latest_section = new NHttpMsgHeader(data, dsize, session_data, source_id, buf_owner);
         break;
     case SEC_BODY:
-        msg_section = new NHttpMsgBody(data, dsize, session_data, source_id, buf_owner);
+        latest_section = new NHttpMsgBody(data, dsize, session_data, source_id, buf_owner);
         break;
     case SEC_CHUNK:
-        msg_section = new NHttpMsgChunk(data, dsize, session_data, source_id, buf_owner);
+        latest_section = new NHttpMsgChunk(data, dsize, session_data, source_id, buf_owner);
         break;
     case SEC_TRAILER:
-        msg_section = new NHttpMsgTrailer(data, dsize, session_data, source_id, buf_owner);
+        latest_section = new NHttpMsgTrailer(data, dsize, session_data, source_id, buf_owner);
         break;
     default:
         assert(0);
@@ -117,19 +119,13 @@ ProcessResult NHttpInspect::process(const uint8_t* data, const uint16_t dsize, F
         return RES_IGNORE;
     }
 
-    msg_section->analyze();
-    msg_section->update_flow();
-    msg_section->gen_events();
-
-    ProcessResult return_value = msg_section->worth_detection();
-    if (return_value == RES_INSPECT)
-    {
-        msg_section->legacy_clients();
-    }
+    latest_section->analyze();
+    latest_section->update_flow();
+    latest_section->gen_events();
 
     if (NHttpTestManager::use_test_output())
     {
-        msg_section->print_section(NHttpTestManager::get_output_file());
+        latest_section->print_section(NHttpTestManager::get_output_file());
         fflush(NHttpTestManager::get_output_file());
         if (NHttpTestManager::use_test_input())
         {
@@ -143,6 +139,6 @@ ProcessResult NHttpInspect::process(const uint8_t* data, const uint16_t dsize, F
         fflush(stdout);
     }
 
-    return return_value;
+    return latest_section->worth_detection();
 }
 
index 921e81fb8c28be6abb4128d2cb71ec8ecfa89eeb..068160d05fc6266725ffb5b10dcead9b3b4e0de1 100644 (file)
@@ -29,6 +29,7 @@
 #include "nhttp_stream_splitter.h"
 
 class NHttpApi;
+class NHttpMsgSection;
 
 class NHttpInspect : public Inspector
 {
@@ -48,6 +49,8 @@ public:
                NHttpStreamSplitter(is_client_to_server, this);
     }
 
+    static THREAD_LOCAL NHttpMsgSection* latest_section; // FIXIT-L temporarily public
+
 private:
     friend NHttpApi;
     friend NHttpStreamSplitter;
index b6b4eccd6f8e8014d000d62e45785fb3d5ac8384..42e4b6be0db56e34caed88863cde2cd7c763d59f 100644 (file)
@@ -47,6 +47,8 @@ void NHttpMsgBody::analyze()
 
     if (tcp_close && (body_octets < data_length))
         infractions += INF_TRUNCATED;
+    // FIXIT-L try to find a more logical location for this
+    set_file_data((uint8_t*)data.start, (unsigned)data.length);
 }
 
 void NHttpMsgBody::gen_events()
@@ -87,17 +89,3 @@ void NHttpMsgBody::update_flow()
     }
 }
 
-// Legacy support function. Puts message fields into the buffers used by old Snort.
-void NHttpMsgBody::legacy_clients()
-{
-    ClearHttpBuffers();
-    legacy_request();
-    legacy_status();
-    legacy_header(false);
-    if (data.length > 0)
-    {
-        SetHttpBuffer(HTTP_BUFFER_CLIENT_BODY, data.start, (unsigned)data.length);
-        set_file_data((uint8_t*)data.start, (unsigned)data.length);
-    }
-}
-
index a302063ebb00e81e93de65d326474858c3464351..5e4ef207128d55201f35c0c1bbf69f00d3c9672f 100644 (file)
@@ -36,7 +36,7 @@ public:
     void print_section(FILE* output) override;
     void gen_events() override;
     void update_flow() override;
-    void legacy_clients() override;
+    Field& get_data() { return data; }
 
 protected:
     int64_t data_length; // FIXIT-M this has no meaning in chunk subclass. Potential source of errors.
index 1b2b9d527660bed127237baaa9ebdb692b9b270b..56a2a41c7a938d0984bed50be8a0dfd4de48082e 100644 (file)
@@ -62,7 +62,7 @@ void NHttpMsgHeadShared::parse_header_block()
     }
     if (bytes_used < msg_text.length)
     {
-        infractions += INF_TOOMANYHEADERS;
+        infractions += INF_TOO_MANY_HEADERS;
     }
 }
 
@@ -118,7 +118,7 @@ void NHttpMsgHeadShared::parse_header_lines()
         }
         else
         {
-            infractions += INF_BADHEADER;
+            infractions += INF_BAD_HEADER;
         }
     }
 }
@@ -129,7 +129,7 @@ void NHttpMsgHeadShared::derive_header_name_id(int index)
     uint8_t* lower_name;
     if ((lower_name = scratch_pad.request(header_name[index].length)) == nullptr)
     {
-        infractions += INF_NOSCRATCH;
+        infractions += INF_NO_SCRATCH;
         header_name_id[index] = HEAD__INSUFMEMORY;
         return;
     }
@@ -149,7 +149,7 @@ const Field& NHttpMsgHeadShared::get_header_value_norm(NHttpEnums::HeaderId head
 
 void NHttpMsgHeadShared::gen_events()
 {
-    if (infractions && INF_TOOMANYHEADERS)
+    if (infractions && INF_TOO_MANY_HEADERS)
         events.create_event(EVENT_MAX_HEADERS);
 }
 
index 8a5c2773f742179191a85b43bfba9184df619b86..7cb55c5ff217097c8962acc51d3022b268836bb0 100644 (file)
@@ -54,8 +54,6 @@ void NHttpMsgHeader::print_section(FILE* output)
 
 void NHttpMsgHeader::update_flow()
 {
-    const uint64_t disaster_mask = 0;
-
     // The following logic to determine body type is by no means the last word on this topic.
     // FIXIT-H need to distinguish methods such as POST that should have a body from those that
     // should not.
@@ -66,11 +64,6 @@ void NHttpMsgHeader::update_flow()
         session_data->type_expected[source_id] = SEC_CLOSED;
         session_data->half_reset(source_id);
     }
-    else if (infractions && disaster_mask)
-    {
-        session_data->type_expected[source_id] = SEC_ABORT;
-        session_data->half_reset(source_id);
-    }
     else if ((source_id == SRC_SERVER) && ((status_code_num <= 199) || (status_code_num == 204) ||
         (status_code_num == 304)))
     {
@@ -139,12 +132,3 @@ ProcessResult NHttpMsgHeader::worth_detection()
            ? RES_INSPECT : RES_IGNORE;
 }
 
-// Legacy support function. Puts message fields into the buffers used by old Snort.
-void NHttpMsgHeader::legacy_clients()
-{
-    ClearHttpBuffers();
-    legacy_request();
-    legacy_status();
-    legacy_header(false);
-}
-
index 69024db77b61ebcde77e8cb972a7c7f2652ca970..6b063dd8be5447458c1d410d7e516110e8dfb128 100644 (file)
@@ -35,7 +35,6 @@ public:
     void gen_events() override;
     void update_flow() override;
     NHttpEnums::ProcessResult worth_detection() override;
-    void legacy_clients() override;
 };
 
 #endif
index 727bd208305b144f0a33930f9876bf16d43e6ffe..163cf14fa948b85a1f42a2b54bb7671c6e102cd8 100644 (file)
@@ -51,7 +51,7 @@ void NHttpMsgRequest::parse_start_line()
     if (start_line.start[start_line.length-9] != ' ')
     {
         // space before "HTTP" missing or in wrong place
-        infractions += INF_BADREQLINE;
+        infractions += INF_BAD_REQ_LINE;
         return;
     }
 
@@ -64,7 +64,7 @@ void NHttpMsgRequest::parse_start_line()
     if (space >= start_line.length-9)
     {
         // leading space or no space
-        infractions += INF_BADREQLINE;
+        infractions += INF_BAD_REQ_LINE;
         return;
     }
 
@@ -112,27 +112,27 @@ void NHttpMsgRequest::gen_events()
         events.create_event(EVENT_UNKNOWN_METHOD);
 
     // URI character encoding events
-    if (uri && (uri->get_uri_infractions() && INF_URIPERCENTASCII))
+    if (uri && (uri->get_uri_infractions() && INF_URI_PERCENT_ASCII))
         events.create_event(EVENT_ASCII);
-    if (uri && (uri->get_uri_infractions() && INF_URIPERCENTUCODE))
+    if (uri && (uri->get_uri_infractions() && INF_URI_PERCENT_UCODE))
         events.create_event(EVENT_U_ENCODE);
-    if (uri && (uri->get_uri_infractions() && INF_URI8BITCHAR))
+    if (uri && (uri->get_uri_infractions() && INF_URI_8BIT_CHAR))
         events.create_event(EVENT_BARE_BYTE);
-    if (uri && (uri->get_uri_infractions() && INF_URIPERCENTUTF8))
+    if (uri && (uri->get_uri_infractions() && INF_URI_PERCENT_UTF8))
         events.create_event(EVENT_UTF_8);
-    if (uri && (uri->get_uri_infractions() && INF_URIBADCHAR))
+    if (uri && (uri->get_uri_infractions() && INF_URI_BAD_CHAR))
         events.create_event(EVENT_NON_RFC_CHAR);
 
     // URI path events
-    if (uri && (uri->get_path_infractions() && INF_URIMULTISLASH))
+    if (uri && (uri->get_path_infractions() && INF_URI_MULTISLASH))
         events.create_event(EVENT_MULTI_SLASH);
-    if (uri && (uri->get_path_infractions() && INF_URIBACKSLASH))
+    if (uri && (uri->get_path_infractions() && INF_URI_BACKSLASH))
         events.create_event(EVENT_IIS_BACKSLASH);
-    if (uri && (uri->get_path_infractions() && INF_URISLASHDOT))
+    if (uri && (uri->get_path_infractions() && INF_URI_SLASH_DOT))
         events.create_event(EVENT_SELF_DIR_TRAV);
-    if (uri && (uri->get_path_infractions() && INF_URISLASHDOTDOT))
+    if (uri && (uri->get_path_infractions() && INF_URI_SLASH_DOT_DOT))
         events.create_event(EVENT_DIR_TRAV);
-    if (uri && (uri->get_path_infractions() && INF_URIROOTTRAV))
+    if (uri && (uri->get_path_infractions() && INF_URI_ROOT_TRAV))
         events.create_event(EVENT_WEBROOT_DIR);
 }
 
@@ -176,15 +176,13 @@ void NHttpMsgRequest::print_section(FILE* output)
 
 void NHttpMsgRequest::update_flow()
 {
-    const uint64_t disaster_mask = INF_BADREQLINE;
-
     // The following logic to determine body type is by no means the last word on this topic.
     if (tcp_close)
     {
         session_data->type_expected[source_id] = SEC_CLOSED;
         session_data->half_reset(source_id);
     }
-    else if (infractions && disaster_mask)
+    else if (infractions && INF_BAD_REQ_LINE)
     {
         session_data->type_expected[source_id] = SEC_ABORT;
         session_data->half_reset(source_id);
@@ -200,10 +198,3 @@ void NHttpMsgRequest::update_flow()
     session_data->section_type[source_id] = SEC__NOTCOMPUTE;
 }
 
-// Legacy support function. Puts message fields into the buffers used by old Snort.
-void NHttpMsgRequest::legacy_clients()
-{
-    ClearHttpBuffers();
-    legacy_request();
-}
-
index 38e2326e7c56610bd73d8c62477281e67bd44537..16e199dc6e5ef2038aedd498c7b740865a0b7e12 100644 (file)
@@ -39,7 +39,6 @@ public:
     void print_section(FILE* output) override;
     void gen_events() override;
     void update_flow() override;
-    void legacy_clients() override;
     const Field& get_method() { return method; }
     const Field& get_uri();
     const Field& get_uri_norm_legacy();
index e75938d10c3e23ef1f4c0a4afcf1e37ad95415a9..c5d0a4d27ba380713f93d55d827d5c04c9fe8445 100644 (file)
@@ -29,6 +29,7 @@
 #include "nhttp_msg_request.h"
 #include "nhttp_msg_status.h"
 #include "nhttp_msg_head_shared.h"
+#include "nhttp_msg_body.h"
 
 using namespace NHttpEnums;
 
@@ -54,15 +55,13 @@ void NHttpMsgSection::print_message_title(FILE* output, const char* title) const
     msg_text.print(output, "Input");
 }
 
-void NHttpMsgSection::print_message_wrapup(FILE* output) const
+void NHttpMsgSection::print_message_wrapup(FILE* output)
 {
     fprintf(output, "Infractions: %" PRIx64 ", Events: %" PRIx64 ", TCP Close: %s\n",
         infractions.get_raw(), events.get_raw(), tcp_close ? "True" : "False");
-    fprintf(output, "Interface to old clients. http_mask = %x.\n", http_mask);
-    for (int i=0; i < HTTP_BUFFER_MAX; i++)
+    for (unsigned k=1; k < HTTP_BUFFER_MAX; k++)
     {
-        if ((1 << i) & http_mask)
-            Field(http_buffer[i].length, http_buffer[i].buf).print(output, http_buffer_name[i]);
+        get_legacy(k).print(output, http_buffer_name[k]);
     }
     if (g_file_data.len > 0)
     {
@@ -73,84 +72,78 @@ void NHttpMsgSection::print_message_wrapup(FILE* output) const
     fprintf(output, "\n");
 }
 
-void NHttpMsgSection::legacy_request()
+const Field& NHttpMsgSection::get_legacy(unsigned buffer_id)
 {
-    NHttpMsgRequest* const request = transaction->get_request();
-    if (request == nullptr)
-        return;
-    if (request->get_method().length > 0)
+    // When current section is trailers, that is what will be used for header and cookie buffers.
+    switch (buffer_id)
     {
-        SetHttpBuffer(HTTP_BUFFER_METHOD, request->get_method().start,
-            (unsigned)request->get_method().length);
-    }
-    if (request->get_uri().length > 0)
-    {
-        SetHttpBuffer(HTTP_BUFFER_RAW_URI, request->get_uri().start,
-            (unsigned)request->get_uri().length);
-    }
-    if (request->get_uri_norm_legacy().length > 0)
-    {
-        SetHttpBuffer(HTTP_BUFFER_URI, request->get_uri_norm_legacy().start,
-            (unsigned)request->get_uri_norm_legacy().length);
-    }
-}
-
-void NHttpMsgSection::legacy_status()
-{
-    NHttpMsgStatus* const status = transaction->get_status();
-    if (status == nullptr)
-        return;
-    if (status->get_status_code().length > 0)
-    {
-        SetHttpBuffer(HTTP_BUFFER_STAT_CODE, status->get_status_code().start,
-            (unsigned)status->get_status_code().length);
-    }
-    if (status->get_reason_phrase().length > 0)
-    {
-        SetHttpBuffer(HTTP_BUFFER_STAT_MSG, status->get_reason_phrase().start,
-            (unsigned)status->get_reason_phrase().length);
-    }
-}
-
-void NHttpMsgSection::legacy_header(bool use_trailer)
-{
-    NHttpMsgHeadShared* const header = use_trailer ?
-        (NHttpMsgHeadShared*)transaction->get_trailer(source_id) :
-        (NHttpMsgHeadShared*)transaction->get_header(source_id);
-    if (header == nullptr)
-        return;
-
-    if (header->get_headers().length > 0)
-    {
-        SetHttpBuffer(HTTP_BUFFER_RAW_HEADER, header->get_headers().start,
-            (unsigned)header->get_headers().length);
-        SetHttpBuffer(HTTP_BUFFER_HEADER, header->get_headers().start,
-            (unsigned)header->get_headers().length);
-    }
-
-    legacy_cookie(header, source_id);
-}
-
-// FIXIT-M there can be multiple cookie headers in one message.
-void NHttpMsgSection::legacy_cookie(NHttpMsgHeadShared* header, SourceId source_id)
-{
-    HeaderId cookie_head = (source_id == SRC_CLIENT) ? HEAD_COOKIE : HEAD_SET_COOKIE;
-
-    for (int k=0; k < header->get_num_headers(); k++)
-    {
-        if (header->get_header_name_id(k) == cookie_head)
+    case HTTP_BUFFER_CLIENT_BODY:
+      {
+        NHttpMsgBody* body = transaction->get_body();
+        return (body != nullptr) ? body->get_data() : Field::FIELD_NULL;
+      }
+    case HTTP_BUFFER_COOKIE:
+      {
+        NHttpMsgHeadShared* header = transaction->get_latest_header(source_id);
+        if (header == nullptr)
+            return Field::FIELD_NULL;
+        HeaderId cookie_head = (source_id == SRC_CLIENT) ? HEAD_COOKIE : HEAD_SET_COOKIE;
+        return header->get_header_value_norm(cookie_head);
+      }
+    case HTTP_BUFFER_HEADER:
+      {
+        NHttpMsgHeadShared* header = transaction->get_latest_header(source_id);
+        return (header != nullptr) ? header->get_headers() : Field::FIELD_NULL;
+      }
+    case HTTP_BUFFER_METHOD:
+      {
+        NHttpMsgRequest* request = transaction->get_request();
+        return (request != nullptr) ? request->get_method() : Field::FIELD_NULL;
+      }
+    case HTTP_BUFFER_RAW_COOKIE:
+      {
+        NHttpMsgHeadShared* header = transaction->get_latest_header(source_id);
+        if (header == nullptr)
+            return Field::FIELD_NULL;
+        HeaderId cookie_head = (source_id == SRC_CLIENT) ? HEAD_COOKIE : HEAD_SET_COOKIE;
+        // FIXIT-M there can be multiple cookie header in one message.
+        for (int k=0; k < header->get_num_headers(); k++)
         {
-            if (header->get_header_value(k).length > 0)
-                SetHttpBuffer(HTTP_BUFFER_RAW_COOKIE, header->get_header_value(k).start,
-                    (unsigned)header->get_header_value(k).length);
-            break;
+            if (header->get_header_name_id(k) == cookie_head)
+            {
+                return header->get_header_value(k);
+            }
         }
-    }
-
-    if (header->get_header_value_norm(cookie_head).length > 0)
-    {
-        SetHttpBuffer(HTTP_BUFFER_COOKIE, header->get_header_value_norm(cookie_head).start,
-            (unsigned)header->get_header_value_norm(cookie_head).length);
+        return Field::FIELD_NULL;
+      }
+    case HTTP_BUFFER_RAW_HEADER:
+      {
+        NHttpMsgHeadShared* header = transaction->get_latest_header(source_id);
+        return (header != nullptr) ? header->get_headers() : Field::FIELD_NULL;
+      }
+    case HTTP_BUFFER_RAW_URI:
+      {
+        NHttpMsgRequest* request = transaction->get_request();
+        return (request != nullptr) ? request->get_uri() : Field::FIELD_NULL;
+      }
+    case HTTP_BUFFER_STAT_CODE:
+      {
+        NHttpMsgStatus* status = transaction->get_status();
+        return (status != nullptr) ? status->get_status_code() : Field::FIELD_NULL;
+      }
+    case HTTP_BUFFER_STAT_MSG:
+      {
+        NHttpMsgStatus* status = transaction->get_status();
+        return (status != nullptr) ? status->get_reason_phrase() : Field::FIELD_NULL;
+      }
+    case HTTP_BUFFER_URI:
+      {
+        NHttpMsgRequest* request = transaction->get_request();
+        return (request != nullptr) ? request->get_uri_norm_legacy() : Field::FIELD_NULL;
+      }
+    default:
+        assert(0);
+        return Field::FIELD_NULL;
     }
 }
 
index fd64a0621bd540a89e2a41305215760325fad239..4f6aed28f55b08e4427a24500e4f35990fdfdb64 100644 (file)
@@ -20,6 +20,8 @@
 #ifndef NHTTP_MSG_SECTION_H
 #define NHTTP_MSG_SECTION_H
 
+#include "detection/detection_util.h"
+
 #include "nhttp_scratch_pad.h"
 #include "nhttp_field.h"
 #include "nhttp_flow_data.h"
@@ -46,8 +48,7 @@ public:
     // Manages the splitter and communication between message sections
     virtual void update_flow() = 0;
 
-    // Populates the raw and normalized buffer interface used by old Snort
-    virtual void legacy_clients() = 0;
+    const Field& get_legacy(unsigned buffer_id);
 
     // Should this section be sent directly to detection after inspection?
     virtual NHttpEnums::ProcessResult worth_detection() { return NHttpEnums::RES_INSPECT; }
@@ -63,11 +64,7 @@ protected:
 
     // Convenience methods
     void print_message_title(FILE* output, const char* title) const;
-    void print_message_wrapup(FILE* output) const;
-    void legacy_request();
-    void legacy_status();
-    void legacy_header(bool use_trailer);
-    void legacy_cookie(NHttpMsgHeadShared* header, NHttpEnums::SourceId source_id);
+    void print_message_wrapup(FILE* output);
 
     const Field msg_text;
 
index fe231b89170818bfc921572f8de63676eea53bdc..ff7ab281053018e37a23a6d6faa50eb62252c33e 100644 (file)
@@ -46,14 +46,14 @@ void NHttpMsgStart::derive_version_id()
     if (version.length != 8)
     {
         version_id = VERS__PROBLEMATIC;
-        infractions += INF_BADVERSION;
+        infractions += INF_BAD_VERSION;
         return;
     }
 
     if (memcmp(version.start, "HTTP/", 5) || (version.start[6] != '.'))
     {
         version_id = VERS__PROBLEMATIC;
-        infractions += INF_BADVERSION;
+        infractions += INF_BAD_VERSION;
     }
     else if ((version.start[5] == '1') && (version.start[7] == '1'))
     {
@@ -71,12 +71,12 @@ void NHttpMsgStart::derive_version_id()
         (version.start[7] >= '0') && (version.start[7] <= '9'))
     {
         version_id = VERS__OTHER;
-        infractions += INF_UNKNOWNVERSION;
+        infractions += INF_UNKNOWN_VERSION;
     }
     else
     {
         version_id = VERS__PROBLEMATIC;
-        infractions += INF_BADVERSION;
+        infractions += INF_BAD_VERSION;
     }
 }
 
index 8d9e2fc870940c71d79951251431a42663f42512..b579387bbdfd40cfb7acb23d3f8aaf62f4811262 100644 (file)
@@ -55,7 +55,7 @@ void NHttpMsgStatus::parse_start_line()
     // as error. HTTP/X.Y<SP>###<SP><text>
     if ((start_line.length < 13) || (start_line.start[8] != ' ') || (start_line.start[12] != ' '))
     {
-        infractions += INF_BADSTATLINE;
+        infractions += INF_BAD_STAT_LINE;
         return;
     }
     version.start = start_line.start;
@@ -69,7 +69,7 @@ void NHttpMsgStatus::parse_start_line()
         if ((reason_phrase.start[k] <= 31) || (reason_phrase.start[k] >= 127))
         {
             // Illegal character in reason phrase
-            infractions += INF_BADPHRASE;
+            infractions += INF_BAD_PHRASE;
             break;
         }
     }
@@ -93,7 +93,7 @@ void NHttpMsgStatus::derive_status_code_num()
         '0') || (status_code.start[1] > '9') ||
         (status_code.start[2] < '0') || (status_code.start[2] > '9'))
     {
-        infractions += INF_BADSTATCODE;
+        infractions += INF_BAD_STAT_CODE;
         status_code_num = STAT_PROBLEMATIC;
         return;
     }
@@ -101,7 +101,7 @@ void NHttpMsgStatus::derive_status_code_num()
         (status_code.start[2] - '0');
     if ((status_code_num < 100) || (status_code_num > 599))
     {
-        infractions += INF_BADSTATCODE;
+        infractions += INF_BAD_STAT_CODE;
     }
 }
 
@@ -118,15 +118,13 @@ void NHttpMsgStatus::print_section(FILE* output)
 
 void NHttpMsgStatus::update_flow()
 {
-    const uint64_t disaster_mask = INF_BADSTATLINE;
-
     // The following logic to determine body type is by no means the last word on this topic.
     if (tcp_close)
     {
         session_data->type_expected[source_id] = SEC_CLOSED;
         session_data->half_reset(source_id);
     }
-    else if (infractions && disaster_mask)
+    else if (infractions && INF_BAD_STAT_LINE)
     {
         session_data->type_expected[source_id] = SEC_ABORT;
         session_data->half_reset(source_id);
@@ -142,11 +140,3 @@ void NHttpMsgStatus::update_flow()
     session_data->section_type[source_id] = SEC__NOTCOMPUTE;
 }
 
-// Legacy support function. Puts message fields into the buffers used by old Snort.
-void NHttpMsgStatus::legacy_clients()
-{
-    ClearHttpBuffers();
-    legacy_request();
-    legacy_status();
-}
-
index 35d63823bcf603afa869308ed4468df2840400f5..b8f836e5b61b7e24c09e44a707d5a27c9006cfb2 100644 (file)
@@ -36,7 +36,6 @@ public:
     void print_section(FILE* output) override;
     void gen_events() override;
     void update_flow() override;
-    void legacy_clients() override;
 
     const Field& get_status_code() { return status_code; }
     const Field& get_reason_phrase() { return reason_phrase; }
index b937e5dee211b2c219342a50292dab6b2ffab8a6..091e48a2da7e2e28667c8e1568172fc5a9562bbd 100644 (file)
@@ -70,12 +70,3 @@ ProcessResult NHttpMsgTrailer::worth_detection()
     return (msg_text.length > 0) ? RES_INSPECT : RES_IGNORE;
 }
 
-// Legacy support function. Puts message fields into the buffers used by old Snort.
-void NHttpMsgTrailer::legacy_clients()
-{
-    ClearHttpBuffers();
-    legacy_request();
-    legacy_status();
-    legacy_header(true);
-}
-
index 0e9b8c3caf4be73bdee841bb25af304ee7496a92..69ae8f45a209e902a4f08ee4c2269ed54e6350aa 100644 (file)
@@ -35,7 +35,6 @@ public:
     void gen_events() override;
     void update_flow() override;
     NHttpEnums::ProcessResult worth_detection() override;
-    void legacy_clients() override;
 };
 
 #endif
index 3bfe3ece66885305e528c67567582f6883e6aba9..9c6665cdd0ce85b1af606cea45f0892764d5ec4a 100644 (file)
@@ -43,12 +43,12 @@ int32_t norm_decimal_integer(const uint8_t* in_buf, int32_t in_length, uint8_t*
             non_leading_zeros++;
         if (non_leading_zeros > 18)
         {
-            infractions += INF_BADHEADERDATA;
+            infractions += INF_BAD_HEADER_DATA;
             return STAT_PROBLEMATIC;
         }
         if ((value < 0) || (value > 9))
         {
-            infractions += INF_BADHEADERDATA;
+            infractions += INF_BAD_HEADER_DATA;
             return STAT_PROBLEMATIC;
         }
         total = total*10 + value;
index d473fc8c695c8edda78a7546391442a09b447d9f..ba392bad6db8d24eba7c530330476f869f28064d 100644 (file)
@@ -40,7 +40,7 @@ ScanResult NHttpStartSplitter::split(const uint8_t* buffer, uint32_t length,
                 }
                 else
                 {
-                    infractions += INF_TOOMUCHLEADINGWS;
+                    infractions += INF_TOO_MUCH_LEADING_WS;
                     events.create_event(EVENT_LOSS_OF_SYNC);
                     return SCAN_ABORT;
                 }
@@ -102,7 +102,7 @@ ScanResult NHttpHeaderSplitter::split(const uint8_t* buffer, uint32_t length,
                 // Alert on \n not preceded by \r. Correct cases are \r\n\r\n and \r\n.
                 if (!((num_crlf == 4) || ((num_crlf == 2) && (first_lf == 0))))
                 {
-                    infractions += INF_LFWITHOUTCR;
+                    infractions += INF_LF_WITHOUT_CR;
                     events.create_event(EVENT_IIS_DELIMITER);
                 }
                 num_flush = k + 1 + peek_octets;
index d621e425b6ed6d439f405808a08364998529a080..c55afe0fc24c671258e73a0f09a47fcffac409af 100644 (file)
@@ -163,7 +163,7 @@ StreamSplitter::Status NHttpStreamSplitter::scan(Flow* flow, const uint8_t* data
         case SCAN_NOTFOUND:
             if (splitter->get_octets_seen() == MAXOCTETS)
             {
-                session_data->infractions[source_id] += INF_ENDLESSHEADER;
+                session_data->infractions[source_id] += INF_ENDLESS_HEADER;
                 session_data->events[source_id].create_event(EVENT_LOSS_OF_SYNC);
                 // FIXIT-H need to process this data (except chunk header) not just discard it.
                 session_data->type_expected[source_id] = SEC_ABORT;
index d88990cac117734889da6db86f5c94b4ee838746..e6ae64a250335c5830787fe122fe90bf4931b72f 100644 (file)
@@ -25,6 +25,7 @@
 #include "nhttp_msg_status.h"
 #include "nhttp_msg_header.h"
 #include "nhttp_msg_trailer.h"
+#include "nhttp_msg_body.h"
 
 using namespace NHttpEnums;
 
@@ -76,8 +77,7 @@ NHttpTransaction* NHttpTransaction::attach_my_transaction(NHttpFlowData* session
             }
             else if (!session_data->add_to_pipeline(session_data->transaction[SRC_CLIENT]))
             {
-                // The pipeline is full and just overflowed. FIXIT-M we should alert and set
-                // infraction.
+                // The pipeline is full and just overflowed. FIXIT-M alert and set infraction.
                 delete session_data->transaction[SRC_CLIENT];
             }
         }
index fff88540fca9d80ab0f64671781b6a75b8645dc2..00fb88ff5038bee83cf0133670f36ec4f14f8b17 100644 (file)
@@ -28,6 +28,8 @@ class NHttpMsgStatus;
 class NHttpMsgHeader;
 class NHttpMsgTrailer;
 class NHttpMsgSection;
+class NHttpMsgBody;
+class NHttpMsgHeadShared;
 
 class NHttpTransaction
 {
@@ -44,19 +46,22 @@ public:
 
     NHttpMsgHeader* get_header(NHttpEnums::SourceId source_id) const { return header[source_id]; }
     void set_header(NHttpMsgHeader* header_, NHttpEnums::SourceId source_id)
-    {
-        header[source_id] =
-            header_;
-    }
+        { header[source_id] = header_; }
 
     NHttpMsgTrailer* get_trailer(NHttpEnums::SourceId source_id) const
+        { return trailer[source_id]; }
+    void set_trailer(NHttpMsgTrailer* trailer_, NHttpEnums::SourceId source_id)
+        { trailer[source_id] = trailer_; }
+
+    NHttpMsgBody* get_body() const { return latest_body; }
+    void set_body(NHttpMsgBody* latest_body_) { latest_body = latest_body_; }
+
+    // Convenience method
+    NHttpMsgHeadShared* get_latest_header(NHttpEnums::SourceId source_id)
     {
-        return trailer[source_id];
+        return (trailer[source_id] != nullptr) ? (NHttpMsgHeadShared*)trailer[source_id] :
+            (NHttpMsgHeadShared*)header[source_id];
     }
-    void set_trailer(NHttpMsgTrailer* trailer_, NHttpEnums::SourceId
-        source_id) { trailer[source_id] = trailer_; }
-
-    void set_body(NHttpMsgSection* latest_body_) { latest_body = latest_body_; }
 
 private:
     NHttpTransaction() = default;
@@ -65,7 +70,7 @@ private:
     NHttpMsgStatus* status = nullptr;
     NHttpMsgHeader* header[2] = { nullptr, nullptr };
     NHttpMsgTrailer* trailer[2] = { nullptr, nullptr };
-    NHttpMsgSection* latest_body = nullptr;
+    NHttpMsgBody* latest_body = nullptr;
 };
 
 #endif
index 589696992feeda4988562140d2aa9f04be402747..327fb2cff7b803ac6bb70a88def6f79da9b078b3 100644 (file)
@@ -94,7 +94,7 @@ void NHttpUri::parse_uri()
         }
         else
         {
-            format_infractions += INF_BADURI;
+            format_infractions += INF_BAD_URI;
             uri_type = URI__PROBLEMATIC;
             scheme.length = STAT_PROBLEMATIC;
             authority.length = STAT_PROBLEMATIC;
@@ -119,7 +119,7 @@ SchemeId NHttpUri::get_scheme_id()
     uint8_t* lower_scheme;
     if ((lower_scheme = scratch_pad.request(scheme.length)) == nullptr)
     {
-        scheme_infractions += INF_NOSCRATCH;
+        scheme_infractions += INF_NO_SCRATCH;
         scheme_id = SCH__INSUFMEMORY;
         return scheme_id;
     }
@@ -205,7 +205,7 @@ int32_t NHttpUri::get_port_value()
         port_value = port_value * 10 + (port.start[k] - '0');
         if ((port.start[k] < '0') || (port.start[k] > '9') || (port_value > 65535))
         {
-            port_infractions += INF_BADPORT;
+            port_infractions += INF_BAD_PORT;
             port_value = STAT_PROBLEMATIC;
             break;
         }
index 9e136ae07accb4972d974f16162554c3c744db7f..b97f412fdc7b0934ec1525f10a3f2c25983a5ea6 100644 (file)
@@ -77,7 +77,7 @@ bool UriNormalizer::no_path_check(const uint8_t* in_buf, int32_t in_length,
     {
         if ((uri_char[in_buf[k]] == CHAR_NORMAL) || (uri_char[in_buf[k]] == CHAR_PATH))
             continue;
-        infractions += INF_URINEEDNORM;
+        infractions += INF_URI_NEED_NORM;
         return false;
     }
     return true;
@@ -93,7 +93,7 @@ bool UriNormalizer::path_check(const uint8_t* in_buf, int32_t in_length,
             continue;
         if ((in_buf[k] == '/') && ((k == 0) || (in_buf[k-1] != '/')))
             continue;
-        infractions += INF_URINEEDNORM;
+        infractions += INF_URI_NEED_NORM;
         return false;
     }
     return true;
@@ -112,11 +112,11 @@ int32_t UriNormalizer::norm_char_clean(const uint8_t* in_buf, int32_t in_length,
             out_buf[length++] = in_buf[k];
             break;
         case CHAR_INVALID:
-            infractions += INF_URIBADCHAR;
+            infractions += INF_URI_BAD_CHAR;
             out_buf[length++] = in_buf[k];
             break;
         case CHAR_EIGHTBIT:
-            infractions += INF_URI8BITCHAR;
+            infractions += INF_URI_8BIT_CHAR;
             out_buf[length++] = in_buf[k];
             break;
         case CHAR_PERCENT:
@@ -129,16 +129,16 @@ int32_t UriNormalizer::norm_char_clean(const uint8_t* in_buf, int32_t in_length,
                     {
                         // Normal % escape of an ASCII special character that is supposed to be
                         // escaped
-                        infractions += INF_URIPERCENTNORMAL;
+                        infractions += INF_URI_PERCENT_NORMAL;
                         out_buf[length++] = '%';
                     }
                     else
                     {
                         // Suspicious % escape of an ASCII character that does not need to be
                         // escaped
-                        infractions += INF_URIPERCENTASCII;
+                        infractions += INF_URI_PERCENT_ASCII;
                         if (uri_char[value] == CHAR_INVALID)
-                            infractions += INF_URIBADCHAR;
+                            infractions += INF_URI_BAD_CHAR;
                         out_buf[length++] = value;
                         k += 2;
                     }
@@ -146,7 +146,7 @@ int32_t UriNormalizer::norm_char_clean(const uint8_t* in_buf, int32_t in_length,
                 else
                 {
                     // UTF-8 decoding not implemented yet
-                    infractions += INF_URIPERCENTUTF8;
+                    infractions += INF_URI_PERCENT_UTF8;
                     out_buf[length++] = '%';
                 }
             }
@@ -155,13 +155,13 @@ int32_t UriNormalizer::norm_char_clean(const uint8_t* in_buf, int32_t in_length,
                 && (as_hex[in_buf[k+4]] != -1) && (as_hex[in_buf[k+5]] != -1))
             {
                 // 'u' UTF-16 decoding not implemented yet
-                infractions += INF_URIPERCENTUCODE;
+                infractions += INF_URI_PERCENT_UCODE;
                 out_buf[length++] = '%';
             }
             else
             {
                 // Don't recognize it
-                infractions += INF_URIPERCENTOTHER;
+                infractions += INF_URI_PERCENT_OTHER;
                 out_buf[length++] = '%';
             }
             break;
@@ -181,7 +181,7 @@ int32_t UriNormalizer::norm_backslash(const uint8_t* in_buf, int32_t in_length,
         else
         {
             out_buf[k] = '/';
-            infractions += INF_URIBACKSLASH;
+            infractions += INF_URI_BACKSLASH;
         }
     }
     return in_length;
@@ -205,13 +205,13 @@ int32_t UriNormalizer::norm_path_clean(const uint8_t* in_buf, int32_t in_length,
         // Ignore this slash if it directly follows another slash
         else if ((k < in_length) && (length >= 1) && (out_buf[length-1] == '/'))
         {
-            infractions += INF_URIMULTISLASH;
+            infractions += INF_URI_MULTISLASH;
         }
         // This slash is the end of a /./ pattern, ignore this slash and remove the period from the
         // output
         else if ((length >= 2) && (out_buf[length-1] == '.') && (out_buf[length-2] == '/'))
         {
-            infractions += INF_URISLASHDOT;
+            infractions += INF_URI_SLASH_DOT;
             length -= 1;
         }
         // This slash is the end of a /../ pattern, normalization depends on whether there is a
@@ -219,7 +219,7 @@ int32_t UriNormalizer::norm_path_clean(const uint8_t* in_buf, int32_t in_length,
         else if ((length >= 3) && (out_buf[length-1] == '.') && (out_buf[length-2] == '.') &&
             (out_buf[length-3] == '/'))
         {
-            infractions += INF_URISLASHDOTDOT;
+            infractions += INF_URI_SLASH_DOT_DOT;
             // Traversing above the root of the absolute path. A path of the form
             // /../../../foo/bar/whatever cannot be further normalized. Instead of taking away a
             // directory we leave the .. and write out the new slash. This code can write out the
@@ -229,7 +229,7 @@ int32_t UriNormalizer::norm_path_clean(const uint8_t* in_buf, int32_t in_length,
                 ((length >= 6) && (out_buf[length-4] == '.') && (out_buf[length-5] == '.') &&
                 (out_buf[length-6] == '/')))
             {
-                infractions += INF_URIROOTTRAV;
+                infractions += INF_URI_ROOT_TRAV;
                 out_buf[length++] = '/';
             }
             // Remove the previous directory from the output. "/foo/bar/../" becomes "/foo/"