]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
http2: handles incomplete frames after banner
authorPhilippe Antoine <contact@catenacyber.fr>
Wed, 9 Sep 2020 07:27:00 +0000 (09:27 +0200)
committerVictor Julien <victor@inliniac.net>
Wed, 9 Sep 2020 10:31:20 +0000 (12:31 +0200)
To signal incomplete data, we must return the number of
consumed bytes. When we get a banner and some records, we have
to take into account the number of bytes already consumed by
the banner parsing before reaching an incomplete record.

rust/src/http2/http2.rs

index 2c9d28e5c9993b2db387f1b192f2997aa653d1a4..52e14475661752a8061544c870c974d62eda0fe4 100644 (file)
@@ -755,6 +755,7 @@ impl HTTP2State {
 
     fn parse_ts(&mut self, mut input: &[u8]) -> AppLayerResult {
         //very first : skip magic
+        let mut magic_consumed = 0;
         if self.progress < HTTP2ConnectionState::Http2StateMagicDone {
             //skip magic
             if input.len() >= HTTP2_MAGIC_LEN {
@@ -762,6 +763,7 @@ impl HTTP2State {
                 match std::str::from_utf8(&input[..HTTP2_MAGIC_LEN]) {
                     Ok("PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n") => {
                         input = &input[HTTP2_MAGIC_LEN..];
+                        magic_consumed = HTTP2_MAGIC_LEN;
                     }
                     Ok(&_) => {
                         self.set_event(HTTP2Event::InvalidClientMagic);
@@ -791,7 +793,13 @@ impl HTTP2State {
         }
 
         //then parse all we can
-        return self.parse_frames(input, il, STREAM_TOSERVER);
+        let r = self.parse_frames(input, il, STREAM_TOSERVER);
+        if r.status == 1 {
+            //adds bytes consumed by banner to incomplete result
+            return AppLayerResult::incomplete(r.consumed + magic_consumed as u32, r.needed);
+        } else {
+            return r;
+        }
     }
 
     fn parse_tc(&mut self, mut input: &[u8]) -> AppLayerResult {