]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
dcerpc/tcp: implement trunc logic
authorVictor Julien <victor@inliniac.net>
Sat, 19 Sep 2020 18:44:40 +0000 (20:44 +0200)
committerVictor Julien <victor@inliniac.net>
Fri, 25 Sep 2020 05:24:59 +0000 (07:24 +0200)
When one side of the connection reaches the STREAM_DEPTH condition the
parser should be aware of this. Otherwise transactions will forever be
waiting for data in that direction.

rust/src/dcerpc/dcerpc.rs
src/app-layer-dcerpc.c

index d029e1bd559bc9ff23985b03662534adca8c8b5b..fdf5c8e163040e1c160b9e8cab7bac6704043a7f 100644 (file)
@@ -306,6 +306,8 @@ pub struct DCERPCState {
     pub tc_gap: bool,
     pub ts_ssn_gap: bool,
     pub tc_ssn_gap: bool,
+    pub ts_ssn_trunc: bool, /// true if Truncated in this direction
+    pub tc_ssn_trunc: bool,
 }
 
 impl DCERPCState {
@@ -330,6 +332,8 @@ impl DCERPCState {
             tc_gap: false,
             ts_ssn_gap: false,
             tc_ssn_gap: false,
+            ts_ssn_trunc: false,
+            tc_ssn_trunc: false,
         };
     }
 
@@ -340,6 +344,8 @@ impl DCERPCState {
         tx.call_id = call_id;
         tx.endianness = endianness;
         self.tx_id += 1;
+        tx.req_done = self.ts_ssn_trunc;
+        tx.resp_done = self.tc_ssn_trunc;
         tx
     }
 
@@ -1153,6 +1159,24 @@ pub extern "C" fn rs_dcerpc_state_transaction_free(_state: *mut std::os::raw::c_
     // do nothing
 }
 
+#[no_mangle]
+pub extern "C" fn rs_dcerpc_state_trunc(state: *mut std::os::raw::c_void, direction: u8) {
+    let dce_state = cast_pointer!(state, DCERPCState);
+    if direction & core::STREAM_TOSERVER != 0 {
+        dce_state.ts_ssn_trunc = true;
+        for tx in &mut dce_state.transactions {
+            tx.req_done = true;
+        }
+        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;
+        }
+        SCLogDebug!("dce_state.tc_ssn_trunc = true; txs {}", dce_state.transactions.len());
+    }
+}
+
 #[no_mangle]
 pub extern "C" fn rs_dcerpc_get_tx_detect_state(
     vtx: *mut std::os::raw::c_void,
index 45ad3ac31bd6cfeda2aeeb03224769006eef86b9..5d1c391729c0734ca45749af1d6d40a334e083b8 100644 (file)
@@ -182,6 +182,8 @@ void RegisterDCERPCParsers(void)
                                                                DCERPCGetAlstateProgressCompletionStatus);
         /* This parser accepts gaps. */
         AppLayerParserRegisterOptionFlags(IPPROTO_TCP, ALPROTO_DCERPC, APP_LAYER_PARSER_OPT_ACCEPT_GAPS);
+
+        AppLayerParserRegisterTruncateFunc(IPPROTO_TCP, ALPROTO_DCERPC, rs_dcerpc_state_trunc);
     } else {
         SCLogInfo("Parsed disabled for %s protocol. Protocol detection"
                   "still on.", proto_name);