files: move FileContainer into FileTransferTracker

Update SMB, NFS, HTTP2.
pull/8426/head
Victor Julien 4 years ago
parent aa376a3b21
commit 6cc9811edd

@ -56,6 +56,9 @@ pub struct FileTransferTracker {
track_id: u32,
chunk_left: u32,
pub file: FileContainer,
pub file_flags: u16,
pub tx_id: u64,
fill_bytes: u8,
@ -82,35 +85,32 @@ impl FileTransferTracker {
!self.file_open
}
fn open(&mut self, config: &'static SuricataFileContext,
files: &mut FileContainer, flags: u16, name: &[u8]) -> i32
fn open(&mut self, config: &'static SuricataFileContext, name: &[u8]) -> i32
{
let r = files.file_open(config, self.track_id, name, flags);
let r = self.file.file_open(config, self.track_id, name, self.file_flags);
if r == 0 {
self.file_open = true;
}
r
}
pub fn close(&mut self, config: &'static SuricataFileContext,
files: &mut FileContainer, flags: u16)
pub fn close(&mut self, config: &'static SuricataFileContext)
{
if !self.file_is_truncated {
SCLogDebug!("closing file with id {}", self.track_id);
files.file_close(config, &self.track_id, flags);
self.file.file_close(config, &self.track_id, self.file_flags);
}
self.file_open = false;
self.tracked = 0;
}
pub fn trunc (&mut self, config: &'static SuricataFileContext,
files: &mut FileContainer, flags: u16)
pub fn trunc (&mut self, config: &'static SuricataFileContext)
{
if self.file_is_truncated || !self.file_open {
return;
}
let myflags = flags | 1; // TODO util-file.c::FILE_TRUNCATED
files.file_close(config, &self.track_id, myflags);
let myflags = self.file_flags | 1; // TODO util-file.c::FILE_TRUNCATED
self.file.file_close(config, &self.track_id, myflags);
SCLogDebug!("truncated file");
self.file_is_truncated = true;
self.chunks.clear();
@ -125,13 +125,12 @@ impl FileTransferTracker {
}
pub fn new_chunk(&mut self, config: &'static SuricataFileContext,
files: &mut FileContainer, flags: u16,
name: &[u8], data: &[u8], chunk_offset: u64, chunk_size: u32,
fill_bytes: u8, is_last: bool, xid: &u32) -> u32
{
if self.chunk_left != 0 || self.fill_bytes != 0 {
SCLogDebug!("current chunk incomplete: truncating");
self.trunc(config, files, flags);
self.trunc(config);
}
SCLogDebug!("NEW CHUNK: chunk_size {} fill_bytes {}", chunk_size, fill_bytes);
@ -143,7 +142,7 @@ impl FileTransferTracker {
SCLogDebug!("NEW CHUNK IS OOO: expected {}, got {}", self.tracked, chunk_offset);
if is_last {
SCLogDebug!("last chunk is out of order, this means we missed data before");
self.trunc(config, files, flags);
self.trunc(config);
}
self.chunk_is_ooo = true;
self.cur_ooo_chunk_offset = chunk_offset;
@ -159,11 +158,11 @@ impl FileTransferTracker {
if !self.file_open {
SCLogDebug!("NEW CHUNK: FILE OPEN");
self.track_id = *xid;
self.open(config, files, flags, name);
self.open(config, name);
}
if self.file_open {
let res = self.update(config, files, flags, data, 0);
let res = self.update(config, data, 0);
SCLogDebug!("NEW CHUNK: update res {:?}", res);
return res;
}
@ -174,8 +173,7 @@ impl FileTransferTracker {
/// update the file tracker
/// If gap_size > 0 'data' should not be used.
/// return how much we consumed of data
pub fn update(&mut self, config: &'static SuricataFileContext,
files: &mut FileContainer, flags: u16, data: &[u8], gap_size: u32) -> u32
pub fn update(&mut self, config: &'static SuricataFileContext, data: &[u8], gap_size: u32) -> u32
{
if self.file_is_truncated {
let consumed = std::cmp::min(data.len() as u32, self.chunk_left);
@ -192,7 +190,7 @@ impl FileTransferTracker {
//SCLogDebug!("UPDATE: nothing to do");
if self.chunk_is_last {
SCLogDebug!("last empty chunk, closing");
self.close(config, files, flags);
self.close(config);
self.chunk_is_last = false;
}
return 0
@ -217,7 +215,7 @@ impl FileTransferTracker {
let d = &data[0..self.chunk_left as usize];
if !self.chunk_is_ooo {
let res = files.file_append(config, &self.track_id, d, is_gap);
let res = self.file.file_append(config, &self.track_id, d, is_gap);
match res {
0 => { },
-2 => {
@ -270,7 +268,7 @@ impl FileTransferTracker {
Some(c) => {
self.in_flight -= c.chunk.len() as u64;
let res = files.file_append(config, &self.track_id, &c.chunk, c.contains_gap);
let res = self.file.file_append(config, &self.track_id, &c.chunk, c.contains_gap);
match res {
0 => { },
-2 => {
@ -302,7 +300,7 @@ impl FileTransferTracker {
}
if self.chunk_is_last {
SCLogDebug!("last chunk, closing");
self.close(config, files, flags);
self.close(config);
self.chunk_is_last = false;
} else {
SCLogDebug!("NOT last chunk, keep going");
@ -310,7 +308,7 @@ impl FileTransferTracker {
} else {
if !self.chunk_is_ooo {
let res = files.file_append(config, &self.track_id, data, is_gap);
let res = self.file.file_append(config, &self.track_id, data, is_gap);
match res {
0 => { },
-2 => {

@ -137,13 +137,11 @@ pub struct HTTP2Transaction {
pub tx_data: AppLayerTxData,
pub ft_tc: FileTransferTracker,
ft_ts: FileTransferTracker,
pub ft_ts: FileTransferTracker,
//temporary escaped header for detection
//must be attached to transaction for memory management (be freed at the right time)
pub escaped: Vec<Vec<u8>>,
pub files: Files,
}
impl Transaction for HTTP2Transaction {
@ -173,7 +171,6 @@ impl HTTP2Transaction {
ft_tc: FileTransferTracker::new(),
ft_ts: FileTransferTracker::new(),
escaped: Vec::with_capacity(16),
files: Files::default(),
}
}
@ -210,8 +207,8 @@ impl HTTP2Transaction {
}
pub fn update_file_flags(&mut self, flow_file_flags: u16) {
self.files.flags_ts = unsafe { FileFlowFlagsToFlags(flow_file_flags, STREAM_TOSERVER) | FILE_USE_DETECT };
self.files.flags_tc = unsafe { FileFlowFlagsToFlags(flow_file_flags, STREAM_TOCLIENT) | FILE_USE_DETECT };
self.ft_ts.file_flags = unsafe { FileFlowFlagsToFlags(flow_file_flags, STREAM_TOSERVER) | FILE_USE_DETECT };
self.ft_tc.file_flags = unsafe { FileFlowFlagsToFlags(flow_file_flags, STREAM_TOCLIENT) | FILE_USE_DETECT };
}
fn decompress<'a>(
@ -250,11 +247,8 @@ impl HTTP2Transaction {
range::http2_range_append(sfcm, self.file_range, decompressed)
}
}
let (files, flags) = self.files.get(Direction::ToClient);
self.ft_tc.new_chunk(
sfcm,
files,
flags,
b"",
decompressed,
self.ft_tc.tracked, //offset = append
@ -268,11 +262,8 @@ impl HTTP2Transaction {
if !self.ft_ts.file_open {
self.tx_data.incr_files_opened();
}
let (files, flags) = self.files.get(Direction::ToServer);
self.ft_ts.new_chunk(
sfcm,
files,
flags,
b"",
decompressed,
self.ft_ts.tracked, //offset = append
@ -365,8 +356,8 @@ impl HTTP2Transaction {
impl Drop for HTTP2Transaction {
fn drop(&mut self) {
if let Some(sfcm) = unsafe { SURICATA_HTTP2_FILE_CONFIG } {
self.files.files_ts.free(sfcm);
self.files.files_tc.free(sfcm);
self.ft_ts.file.free(sfcm);
self.ft_tc.file.free(sfcm);
}
self.free();
}
@ -466,7 +457,7 @@ impl HTTP2State {
if let Some(sfcm) = unsafe { SURICATA_HTTP2_FILE_CONFIG } {
(c.HTPFileCloseHandleRange)(
sfcm.files_sbcfg,
&mut tx.files.files_tc,
&mut tx.ft_tc.file,
0,
tx.file_range,
std::ptr::null_mut(),
@ -507,7 +498,7 @@ impl HTTP2State {
if let Some(sfcm) = unsafe { SURICATA_HTTP2_FILE_CONFIG } {
(c.HTPFileCloseHandleRange)(
sfcm.files_sbcfg,
&mut tx.files.files_tc,
&mut tx.ft_tc.file,
0,
tx.file_range,
std::ptr::null_mut(),
@ -1216,9 +1207,12 @@ pub unsafe extern "C" fn rs_http2_getfiles(
tx: *mut std::os::raw::c_void, direction: u8,
) -> AppLayerGetFileState {
let tx = cast_pointer!(tx, HTTP2Transaction);
let (files, _flags) = tx.files.get(direction.into());
if let Some(sfcm) = { SURICATA_HTTP2_FILE_CONFIG } {
return AppLayerGetFileState { fc: files, cfg: sfcm.files_sbcfg }
if direction & STREAM_TOSERVER != 0 {
return AppLayerGetFileState { fc: &mut tx.ft_ts.file, cfg: sfcm.files_sbcfg }
} else {
return AppLayerGetFileState { fc: &mut tx.ft_tc.file, cfg: sfcm.files_sbcfg }
}
}
AppLayerGetFileState::err()
}

@ -131,7 +131,7 @@ pub fn http2_range_open(
// whole file in one range
return;
}
let (_, flags) = tx.files.get(dir);
let flags = if dir == Direction::ToServer { tx.ft_ts.file_flags } else { tx.ft_tc.file_flags };
if let Ok((key, index)) = http2_range_key_get(tx) {
let name = &key[index..];
tx.file_range = unsafe {
@ -162,7 +162,11 @@ pub fn http2_range_close(
) {
let added = if let Some(c) = unsafe { SC } {
if let Some(sfcm) = unsafe { SURICATA_HTTP2_FILE_CONFIG } {
let (files, flags) = tx.files.get(dir);
let (files, flags) = if dir == Direction::ToServer {
(&mut tx.ft_ts.file, tx.ft_ts.file_flags)
} else {
(&mut tx.ft_tc.file, tx.ft_tc.file_flags)
};
let added = (c.HTPFileCloseHandleRange)(
sfcm.files_sbcfg,
files,

@ -123,6 +123,10 @@ pub enum NFSTransactionTypeData {
#[derive(Default, Debug)]
pub struct NFSTransactionFile {
/// file transactions are unidirectional in the sense that they track
/// a single file on one direction
pub direction: Direction, // Direction::ToClient or Direction::ToServer
/// additional procedures part of a single file transfer. Currently
/// only COMMIT on WRITEs.
pub file_additional_procs: Vec<u32>,
@ -139,9 +143,6 @@ pub struct NFSTransactionFile {
/// file tracker for a single file. Boxed so that we don't use
/// as much space if we're not a file tx.
pub file_tracker: FileTransferTracker,
/// storage for the actual file
pub files: Files,
}
impl NFSTransactionFile {
@ -152,8 +153,8 @@ impl NFSTransactionFile {
}
}
pub fn update_file_flags(&mut self, flow_file_flags: u16) {
self.files.flags_ts = unsafe { FileFlowFlagsToFlags(flow_file_flags, STREAM_TOSERVER) | FILE_USE_DETECT };
self.files.flags_tc = unsafe { FileFlowFlagsToFlags(flow_file_flags, STREAM_TOCLIENT) | FILE_USE_DETECT };
let dir_flag = if self.direction == Direction::ToServer { STREAM_TOSERVER } else { STREAM_TOCLIENT };
self.file_tracker.file_flags = unsafe { FileFlowFlagsToFlags(flow_file_flags, dir_flag) | FILE_USE_DETECT };
}
}
@ -161,9 +162,11 @@ impl NFSTransactionFile {
pub unsafe extern "C" fn rs_nfs_gettxfiles(_state: *mut std::ffi::c_void, tx: *mut std::ffi::c_void, direction: u8) -> AppLayerGetFileState {
let tx = cast_pointer!(tx, NFSTransaction);
if let Some(NFSTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
let (files, _flags) = tdf.files.get(direction.into());
if let Some(sfcm) = { SURICATA_NFS_FILE_CONFIG } {
return AppLayerGetFileState { fc: files, cfg: sfcm.files_sbcfg }
let tx_dir : u8 = tdf.direction.into();
if direction & tx_dir != 0 {
if let Some(sfcm) = { SURICATA_NFS_FILE_CONFIG } {
return AppLayerGetFileState { fc: &mut tdf.file_tracker.file, cfg: sfcm.files_sbcfg }
}
}
}
AppLayerGetFileState::err()
@ -199,9 +202,6 @@ pub struct NFSTransaction {
/// is a special file tx that we look up by file_handle instead of XID
pub is_file_tx: bool,
pub is_file_closed: bool,
/// file transactions are unidirectional in the sense that they track
/// a single file on one direction
pub file_tx_direction: Direction, // Direction::ToClient or Direction::ToServer
pub file_handle: Vec<u8>,
/// Procedure type specific data
@ -238,7 +238,6 @@ impl NFSTransaction {
nfs_version:0,
is_file_tx: false,
is_file_closed: false,
file_tx_direction: Direction::ToServer,
file_handle:Vec::new(),
type_data: None,
tx_data: AppLayerTxData::new(),
@ -261,8 +260,7 @@ impl Drop for NFSTransaction {
fn drop(&mut self) {
if let Some(NFSTransactionTypeData::FILE(ref mut tdf)) = self.type_data {
if let Some(sfcm) = unsafe { SURICATA_NFS_FILE_CONFIG } {
tdf.files.files_ts.free(sfcm);
tdf.files.files_tc.free(sfcm);
tdf.file_tracker.file.free(sfcm);
}
}
self.free();
@ -298,37 +296,33 @@ impl NFSRequestXidMap {
}
/// little wrapper around the FileTransferTracker::new_chunk method
pub fn filetracker_newchunk(ft: &mut FileTransferTracker, files: &mut FileContainer,
flags: u16, name: &[u8], data: &[u8],
pub fn filetracker_newchunk(ft: &mut FileTransferTracker, name: &[u8], data: &[u8],
chunk_offset: u64, chunk_size: u32, fill_bytes: u8, is_last: bool, xid: &u32)
{
if let Some(sfcm) = unsafe { SURICATA_NFS_FILE_CONFIG } {
ft.new_chunk(sfcm, files, flags, name, data, chunk_offset,
ft.new_chunk(sfcm, name, data, chunk_offset,
chunk_size, fill_bytes, is_last, xid);
}
}
fn filetracker_trunc(ft: &mut FileTransferTracker, files: &mut FileContainer,
flags: u16)
fn filetracker_trunc(ft: &mut FileTransferTracker)
{
if let Some(sfcm) = unsafe { SURICATA_NFS_FILE_CONFIG } {
ft.trunc(sfcm, files, flags);
ft.trunc(sfcm);
}
}
pub fn filetracker_close(ft: &mut FileTransferTracker, files: &mut FileContainer,
flags: u16)
pub fn filetracker_close(ft: &mut FileTransferTracker)
{
if let Some(sfcm) = unsafe { SURICATA_NFS_FILE_CONFIG } {
ft.close(sfcm, files, flags);
ft.close(sfcm);
}
}
fn filetracker_update(ft: &mut FileTransferTracker, files: &mut FileContainer,
flags: u16, data: &[u8], gap_size: u32) -> u32
fn filetracker_update(ft: &mut FileTransferTracker, data: &[u8], gap_size: u32) -> u32
{
if let Some(sfcm) = unsafe { SURICATA_NFS_FILE_CONFIG } {
ft.update(sfcm, files, flags, data, gap_size)
ft.update(sfcm, data, gap_size)
} else {
0
}
@ -621,8 +615,7 @@ impl NFSState {
if self.ts > f.post_gap_ts {
tx.request_done = true;
tx.response_done = true;
let (files, flags) = f.files.get(tx.file_tx_direction);
filetracker_trunc(&mut f.file_tracker, files, flags);
filetracker_trunc(&mut f.file_tracker);
} else {
post_gap_txs = true;
}
@ -733,10 +726,10 @@ impl NFSState {
tx.file_name = file_name.to_vec();
tx.file_handle = file_handle.to_vec();
tx.is_file_tx = true;
tx.file_tx_direction = direction;
tx.type_data = Some(NFSTransactionTypeData::FILE(NFSTransactionFile::new()));
if let Some(NFSTransactionTypeData::FILE(ref mut d)) = tx.type_data {
d.direction = direction;
d.file_tracker.tx_id = tx.id - 1;
tx.tx_data.update_file_flags(self.state_data.file_flags);
d.update_file_flags(tx.tx_data.file_flags);
@ -757,7 +750,7 @@ impl NFSState {
for tx in &mut self.transactions {
if let Some(NFSTransactionTypeData::FILE(ref mut d)) = tx.type_data {
if tx.is_file_tx && !tx.is_file_closed &&
direction == tx.file_tx_direction &&
direction == d.direction &&
tx.file_handle == fh
{
tx.tx_data.update_file_flags(self.state_data.file_flags);
@ -797,8 +790,7 @@ impl NFSState {
let found = match self.get_file_tx_by_handle(&file_handle, Direction::ToServer) {
Some(tx) => {
if let Some(NFSTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
let (files, flags) = tdf.files.get(Direction::ToServer);
filetracker_newchunk(&mut tdf.file_tracker, files, flags,
filetracker_newchunk(&mut tdf.file_tracker,
&file_name, w.file_data, w.offset,
w.file_len, fill_bytes as u8, is_last, &r.hdr.xid);
tdf.chunk_count += 1;
@ -818,8 +810,7 @@ impl NFSState {
if !found {
let tx = self.new_file_tx(&file_handle, &file_name, Direction::ToServer);
if let Some(NFSTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
let (files, flags) = tdf.files.get(Direction::ToServer);
filetracker_newchunk(&mut tdf.file_tracker, files, flags,
filetracker_newchunk(&mut tdf.file_tracker,
&file_name, w.file_data, w.offset,
w.file_len, fill_bytes as u8, is_last, &r.hdr.xid);
tx.procedure = NFSPROC3_WRITE;
@ -972,12 +963,11 @@ impl NFSState {
let consumed = match self.get_file_tx_by_handle(&file_handle, direction) {
Some(tx) => {
if let Some(NFSTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
let (files, flags) = tdf.files.get(direction);
if ssn_gap {
let queued_data = tdf.file_tracker.get_queued_size();
if queued_data > 2000000 { // TODO should probably be configurable
SCLogDebug!("QUEUED size {} while we've seen GAPs. Truncating file.", queued_data);
filetracker_trunc(&mut tdf.file_tracker, files, flags);
filetracker_trunc(&mut tdf.file_tracker);
}
}
@ -987,7 +977,7 @@ impl NFSState {
}
tdf.chunk_count += 1;
let cs = filetracker_update(&mut tdf.file_tracker, files, flags, data, gap_size);
let cs = filetracker_update(&mut tdf.file_tracker, data, gap_size);
/* see if we need to close the tx */
if tdf.file_tracker.is_done() {
if direction == Direction::ToClient {
@ -1076,8 +1066,7 @@ impl NFSState {
Some(tx) => {
SCLogDebug!("updated TX {:?}", tx);
if let Some(NFSTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
let (files, flags) = tdf.files.get(Direction::ToClient);
filetracker_newchunk(&mut tdf.file_tracker, files, flags,
filetracker_newchunk(&mut tdf.file_tracker,
&file_name, reply.data, chunk_offset,
reply.count, fill_bytes as u8, is_last, &r.hdr.xid);
tdf.chunk_count += 1;
@ -1105,8 +1094,7 @@ impl NFSState {
if !found {
let tx = self.new_file_tx(&file_handle, &file_name, Direction::ToClient);
if let Some(NFSTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
let (files, flags) = tdf.files.get(Direction::ToClient);
filetracker_newchunk(&mut tdf.file_tracker, files, flags,
filetracker_newchunk(&mut tdf.file_tracker,
&file_name, reply.data, chunk_offset,
reply.count, fill_bytes as u8, is_last, &r.hdr.xid);
tx.procedure = if nfs_version < 4 { NFSPROC3_READ } else { NFSPROC4_READ };

@ -120,10 +120,9 @@ impl NFSState {
let file_handle = rd.handle.value.to_vec();
if let Some(tx) = self.get_file_tx_by_handle(&file_handle, Direction::ToServer) {
if let Some(NFSTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
let (files, flags) = tdf.files.get(Direction::ToServer);
tdf.chunk_count += 1;
tdf.file_additional_procs.push(NFSPROC3_COMMIT);
filetracker_close(&mut tdf.file_tracker, files, flags);
filetracker_close(&mut tdf.file_tracker);
tdf.file_last_xid = r.hdr.xid;
tx.is_last = true;
tx.request_done = true;

@ -68,8 +68,7 @@ impl NFSState {
let found = match self.get_file_tx_by_handle(&file_handle, Direction::ToServer) {
Some(tx) => {
if let Some(NFSTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
let (files, flags) = tdf.files.get(Direction::ToServer);
filetracker_newchunk(&mut tdf.file_tracker, files, flags,
filetracker_newchunk(&mut tdf.file_tracker,
&file_name, w.data, w.offset,
w.write_len, fill_bytes as u8, is_last, &r.hdr.xid);
tdf.chunk_count += 1;
@ -86,8 +85,7 @@ impl NFSState {
if !found {
let tx = self.new_file_tx(&file_handle, &file_name, Direction::ToServer);
if let Some(NFSTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
let (files, flags) = tdf.files.get(Direction::ToServer);
filetracker_newchunk(&mut tdf.file_tracker, files, flags,
filetracker_newchunk(&mut tdf.file_tracker,
&file_name, w.data, w.offset,
w.write_len, fill_bytes as u8, is_last, &r.hdr.xid);
tx.procedure = NFSPROC4_WRITE;
@ -117,8 +115,7 @@ impl NFSState {
let file_handle = fh.to_vec();
if let Some(tx) = self.get_file_tx_by_handle(&file_handle, Direction::ToServer) {
if let Some(NFSTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
let (files, flags) = tdf.files.get(Direction::ToServer);
filetracker_close(&mut tdf.file_tracker, files, flags);
filetracker_close(&mut tdf.file_tracker);
tdf.file_last_xid = r.hdr.xid;
tx.is_last = true;
tx.request_done = true;

@ -33,7 +33,7 @@ pub struct SMBTransactionFile {
/// after a gap, this will be set to a time in the future. If the file
/// receives no updates before that, it will be considered complete.
pub post_gap_ts: u64,
pub files: Files,
//pub files: Files,
}
impl SMBTransactionFile {
@ -45,43 +45,39 @@ impl SMBTransactionFile {
}
pub fn update_file_flags(&mut self, flow_file_flags: u16) {
self.files.flags_ts = unsafe { FileFlowFlagsToFlags(flow_file_flags, STREAM_TOSERVER) | FILE_USE_DETECT };
self.files.flags_tc = unsafe { FileFlowFlagsToFlags(flow_file_flags, STREAM_TOCLIENT) | FILE_USE_DETECT };
let dir_flag = if self.direction == Direction::ToServer { STREAM_TOSERVER } else { STREAM_TOCLIENT };
self.file_tracker.file_flags = unsafe { FileFlowFlagsToFlags(flow_file_flags, dir_flag) | FILE_USE_DETECT };
}
}
/// little wrapper around the FileTransferTracker::new_chunk method
pub fn filetracker_newchunk(ft: &mut FileTransferTracker, files: &mut FileContainer,
flags: u16, name: &[u8], data: &[u8],
pub fn filetracker_newchunk(ft: &mut FileTransferTracker, name: &[u8], data: &[u8],
chunk_offset: u64, chunk_size: u32, is_last: bool, xid: &u32)
{
if let Some(sfcm) = unsafe { SURICATA_SMB_FILE_CONFIG } {
ft.new_chunk(sfcm, files, flags, name, data, chunk_offset,
ft.new_chunk(sfcm, name, data, chunk_offset,
chunk_size, 0, is_last, xid);
}
}
pub fn filetracker_trunc(ft: &mut FileTransferTracker, files: &mut FileContainer,
flags: u16)
pub fn filetracker_trunc(ft: &mut FileTransferTracker)
{
if let Some(sfcm) = unsafe { SURICATA_SMB_FILE_CONFIG } {
ft.trunc(sfcm, files, flags);
ft.trunc(sfcm);
}
}
pub fn filetracker_close(ft: &mut FileTransferTracker, files: &mut FileContainer,
flags: u16)
pub fn filetracker_close(ft: &mut FileTransferTracker)
{
if let Some(sfcm) = unsafe { SURICATA_SMB_FILE_CONFIG } {
ft.close(sfcm, files, flags);
ft.close(sfcm);
}
}
fn filetracker_update(ft: &mut FileTransferTracker, files: &mut FileContainer,
flags: u16, data: &[u8], gap_size: u32) -> u32
fn filetracker_update(ft: &mut FileTransferTracker, data: &[u8], gap_size: u32) -> u32
{
if let Some(sfcm) = unsafe { SURICATA_SMB_FILE_CONFIG } {
ft.update(sfcm, files, flags, data, gap_size)
ft.update(sfcm, data, gap_size)
} else {
0
}
@ -204,12 +200,11 @@ impl SMBState {
let consumed = match self.get_file_tx_by_fuid(&file_handle, direction) {
Some(tx) => {
if let Some(SMBTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
let (files, flags) = tdf.files.get(direction);
if ssn_gap {
let queued_data = tdf.file_tracker.get_queued_size();
if queued_data > 2000000 { // TODO should probably be configurable
SCLogDebug!("QUEUED size {} while we've seen GAPs. Truncating file.", queued_data);
filetracker_trunc(&mut tdf.file_tracker, files, flags);
filetracker_trunc(&mut tdf.file_tracker);
}
}
@ -219,7 +214,7 @@ impl SMBState {
}
let file_data = &data[0..data_to_handle_len];
filetracker_update(&mut tdf.file_tracker, files, flags, file_data, gap_size)
filetracker_update(&mut tdf.file_tracker, file_data, gap_size)
} else {
0
}
@ -238,9 +233,11 @@ use crate::applayer::AppLayerGetFileState;
pub unsafe extern "C" fn rs_smb_gettxfiles(_state: *mut std::ffi::c_void, tx: *mut std::ffi::c_void, direction: u8) -> AppLayerGetFileState {
let tx = cast_pointer!(tx, SMBTransaction);
if let Some(SMBTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
let (files, _flags) = tdf.files.get(direction.into());
if let Some(sfcm) = { SURICATA_SMB_FILE_CONFIG } {
return AppLayerGetFileState { fc: files, cfg: sfcm.files_sbcfg }
let tx_dir : u8 = tdf.direction.into();
if direction & tx_dir != 0 {
if let Some(sfcm) = { SURICATA_SMB_FILE_CONFIG } {
return AppLayerGetFileState { fc: &mut tdf.file_tracker.file, cfg: sfcm.files_sbcfg }
}
}
}
AppLayerGetFileState::err()

@ -530,8 +530,7 @@ impl Drop for SMBTransaction {
fn drop(&mut self) {
if let Some(SMBTransactionTypeData::FILE(ref mut tdf)) = self.type_data {
if let Some(sfcm) = unsafe { SURICATA_SMB_FILE_CONFIG } {
tdf.files.files_ts.free(sfcm);
tdf.files.files_tc.free(sfcm);
tdf.file_tracker.file.free(sfcm);
}
}
self.free();
@ -1103,8 +1102,7 @@ impl SMBState {
if self.ts > f.post_gap_ts {
tx.request_done = true;
tx.response_done = true;
let (files, flags) = f.files.get(f.direction);
filetracker_trunc(&mut f.file_tracker, files, flags);
filetracker_trunc(&mut f.file_tracker);
} else {
post_gap_txs = true;
}

@ -155,8 +155,7 @@ fn smb1_close_file(state: &mut SMBState, fid: &[u8], direction: Direction)
if let Some(SMBTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
if !tx.request_done {
SCLogDebug!("closing file tx {} FID {:?}", tx.id, fid);
let (files, flags) = tdf.files.get(direction);
filetracker_close(&mut tdf.file_tracker, files, flags);
filetracker_close(&mut tdf.file_tracker);
tx.request_done = true;
tx.response_done = true;
SCLogDebug!("tx {} is done", tx.id);
@ -965,8 +964,7 @@ pub fn smb1_write_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>, an
if rd.offset < tdf.file_tracker.tracked {
set_event_fileoverlap = true;
}
let (files, flags) = tdf.files.get(Direction::ToServer);
filetracker_newchunk(&mut tdf.file_tracker, files, flags,
filetracker_newchunk(&mut tdf.file_tracker,
&file_name, rd.data, rd.offset,
rd.len, false, &file_id);
SCLogDebug!("FID {:?} found at tx {} => {:?}", file_fid, tx.id, tx);
@ -993,12 +991,10 @@ pub fn smb1_write_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>, an
if rd.offset < tdf.file_tracker.tracked {
set_event_fileoverlap = true;
}
let (files, flags) = tdf.files.get(Direction::ToServer);
filetracker_newchunk(&mut tdf.file_tracker, files, flags,
filetracker_newchunk(&mut tdf.file_tracker,
&file_name, rd.data, rd.offset,
rd.len, false, &file_id);
tdf.share_name = share_name;
SCLogDebug!("files {:?}", files);
SCLogDebug!("tdf {:?}", tdf);
}
tx.vercmd.set_smb1_cmd(SMB1_COMMAND_WRITE_ANDX);
@ -1063,8 +1059,7 @@ pub fn smb1_read_response_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>, an
if offset < tdf.file_tracker.tracked {
set_event_fileoverlap = true;
}
let (files, flags) = tdf.files.get(Direction::ToClient);
filetracker_newchunk(&mut tdf.file_tracker, files, flags,
filetracker_newchunk(&mut tdf.file_tracker,
&file_name, rd.data, offset,
rd.len, false, &file_id);
}
@ -1080,8 +1075,7 @@ pub fn smb1_read_response_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>, an
if offset < tdf.file_tracker.tracked {
set_event_fileoverlap = true;
}
let (files, flags) = tdf.files.get(Direction::ToClient);
filetracker_newchunk(&mut tdf.file_tracker, files, flags,
filetracker_newchunk(&mut tdf.file_tracker,
&file_name, rd.data, offset,
rd.len, false, &file_id);
tdf.share_name = share_name;

@ -171,8 +171,7 @@ pub fn smb2_read_response_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
state.set_event(SMBEvent::ReadQueueCntExceeded);
state.set_skip(Direction::ToClient, rd.len, rd.data.len() as u32);
} else {
let (files, flags) = tdf.files.get(Direction::ToClient);
filetracker_newchunk(&mut tdf.file_tracker, files, flags,
filetracker_newchunk(&mut tdf.file_tracker,
&tdf.file_name, rd.data, offset,
rd.len, false, &file_id);
}
@ -245,8 +244,7 @@ pub fn smb2_read_response_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
state.set_event(SMBEvent::ReadQueueCntExceeded);
state.set_skip(Direction::ToClient, rd.len, rd.data.len() as u32);
} else {
let (files, flags) = tdf.files.get(Direction::ToClient);
filetracker_newchunk(&mut tdf.file_tracker, files, flags,
filetracker_newchunk(&mut tdf.file_tracker,
&file_name, rd.data, offset,
rd.len, false, &file_id);
}
@ -311,8 +309,7 @@ pub fn smb2_write_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
state.set_event(SMBEvent::WriteQueueCntExceeded);
state.set_skip(Direction::ToServer, wr.wr_len, wr.data.len() as u32);
} else {
let (files, flags) = tdf.files.get(Direction::ToServer);
filetracker_newchunk(&mut tdf.file_tracker, files, flags,
filetracker_newchunk(&mut tdf.file_tracker,
&file_name, wr.data, wr.wr_offset,
wr.wr_len, false, &file_id);
}
@ -380,8 +377,7 @@ pub fn smb2_write_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
state.set_event(SMBEvent::WriteQueueCntExceeded);
state.set_skip(Direction::ToServer, wr.wr_len, wr.data.len() as u32);
} else {
let (files, flags) = tdf.files.get(Direction::ToServer);
filetracker_newchunk(&mut tdf.file_tracker, files, flags,
filetracker_newchunk(&mut tdf.file_tracker,
&file_name, wr.data, wr.wr_offset,
wr.wr_len, false, &file_id);
}
@ -594,8 +590,7 @@ pub fn smb2_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
Some(tx) => {
if !tx.request_done {
if let Some(SMBTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
let (files, flags) = tdf.files.get(Direction::ToServer);
filetracker_close(&mut tdf.file_tracker, files, flags);
filetracker_close(&mut tdf.file_tracker);
}
}
tx.request_done = true;
@ -609,8 +604,7 @@ pub fn smb2_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
Some(tx) => {
if !tx.request_done {
if let Some(SMBTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
let (files, flags) = tdf.files.get(Direction::ToClient);
filetracker_close(&mut tdf.file_tracker, files, flags);
filetracker_close(&mut tdf.file_tracker);
}
}
tx.request_done = true;
@ -708,8 +702,7 @@ pub fn smb2_response_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
Some(tx) => {
if !tx.request_done {
if let Some(SMBTransactionTypeData::FILE(ref mut tdf)) = tx.type_data {
let (files, flags) = tdf.files.get(Direction::ToClient);
filetracker_close(&mut tdf.file_tracker, files, flags);
filetracker_close(&mut tdf.file_tracker);
}
}
tx.set_status(r.nt_status, false);

Loading…
Cancel
Save