]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
header lines ending in LF without CR
authorTom Peters <thopeter@cisco.com>
Wed, 1 Oct 2014 20:24:13 +0000 (16:24 -0400)
committerTom Peters <thopeter@cisco.com>
Wed, 1 Oct 2014 20:24:13 +0000 (16:24 -0400)
src/service_inspectors/nhttp_inspect/nhttp_msg_head_shared.cc
src/service_inspectors/nhttp_inspect/nhttp_msg_head_shared.h
src/service_inspectors/nhttp_inspect/nhttp_msg_request.cc
src/service_inspectors/nhttp_inspect/nhttp_msg_section.cc
src/service_inspectors/nhttp_inspect/nhttp_msg_section.h

index 5f4412db5da5b53da46cb822aac5107b928220df..f8b693f6be4fef37f8e755a9a375c2f8dd880522 100644 (file)
@@ -52,10 +52,12 @@ void NHttpMsgHeadShared::analyze() {
 void NHttpMsgHeadShared::parse_header_block() {
     int32_t bytes_used = 0;
     num_headers = 0;
+    int num_seps;
     while (bytes_used < msg_text.length) {
         header_line[num_headers].start = msg_text.start + bytes_used;
-        header_line[num_headers].length = find_crlf(header_line[num_headers].start, msg_text.length - bytes_used);
-        bytes_used += header_line[num_headers++].length + 2;
+        header_line[num_headers].length = find_header_end(header_line[num_headers].start, msg_text.length - bytes_used,
+           &num_seps);
+        bytes_used += header_line[num_headers++].length + num_seps;
         if (num_headers >= MAXHEADERS) {
              break;
         }
@@ -65,6 +67,32 @@ void NHttpMsgHeadShared::parse_header_block() {
     }
 }
 
+// Return the number of octets before the CRLF that ends a header. CRLF does not count when immediately followed by
+// <SP> or <LF>. These whitespace characters at the beginning of the next line indicate that the previous header has
+// wrapped and is continuing on the next line.
+// 
+// The final header in the block will not be terminated by CRLF (splitter design) but will terminate at the end of the
+// buffer. length is returned.
+//
+// Bare LF without CR is accepted as the terminator unless preceded by backslash character. FIXIT-L this does not
+// consider whether \LF is contained within a quoted string and perhaps this should be revisited. The current
+// approach errs in the direction of not incorrectly dividing a single header into two headers.
+//
+// FIXIT-M any abuse of backslashes in headers should be a preprocessor alarm.
+
+uint32_t NHttpMsgHeadShared::find_header_end(const uint8_t* buffer, int32_t length, int* const num_seps) {
+    for (int32_t k=0; k < length-1; k++) {
+        if ((buffer[k] != '\\') && (buffer[k+1] == '\n')) {
+            if ((k+2 >= length) || ((buffer[k+2] != ' ') && (buffer[k+2] != '\t'))) {
+                *num_seps = (buffer[k] == '\r') ? 2 : 1;
+                return k + 2 - *num_seps;
+            }
+        }
+    }
+    *num_seps = 0;
+    return length;
+}
+
 // Divide header field lines into field name and field value
 void NHttpMsgHeadShared::parse_header_lines() {
     int colon;
index 6e014e3a3f680cd7179fe6ec10a64f7ffc554c42..b49f32900ed95b928398a3f9bc76b528fac11fa7 100644 (file)
@@ -73,6 +73,7 @@ protected:
     static const StrCode trans_code_list[];
 
     void parse_header_block();
+    static uint32_t find_header_end(const uint8_t* buffer, int32_t length, int* const num_seps);
     void parse_header_lines();
     void derive_header_name_id(int index);
 
index 959bb5267c96caf9c902a8ff566fdd0af4e4ce22..491a6af83b07bce1c02ed5f81d9775481e219909 100644 (file)
@@ -47,7 +47,6 @@ NHttpMsgRequest::NHttpMsgRequest(const uint8_t *buffer, const uint16_t buf_size,
    transaction->set_request(this);
 }
 
-
 void NHttpMsgRequest::parse_start_line() {
     // There should be exactly two spaces. One following the method and one before "HTTP/".
     // Additional spaces located within the URI are not allowed but we will tolerate it
index fb4ffbc938aef4f304e0b38b9c64f67824e2314e..163536c44de1dcc11b11bfccec87a0e02cdf0cf3 100644 (file)
@@ -56,17 +56,6 @@ NHttpMsgSection::NHttpMsgSection(const uint8_t *buffer, const uint16_t buf_size,
    delete_msg_on_destruct(buf_owner)
 {}
 
-// Return the number of octets before the CRLF that ends a header. Return length if CRLF not present. CRLF does not
-// count when immediately followed by <SP> or <LF>. These whitespace characters at the beginning of the next line
-// indicate that the previous header has wrapped and is continuing on the next line.
-uint32_t NHttpMsgSection::find_crlf(const uint8_t* buffer, int32_t length) {
-    for (int32_t k=0; k < length-1; k++) {
-        if ((buffer[k] == '\r') && (buffer[k+1] == '\n'))
-            if ((k+2 >= length) || ((buffer[k+2] != ' ') && (buffer[k+2] != '\t'))) return k;
-    }
-    return length;
-}
-
 void NHttpMsgSection::print_message_title(FILE *output, const char *title) const {
     fprintf(output, "HTTP message %s:\n", title);
     msg_text.print(output, "Input");
index 31435a01f28eadf1e33b63f4f505f96e24c5a809..f82c5c1fedfff1fa0be806aaad7f6d8d81a1e502 100644 (file)
@@ -59,7 +59,6 @@ protected:
        NHttpEnums::SourceId source_id_, bool buf_owner);
 
     // Convenience methods
-    static uint32_t find_crlf(const uint8_t* buffer, int32_t length);
     void print_message_title(FILE *output, const char *title) const;
     void print_message_wrapup(FILE *output) const;
     void create_event(NHttpEnums::EventSid sid);