From: Victor Julien Date: Fri, 25 Mar 2022 10:17:23 +0000 (+0100) Subject: smb1: apply close to direction X-Git-Tag: suricata-6.0.5~59 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F7190%2Fhead;p=thirdparty%2Fsuricata.git smb1: apply close to direction Instead of closing files in both direction when receiving a close request, close only toserver files for the request and close toclient on receiving a response. (cherry picked from commit b336882008d3640973fa71be6f36f3de33d3cd25) --- diff --git a/rust/src/smb/smb1.rs b/rust/src/smb/smb1.rs index fe7c553133..3ef6b00ada 100644 --- a/rust/src/smb/smb1.rs +++ b/rust/src/smb/smb1.rs @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 Open Information Security Foundation +/* Copyright (C) 2018-2022 Open Information Security Foundation * * You can copy, redistribute or modify this Program under the terms of * the GNU General Public License version 2 as published by the Free @@ -143,39 +143,19 @@ pub fn smb1_check_tx(cmd: u8) -> bool { } } -fn smb1_close_file(state: &mut SMBState, fid: &Vec) +fn smb1_close_file(state: &mut SMBState, fid: &Vec, direction: u8) { - // we can have created 2 txs for a FID: one for reads - // and one for writes. So close both. - match state.get_file_tx_by_fuid(&fid, STREAM_TOSERVER) { - Some((tx, files, flags)) => { - SCLogDebug!("found tx {}", tx.id); - if let Some(SMBTransactionTypeData::FILE(ref mut tdf)) = tx.type_data { - if !tx.request_done { - SCLogDebug!("closing file tx {} FID {:?}", tx.id, fid); - tdf.file_tracker.close(files, flags); - tx.request_done = true; - tx.response_done = true; - SCLogDebug!("tx {} is done", tx.id); - } - } - }, - None => { }, - } - match state.get_file_tx_by_fuid(&fid, STREAM_TOCLIENT) { - Some((tx, files, flags)) => { - SCLogDebug!("found tx {}", tx.id); - if let Some(SMBTransactionTypeData::FILE(ref mut tdf)) = tx.type_data { - if !tx.request_done { - SCLogDebug!("closing file tx {} FID {:?}", tx.id, fid); - tdf.file_tracker.close(files, flags); - tx.request_done = true; - tx.response_done = true; - SCLogDebug!("tx {} is done", tx.id); - } + if let Some((tx, files, flags)) = state.get_file_tx_by_fuid(&fid, direction) { + SCLogDebug!("found tx {}", tx.id); + if let Some(SMBTransactionTypeData::FILE(ref mut tdf)) = tx.type_data { + if !tx.request_done { + SCLogDebug!("closing file tx {} FID {:?}", tx.id, fid); + tdf.file_tracker.close(files, flags); + tx.request_done = true; + tx.response_done = true; + SCLogDebug!("tx {} is done", tx.id); } - }, - None => { }, + } } } @@ -534,8 +514,10 @@ pub fn smb1_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32 { Ok((_, cd)) => { let mut fid = cd.fid.to_vec(); fid.extend_from_slice(&u32_as_bytes(r.ssn_id)); + state.ssn2vec_map.insert(SMBCommonHdr::from1(r, SMBHDR_TYPE_GUID), fid.to_vec()); + SCLogDebug!("closing FID {:?}/{:?}", cd.fid, fid); - smb1_close_file(state, &fid); + smb1_close_file(state, &fid, STREAM_TOSERVER); }, _ => { events.push(SMBEvent::MalformedData); @@ -743,6 +725,14 @@ pub fn smb1_response_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32 false } }, + SMB1_COMMAND_CLOSE => { + let fid = state.ssn2vec_map.remove(&SMBCommonHdr::from1(r, SMBHDR_TYPE_GUID)); + if let Some(fid) = fid { + SCLogDebug!("closing FID {:?}", fid); + smb1_close_file(state, &fid, STREAM_TOCLIENT); + } + false + }, SMB1_COMMAND_TRANS => { smb1_trans_response_record(state, r); true @@ -958,7 +948,7 @@ pub fn smb1_write_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) if r.command == SMB1_COMMAND_WRITE_AND_CLOSE { SCLogDebug!("closing FID {:?}", file_fid); - smb1_close_file(state, &file_fid); + smb1_close_file(state, &file_fid, STREAM_TOSERVER); } }, _ => {