]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
dcerpc: trigger raw assembly on record completion
authorShivani Bhardwaj <shivanib134@gmail.com>
Tue, 23 Feb 2021 09:55:52 +0000 (15:25 +0530)
committerVictor Julien <victor@inliniac.net>
Fri, 26 Feb 2021 09:42:50 +0000 (10:42 +0100)
(cherry picked from commit 0ac5c5376a2a6e32ac0c12ff8bc483abf04c9cb8)

rust/src/dcerpc/dcerpc.rs

index bfd39956d42d6c7986b034d00c8eb57f1ed4cfe2..e5c26ed7d9e017e5476d8425b89ad59ab7546ce3 100644 (file)
@@ -17,7 +17,7 @@
 
 use std::mem::transmute;
 use crate::applayer::*;
-use crate::core::{self, sc_detect_engine_state_free};
+use crate::core::{self, *};
 use crate::dcerpc::parser;
 use nom::error::ErrorKind;
 use nom::number::Endianness;
@@ -350,6 +350,7 @@ pub struct DCERPCState {
     pub tc_ssn_gap: bool,
     pub ts_ssn_trunc: bool, /// true if Truncated in this direction
     pub tc_ssn_trunc: bool,
+    pub flow: Option<*const core::Flow>,
 }
 
 impl DCERPCState {
@@ -376,6 +377,7 @@ impl DCERPCState {
             tc_ssn_gap: false,
             ts_ssn_trunc: false,
             tc_ssn_trunc: false,
+            flow: None,
         };
     }
 
@@ -618,6 +620,9 @@ impl DCERPCState {
                     tx.req_lost = true;
                 }
                 tx.req_done = true;
+                if let Some(flow) = self.flow {
+                    sc_app_layer_parser_trigger_raw_stream_reassembly(flow, dir.into());
+                }
             }
         } else if self.tc_ssn_gap && dir == core::STREAM_TOCLIENT {
             for tx in &mut self.transactions {
@@ -633,6 +638,9 @@ impl DCERPCState {
                 }
                 tx.req_done = true;
                 tx.resp_done = true;
+                if let Some(flow) = self.flow {
+                    sc_app_layer_parser_trigger_raw_stream_reassembly(flow, dir.into());
+                }
             }
         }
     }
@@ -745,6 +753,9 @@ impl DCERPCState {
                 let mut tx = self.create_tx(call_id);
                 tx.req_cmd = self.get_hdr_type().unwrap_or(0);
                 tx.req_done = true;
+                if let Some(flow) = self.flow {
+                    sc_app_layer_parser_trigger_raw_stream_reassembly(flow, core::STREAM_TOSERVER.into());
+                }
                 tx.frag_cnt_ts = 1;
                 self.transactions.push(tx);
                 // Bytes parsed with `parse_dcerpc_bind` + (bytes parsed per bindctxitem [44] * number
@@ -827,6 +838,9 @@ impl DCERPCState {
                     );
                     tx.req_done = true;
                     tx.frag_cnt_ts = 1;
+                    if let Some(flow) = self.flow {
+                        sc_app_layer_parser_trigger_raw_stream_reassembly(flow, core::STREAM_TOSERVER.into());
+                    }
                 }
                 DCERPC_TYPE_RESPONSE => {
                     retval = evaluate_stub_params(
@@ -839,6 +853,9 @@ impl DCERPCState {
                     );
                     tx.resp_done = true;
                     tx.frag_cnt_tc = 1;
+                    if let Some(flow) = self.flow {
+                        sc_app_layer_parser_trigger_raw_stream_reassembly(flow, core::STREAM_TOCLIENT.into());
+                    }
                 }
                 _ => {
                     SCLogDebug!("Unrecognized packet type");
@@ -1069,6 +1086,9 @@ impl DCERPCState {
                     };
                     tx.resp_done = true;
                     tx.frag_cnt_tc = 1;
+                    if let Some(flow) = self.flow {
+                        sc_app_layer_parser_trigger_raw_stream_reassembly(flow, core::STREAM_TOCLIENT.into());
+                    }
                     self.handle_bind_cache(current_call_id, false);
                 }
                 DCERPC_TYPE_REQUEST => {
@@ -1163,7 +1183,7 @@ pub extern "C" fn rs_parse_dcerpc_response_gap(
 
 #[no_mangle]
 pub extern "C" fn rs_dcerpc_parse_request(
-    _flow: *mut core::Flow, state: &mut DCERPCState, _pstate: *mut std::os::raw::c_void,
+    flow: *mut core::Flow, state: &mut DCERPCState, _pstate: *mut std::os::raw::c_void,
     input: *const u8, input_len: u32, _data: *mut std::os::raw::c_void, flags: u8,
 ) -> AppLayerResult {
     SCLogDebug!("Handling request: input {:p} input_len {} flags {:x} EOF {}",
@@ -1177,6 +1197,7 @@ pub extern "C" fn rs_dcerpc_parse_request(
     }
     if input_len > 0 && input != std::ptr::null_mut() {
         let buf = build_slice!(input, input_len as usize);
+        state.flow = Some(flow);
         return state.handle_input_data(buf, core::STREAM_TOSERVER);
     }
     AppLayerResult::err()
@@ -1184,7 +1205,7 @@ pub extern "C" fn rs_dcerpc_parse_request(
 
 #[no_mangle]
 pub extern "C" fn rs_dcerpc_parse_response(
-    _flow: *mut core::Flow, state: &mut DCERPCState, _pstate: *mut std::os::raw::c_void,
+    flow: *mut core::Flow, state: &mut DCERPCState, _pstate: *mut std::os::raw::c_void,
     input: *const u8, input_len: u32, _data: *mut std::os::raw::c_void, flags: u8,
 ) -> AppLayerResult {
     if flags & core::STREAM_EOF != 0 && input_len == 0 {
@@ -1197,6 +1218,7 @@ pub extern "C" fn rs_dcerpc_parse_response(
     if input_len > 0 {
         if input != std::ptr::null_mut() {
             let buf = build_slice!(input, input_len as usize);
+            state.flow = Some(flow);
             return state.handle_input_data(buf, core::STREAM_TOCLIENT);
         }
     }
@@ -1229,12 +1251,18 @@ pub extern "C" fn rs_dcerpc_state_trunc(state: *mut std::os::raw::c_void, direct
         dce_state.ts_ssn_trunc = true;
         for tx in &mut dce_state.transactions {
             tx.req_done = true;
+            if let Some(flow) = dce_state.flow {
+                sc_app_layer_parser_trigger_raw_stream_reassembly(flow, core::STREAM_TOSERVER.into());
+            }
         }
         SCLogDebug!("dce_state.ts_ssn_trunc = true; txs {}", dce_state.transactions.len());
     } else if direction & core::STREAM_TOCLIENT != 0 {
         dce_state.tc_ssn_trunc = true;
         for tx in &mut dce_state.transactions {
             tx.resp_done = true;
+            if let Some(flow) = dce_state.flow {
+                sc_app_layer_parser_trigger_raw_stream_reassembly(flow, core::STREAM_TOCLIENT.into());
+            }
         }
         SCLogDebug!("dce_state.tc_ssn_trunc = true; txs {}", dce_state.transactions.len());
     }