smb2: improve read/write record parsing

parse_smb2_response_read()/parse_smb2_response_write() can be called on
incomplete data, so they didn't use the read/write length field to grab
the data field. Instead it just used rest(). However in some cases
SMB2 records have trailing data, which would be included in the
READ/WRITE data.

This patch addresses this by using the length field if enough data is
available.
pull/3315/head
Victor Julien 8 years ago
parent 97c224d193
commit eac7a92200

@ -15,7 +15,7 @@
* 02110-1301, USA. * 02110-1301, USA.
*/ */
use nom::{rest, le_u8, le_u16, le_u32, le_u64, AsBytes}; use nom::{rest, le_u8, le_u16, le_u32, le_u64, AsBytes, IResult};
use smb::smb::*; use smb::smb::*;
#[derive(Debug,PartialEq)] #[derive(Debug,PartialEq)]
@ -352,6 +352,7 @@ pub struct Smb2WriteRequestRecord<'a> {
pub data: &'a[u8], pub data: &'a[u8],
} }
// can be called on incomplete records
named!(pub parse_smb2_request_write<Smb2WriteRequestRecord>, named!(pub parse_smb2_request_write<Smb2WriteRequestRecord>,
do_parse!( do_parse!(
skip1: take!(4) skip1: take!(4)
@ -362,7 +363,7 @@ named!(pub parse_smb2_request_write<Smb2WriteRequestRecord>,
>> remaining_bytes: le_u32 >> remaining_bytes: le_u32
>> write_flags: le_u32 >> write_flags: le_u32
>> skip2: take!(4) >> skip2: take!(4)
>> data: rest >> data: apply!(parse_smb2_data, wr_len)
>> (Smb2WriteRequestRecord { >> (Smb2WriteRequestRecord {
wr_len:wr_len, wr_len:wr_len,
wr_offset:wr_offset, wr_offset:wr_offset,
@ -401,12 +402,31 @@ pub struct Smb2ReadResponseRecord<'a> {
pub data: &'a[u8], pub data: &'a[u8],
} }
// parse read/write data. If all is available, 'take' it.
// otherwise just return what we have. So this may return
// partial data.
fn parse_smb2_data<'a>(i: &'a[u8], len: u32)
-> IResult<&'a[u8], &'a[u8]>
{
if len as usize > i.len() {
IResult::Done(&[], i)
} else {
do_parse!(i,
data: take!(len)
>> (data)
)
}
}
// can be called on incomplete records
named!(pub parse_smb2_response_read<Smb2ReadResponseRecord>, named!(pub parse_smb2_response_read<Smb2ReadResponseRecord>,
do_parse!( do_parse!(
skip1: take!(4) struct_size: le_u16
>> data_offset: le_u16
>> rd_len: le_u32 >> rd_len: le_u32
>> skip2: take!(8) >> rd_rem: le_u32
>> data: rest >> _padding: take!(4)
>> data: apply!(parse_smb2_data, rd_len)
>> (Smb2ReadResponseRecord { >> (Smb2ReadResponseRecord {
len : rd_len, len : rd_len,
data : data, data : data,

Loading…
Cancel
Save