rust/smb: convert to nom 8

Ticket: #8089
pull/14332/head
Jason Ish 10 months ago committed by Victor Julien
parent 02045e1d62
commit ef9cd7beff

@ -20,19 +20,19 @@ use crate::kerberos::*;
use crate::smb::ntlmssp_records::*;
use crate::smb::smb::*;
use nom7::{Err, IResult};
use nom8::{Err, IResult};
use der_parser::ber::BerObjectContent;
use der_parser::der::{parse_der_oid, parse_der_sequence};
fn parse_secblob_get_spnego(blob: &[u8]) -> IResult<&[u8], &[u8], SecBlobError>
{
let (rem, base_o) = der_parser::parse_der(blob).map_err(Err::convert)?;
let (rem, base_o) = der_parser::parse_der(blob).map_err(|_| Err::Error(SecBlobError::NotSpNego))?;
SCLogDebug!("parse_secblob_get_spnego: base_o {:?}", base_o);
let d = match base_o.content.as_slice() {
Err(_) => { return Err(Err::Error(SecBlobError::NotSpNego)); },
Ok(d) => d,
};
let (next, o) = parse_der_oid(d).map_err(Err::convert)?;
let (next, o) = parse_der_oid(d).map_err(|_| Err::Error(SecBlobError::NotSpNego))?;
SCLogDebug!("parse_secblob_get_spnego: sub_o {:?}", o);
let oid = match o.content.as_oid() {
@ -59,7 +59,7 @@ fn parse_secblob_get_spnego(blob: &[u8]) -> IResult<&[u8], &[u8], SecBlobError>
fn parse_secblob_spnego_start(blob: &[u8]) -> IResult<&[u8], &[u8], SecBlobError>
{
let (rem, o) = der_parser::parse_der(blob).map_err(Err::convert)?;
let (rem, o) = der_parser::parse_der(blob).map_err(|_| Err::Error(SecBlobError::NotSpNego))?;
let d = match o.content.as_slice() {
Ok(d) => {
SCLogDebug!("d: next data len {}",d.len());

@ -15,16 +15,16 @@
* 02110-1301, USA.
*/
use crate::common::nom7::bits;
use nom8::bits::bits;
use crate::smb::error::SmbError;
use nom7::bits::streaming::take as take_bits;
use nom7::bytes::streaming::take;
use nom7::combinator::{cond, rest};
use nom7::multi::count;
use nom7::number::Endianness;
use nom7::number::streaming::{be_u16, le_u8, le_u16, le_u32, u16, u32};
use nom7::sequence::tuple;
use nom7::{Err, IResult};
use nom8::bits::streaming::take as take_bits;
use nom8::bytes::streaming::take;
use nom8::combinator::{cond, rest};
use nom8::multi::count;
use nom8::number::Endianness;
use nom8::number::streaming::{be_u16, le_u8, le_u16, le_u32, u16, u32};
use nom8::Parser;
use nom8::{Err, IResult};
#[derive(Debug,PartialEq, Eq)]
pub struct DceRpcResponseRecord<'a> {
@ -39,8 +39,8 @@ pub fn parse_dcerpc_response_record(i:&[u8], frag_len: u16 )
if frag_len < 24 {
return Err(Err::Error(SmbError::RecordTooSmall));
}
let (i, _) = take(8_usize)(i)?;
let (i, data) = take(frag_len - 24)(i)?;
let (i, _) = take(8_usize).parse(i)?;
let (i, data) = take(frag_len - 24).parse(i)?;
let record = DceRpcResponseRecord { data };
Ok((i, record))
}
@ -60,11 +60,11 @@ pub fn parse_dcerpc_request_record(i:&[u8], frag_len: u16, little: bool)
if frag_len < 24 {
return Err(Err::Error(SmbError::RecordTooSmall));
}
let (i, _) = take(4_usize)(i)?;
let (i, _) = take(4_usize).parse(i)?;
let endian = if little { Endianness::Little } else { Endianness::Big };
let (i, context_id) = u16(endian)(i)?;
let (i, opnum) = u16(endian)(i)?;
let (i, data) = take(frag_len - 24)(i)?;
let (i, context_id) = u16(endian).parse(i)?;
let (i, opnum) = u16(endian).parse(i)?;
let (i, data) = take(frag_len - 24).parse(i)?;
let record = DceRpcRequestRecord { opnum, context_id, data };
Ok((i, record))
}
@ -77,13 +77,13 @@ pub struct DceRpcBindIface<'a> {
}
pub fn parse_dcerpc_bind_iface(i: &[u8]) -> IResult<&[u8], DceRpcBindIface<'_>> {
let (i, _ctx_id) = le_u16(i)?;
let (i, _num_trans_items) = le_u8(i)?;
let (i, _) = take(1_usize)(i)?; // reserved
let (i, interface) = take(16_usize)(i)?;
let (i, ver) = le_u16(i)?;
let (i, ver_min) = le_u16(i)?;
let (i, _) = take(20_usize)(i)?;
let (i, _ctx_id) = le_u16.parse(i)?;
let (i, _num_trans_items) = le_u8.parse(i)?;
let (i, _) = take(1_usize).parse(i)?; // reserved
let (i, interface) = take(16_usize).parse(i)?;
let (i, ver) = le_u16.parse(i)?;
let (i, ver_min) = le_u16.parse(i)?;
let (i, _) = take(20_usize).parse(i)?;
let res = DceRpcBindIface {
iface:interface,
ver,
@ -93,13 +93,13 @@ pub fn parse_dcerpc_bind_iface(i: &[u8]) -> IResult<&[u8], DceRpcBindIface<'_>>
}
pub fn parse_dcerpc_bind_iface_big(i: &[u8]) -> IResult<&[u8], DceRpcBindIface<'_>> {
let (i, _ctx_id) = le_u16(i)?;
let (i, _num_trans_items) = le_u8(i)?;
let (i, _) = take(1_usize)(i)?; // reserved
let (i, interface) = take(16_usize)(i)?;
let (i, ver_min) = be_u16(i)?;
let (i, ver) = be_u16(i)?;
let (i, _) = take(20_usize)(i)?;
let (i, _ctx_id) = le_u16.parse(i)?;
let (i, _num_trans_items) = le_u8.parse(i)?;
let (i, _) = take(1_usize).parse(i)?; // reserved
let (i, interface) = take(16_usize).parse(i)?;
let (i, ver_min) = be_u16.parse(i)?;
let (i, ver) = be_u16.parse(i)?;
let (i, _) = take(20_usize).parse(i)?;
let res = DceRpcBindIface {
iface:interface,
ver,
@ -115,12 +115,12 @@ pub struct DceRpcBindRecord<'a> {
}
pub fn parse_dcerpc_bind_record(i: &[u8]) -> IResult<&[u8], DceRpcBindRecord<'_>> {
let (i, _max_xmit_frag) = le_u16(i)?;
let (i, _max_recv_frag) = le_u16(i)?;
let (i, _assoc_group) = take(4_usize)(i)?;
let (i, num_ctx_items) = le_u8(i)?;
let (i, _) = take(3_usize)(i)?; // reserved
let (i, ifaces) = count(parse_dcerpc_bind_iface, num_ctx_items as usize)(i)?;
let (i, _max_xmit_frag) = le_u16.parse(i)?;
let (i, _max_recv_frag) = le_u16.parse(i)?;
let (i, _assoc_group) = take(4_usize).parse(i)?;
let (i, num_ctx_items) = le_u8.parse(i)?;
let (i, _) = take(3_usize).parse(i)?; // reserved
let (i, ifaces) = count(parse_dcerpc_bind_iface, num_ctx_items as usize).parse(i)?;
let record = DceRpcBindRecord {
num_ctx_items,
ifaces,
@ -129,12 +129,12 @@ pub fn parse_dcerpc_bind_record(i: &[u8]) -> IResult<&[u8], DceRpcBindRecord<'_>
}
pub fn parse_dcerpc_bind_record_big(i: &[u8]) -> IResult<&[u8], DceRpcBindRecord<'_>> {
let (i, _max_xmit_frag) = be_u16(i)?;
let (i, _max_recv_frag) = be_u16(i)?;
let (i, _assoc_group) = take(4_usize)(i)?;
let (i, num_ctx_items) = le_u8(i)?;
let (i, _) = take(3_usize)(i)?; // reserved
let (i, ifaces) = count(parse_dcerpc_bind_iface_big, num_ctx_items as usize)(i)?;
let (i, _max_xmit_frag) = be_u16.parse(i)?;
let (i, _max_recv_frag) = be_u16.parse(i)?;
let (i, _assoc_group) = take(4_usize).parse(i)?;
let (i, num_ctx_items) = le_u8.parse(i)?;
let (i, _) = take(3_usize).parse(i)?; // reserved
let (i, ifaces) = count(parse_dcerpc_bind_iface_big, num_ctx_items as usize).parse(i)?;
let record = DceRpcBindRecord {
num_ctx_items,
ifaces,
@ -151,10 +151,10 @@ pub struct DceRpcBindAckResult<'a> {
}
pub fn parse_dcerpc_bindack_result(i: &[u8]) -> IResult<&[u8], DceRpcBindAckResult<'_>> {
let (i, ack_result) = le_u16(i)?;
let (i, ack_reason) = le_u16(i)?;
let (i, transfer_syntax) = take(16_usize)(i)?;
let (i, syntax_version) = le_u32(i)?;
let (i, ack_result) = le_u16.parse(i)?;
let (i, ack_reason) = le_u16.parse(i)?;
let (i, transfer_syntax) = take(16_usize).parse(i)?;
let (i, syntax_version) = le_u32.parse(i)?;
let res = DceRpcBindAckResult {
ack_result,
ack_reason,
@ -171,16 +171,16 @@ pub struct DceRpcBindAckRecord<'a> {
}
pub fn parse_dcerpc_bindack_record(i: &[u8]) -> IResult<&[u8], DceRpcBindAckRecord<'_>> {
let (i, _max_xmit_frag) = le_u16(i)?;
let (i, _max_recv_frag) = le_u16(i)?;
let (i, _assoc_group) = take(4_usize)(i)?;
let (i, sec_addr_len) = le_u16(i)?;
let (i, _) = take(sec_addr_len)(i)?;
let (i, _max_xmit_frag) = le_u16.parse(i)?;
let (i, _max_recv_frag) = le_u16.parse(i)?;
let (i, _assoc_group) = take(4_usize).parse(i)?;
let (i, sec_addr_len) = le_u16.parse(i)?;
let (i, _) = take(sec_addr_len).parse(i)?;
let topad = sec_addr_len.wrapping_add(2) % 4;
let (i, _) = cond(topad != 0, take(4 - topad))(i)?;
let (i, num_results) = le_u8(i)?;
let (i, _) = take(3_usize)(i)?; // padding
let (i, results) = count(parse_dcerpc_bindack_result, num_results as usize)(i)?;
let (i, _) = cond(topad != 0, take(4 - topad)).parse(i)?;
let (i, num_results) = le_u8.parse(i)?;
let (i, _) = take(3_usize).parse(i)?; // padding
let (i, results) = count(parse_dcerpc_bindack_result, num_results as usize).parse(i)?;
let record = DceRpcBindAckRecord {
num_results,
results,
@ -207,32 +207,34 @@ pub struct DceRpcRecord<'a> {
}
fn parse_dcerpc_flags1(i:&[u8]) -> IResult<&[u8],(u8,u8,u8)> {
bits(tuple((
use nom8::error::Error;
bits::<_, _, Error<_>, _, _>((
take_bits(6u8),
take_bits(1u8), // last (1)
take_bits(1u8),
)))(i)
)).parse(i)
}
fn parse_dcerpc_flags2(i:&[u8]) -> IResult<&[u8],(u32,u32,u32)> {
bits(tuple((
use nom8::error::Error;
bits::<_, _, Error<_>, _, _>((
take_bits(3u32),
take_bits(1u32), // endianness
take_bits(28u32),
)))(i)
)).parse(i)
}
pub fn parse_dcerpc_record(i: &[u8]) -> IResult<&[u8], DceRpcRecord<'_>> {
let (i, version_major) = le_u8(i)?;
let (i, version_minor) = le_u8(i)?;
let (i, packet_type) = le_u8(i)?;
let (i, version_major) = le_u8.parse(i)?;
let (i, version_minor) = le_u8.parse(i)?;
let (i, packet_type) = le_u8.parse(i)?;
let (i, packet_flags) = parse_dcerpc_flags1(i)?;
let (i, data_rep) = parse_dcerpc_flags2(i)?;
let endian = if data_rep.1 == 0 { Endianness::Big } else { Endianness::Little };
let (i, frag_len) = u16(endian)(i)?;
let (i, _auth) = u16(endian)(i)?;
let (i, call_id) = u32(endian)(i)?;
let (i, data) = rest(i)?;
let (i, frag_len) = u16(endian).parse(i)?;
let (i, _auth) = u16(endian).parse(i)?;
let (i, call_id) = u32(endian).parse(i)?;
let (i, data) = rest.parse(i)?;
let record = DceRpcRecord {
version_major,
version_minor,

@ -16,7 +16,7 @@
*/
// Author: Pierre Chifflier <chifflier@wzdftpd.net>
use nom7::error::{ErrorKind, ParseError};
use nom8::error::{ErrorKind, ParseError};
#[derive(Debug)]
pub enum SmbError {

@ -15,10 +15,11 @@
* 02110-1301, USA.
*/
use nom7::bytes::streaming::take;
use nom7::combinator::rest;
use nom7::number::streaming::be_u32;
use nom7::IResult;
use nom8::bytes::streaming::take;
use nom8::combinator::rest;
use nom8::number::streaming::be_u32;
use nom8::Parser;
use nom8::IResult;
pub const NBSS_MSGTYPE_SESSION_MESSAGE: u8 = 0x00;
pub const NBSS_MSGTYPE_SESSION_REQUEST: u8 = 0x81;
@ -60,10 +61,10 @@ impl NbssRecord<'_> {
}
pub fn parse_nbss_record(i: &[u8]) -> IResult<&[u8], NbssRecord<'_>> {
let (i, buf) = be_u32(i)?;
let (i, buf) = be_u32.parse(i)?;
let message_type = (buf >> 24) as u8;
let length = buf & 0xff_ffff;
let (i, data) = take(length as usize)(i)?;
let (i, data) = take(length as usize).parse(i)?;
let record = NbssRecord {
message_type,
length,
@ -73,10 +74,10 @@ pub fn parse_nbss_record(i: &[u8]) -> IResult<&[u8], NbssRecord<'_>> {
}
pub fn parse_nbss_record_partial(i: &[u8]) -> IResult<&[u8], NbssRecord<'_>> {
let (i, buf) = be_u32(i)?;
let (i, buf) = be_u32.parse(i)?;
let message_type = (buf >> 24) as u8;
let length = buf & 0xff_ffff;
let (i, data) = rest(i)?;
let (i, data) = rest.parse(i)?;
let record = NbssRecord {
message_type,
length,
@ -89,7 +90,7 @@ pub fn parse_nbss_record_partial(i: &[u8]) -> IResult<&[u8], NbssRecord<'_>> {
mod tests {
use super::*;
use nom7::Err;
use nom8::Err;
#[test]
fn test_parse_nbss_record() {

@ -15,13 +15,14 @@
* 02110-1301, USA.
*/
use crate::common::nom7::take_until_and_consume;
use nom7::bytes::streaming::take;
use nom7::combinator::{cond, rest, verify};
use nom7::error::{make_error, ErrorKind};
use nom7::number::streaming::{le_u16, le_u32, le_u8};
use nom7::Err;
use nom7::IResult;
use crate::common::nom8::take_until_and_consume;
use nom8::bytes::streaming::take;
use nom8::combinator::{cond, rest, verify};
use nom8::error::{make_error, ErrorKind};
use nom8::number::streaming::{le_u16, le_u32, le_u8};
use nom8::Parser;
use nom8::Err;
use nom8::IResult;
use std::fmt;
#[derive(Debug, PartialEq, Eq)]
@ -43,11 +44,11 @@ impl fmt::Display for NTLMSSPVersion {
}
fn parse_ntlm_auth_version(i: &[u8]) -> IResult<&[u8], NTLMSSPVersion> {
let (i, ver_major) = le_u8(i)?;
let (i, ver_minor) = le_u8(i)?;
let (i, ver_build) = le_u16(i)?;
let (i, _) = take(3_usize)(i)?;
let (i, ver_ntlm_rev) = le_u8(i)?;
let (i, ver_major) = le_u8.parse(i)?;
let (i, ver_minor) = le_u8.parse(i)?;
let (i, ver_build) = le_u16.parse(i)?;
let (i, _) = take(3_usize).parse(i)?;
let (i, ver_ntlm_rev) = le_u8.parse(i)?;
let version = NTLMSSPVersion {
ver_major,
ver_minor,
@ -73,7 +74,7 @@ pub struct NTLMSSPNegotiateFlags {
}
fn parse_ntlm_auth_nego_flags(i: &[u8]) -> IResult<&[u8], NTLMSSPNegotiateFlags> {
let (i, raw) = le_u32(i)?;
let (i, raw) = le_u32.parse(i)?;
return Ok((
i,
NTLMSSPNegotiateFlags {
@ -101,34 +102,34 @@ pub fn parse_ntlm_auth_record(i: &[u8]) -> IResult<&[u8], NTLMSSPAuthRecord<'_>>
let record_len = i.len() + NTLMSSP_IDTYPE_LEN; // identifier (8) and type (4) are cut before we are called
// track start of the data offset
let (i, _lm_blob_len) = verify(le_u16, |&v| (v as usize) < record_len)(i)?;
let (i, _lm_blob_maxlen) = le_u16(i)?;
let (i, lm_blob_offset) = verify(le_u32, |&v| (v as usize) < record_len)(i)?;
let (i, _lm_blob_len) = verify(le_u16, |&v| (v as usize) < record_len).parse(i)?;
let (i, _lm_blob_maxlen) = le_u16.parse(i)?;
let (i, lm_blob_offset) = verify(le_u32, |&v| (v as usize) < record_len).parse(i)?;
let mut data_start = lm_blob_offset;
let (i, _ntlmresp_blob_len) = verify(le_u16, |&v| (v as usize) < record_len)(i)?;
let (i, _ntlmresp_blob_maxlen) = le_u16(i)?;
let (i, ntlmresp_blob_offset) = verify(le_u32, |&v| (v as usize) < record_len)(i)?;
let (i, _ntlmresp_blob_len) = verify(le_u16, |&v| (v as usize) < record_len).parse(i)?;
let (i, _ntlmresp_blob_maxlen) = le_u16.parse(i)?;
let (i, ntlmresp_blob_offset) = verify(le_u32, |&v| (v as usize) < record_len).parse(i)?;
data_start = std::cmp::min(data_start, ntlmresp_blob_offset);
let (i, domain_blob_len) = verify(le_u16, |&v| (v as usize) < record_len)(i)?;
let (i, _domain_blob_maxlen) = le_u16(i)?;
let (i, domain_blob_offset) = verify(le_u32, |&v| (v as usize) < record_len)(i)?;
let (i, domain_blob_len) = verify(le_u16, |&v| (v as usize) < record_len).parse(i)?;
let (i, _domain_blob_maxlen) = le_u16.parse(i)?;
let (i, domain_blob_offset) = verify(le_u32, |&v| (v as usize) < record_len).parse(i)?;
data_start = std::cmp::min(data_start, domain_blob_offset);
let (i, user_blob_len) = verify(le_u16, |&v| (v as usize) < record_len)(i)?;
let (i, _user_blob_maxlen) = le_u16(i)?;
let (i, user_blob_offset) = verify(le_u32, |&v| (v as usize) < record_len)(i)?;
let (i, user_blob_len) = verify(le_u16, |&v| (v as usize) < record_len).parse(i)?;
let (i, _user_blob_maxlen) = le_u16.parse(i)?;
let (i, user_blob_offset) = verify(le_u32, |&v| (v as usize) < record_len).parse(i)?;
data_start = std::cmp::min(data_start, user_blob_offset);
let (i, host_blob_len) = verify(le_u16, |&v| (v as usize) < record_len)(i)?;
let (i, _host_blob_maxlen) = le_u16(i)?;
let (i, host_blob_offset) = verify(le_u32, |&v| (v as usize) < record_len)(i)?;
let (i, host_blob_len) = verify(le_u16, |&v| (v as usize) < record_len).parse(i)?;
let (i, _host_blob_maxlen) = le_u16.parse(i)?;
let (i, host_blob_offset) = verify(le_u32, |&v| (v as usize) < record_len).parse(i)?;
data_start = std::cmp::min(data_start, host_blob_offset);
let (i, _ssnkey_blob_len) = verify(le_u16, |&v| (v as usize) < record_len)(i)?;
let (i, _ssnkey_blob_maxlen) = le_u16(i)?;
let (i, ssnkey_blob_offset) = verify(le_u32, |&v| (v as usize) < record_len)(i)?;
let (i, _ssnkey_blob_len) = verify(le_u16, |&v| (v as usize) < record_len).parse(i)?;
let (i, _ssnkey_blob_maxlen) = le_u16.parse(i)?;
let (i, ssnkey_blob_offset) = verify(le_u32, |&v| (v as usize) < record_len).parse(i)?;
data_start = std::cmp::min(data_start, ssnkey_blob_offset);
let (i, nego_flags) = parse_ntlm_auth_nego_flags(i)?;
@ -137,7 +138,7 @@ pub fn parse_ntlm_auth_record(i: &[u8]) -> IResult<&[u8], NTLMSSPAuthRecord<'_>>
let consumed = orig_i.len() - i.len() + NTLMSSP_IDTYPE_LEN;
let has_space_for_version = data_start as usize >= consumed + 8 && nego_flags.version;
let (_, version) = cond(has_space_for_version, parse_ntlm_auth_version)(i)?;
let (_, version) = cond(has_space_for_version, parse_ntlm_auth_version).parse(i)?;
// Caller does not care about remaining input...
let (_, domain_blob) = extract_ntlm_substring(orig_i, domain_blob_offset, domain_blob_len)?;
@ -170,9 +171,9 @@ pub struct NTLMSSPRecord<'a> {
}
pub fn parse_ntlmssp(i: &[u8]) -> IResult<&[u8], NTLMSSPRecord<'_>> {
let (i, _) = take_until_and_consume(b"NTLMSSP\x00")(i)?;
let (i, msg_type) = le_u32(i)?;
let (i, data) = rest(i)?;
let (i, _) = take_until_and_consume(b"NTLMSSP\x00").parse(i)?;
let (i, msg_type) = le_u32.parse(i)?;
let (i, data) = rest.parse(i)?;
let record = NTLMSSPRecord { msg_type, data };
Ok((i, record))
}
@ -180,7 +181,7 @@ pub fn parse_ntlmssp(i: &[u8]) -> IResult<&[u8], NTLMSSPRecord<'_>> {
#[cfg(test)]
mod tests {
use super::*;
use nom7::Err;
use nom8::Err;
#[test]
fn test_parse_auth_nego_flags() {
// ntlmssp.negotiateflags 1

@ -30,8 +30,8 @@ use std::str;
use std::ffi::{self, CString};
use std::collections::VecDeque;
use nom7::{Err, Needed};
use nom7::error::{make_error, ErrorKind};
use nom8::{Err, Needed};
use nom8::error::{make_error, ErrorKind};
use lru::LruCache;
use suricata_sys::sys::{

@ -30,7 +30,7 @@ use crate::smb::smb1_session::*;
use crate::smb::smb_status::*;
use nom7::Err;
use nom8::Err;
// https://msdn.microsoft.com/en-us/library/ee441741.aspx
pub const SMB1_COMMAND_CREATE_DIRECTORY: u8 = 0x00;

@ -15,17 +15,18 @@
* 02110-1301, USA.
*/
use crate::common::nom7::take_until_and_consume;
use crate::common::nom8::take_until_and_consume;
use crate::smb::error::SmbError;
use crate::smb::smb::*;
use crate::smb::smb_records::*;
use nom7::bytes::streaming::{tag, take};
use nom7::combinator::{complete, cond, peek, rest, verify};
use nom7::error::{make_error, ErrorKind};
use nom7::Err;
use nom7::multi::many1;
use nom7::number::streaming::{le_u8, le_u16, le_u32, le_u64};
use nom7::IResult;
use nom8::bytes::streaming::{tag, take};
use nom8::combinator::{complete, cond, peek, rest, verify};
use nom8::error::{make_error, ErrorKind};
use nom8::Err;
use nom8::multi::many1;
use nom8::number::streaming::{le_u8, le_u16, le_u32, le_u64};
use nom8::IResult;
use nom8::Parser;
pub const SMB1_HEADER_SIZE: usize = 32;
@ -34,7 +35,7 @@ const SMB1_FLAGS_RESPONSE: u8 = 0x80;
fn smb_get_unicode_string_with_offset(i: &[u8], offset: usize) -> IResult<&[u8], Vec<u8>, SmbError>
{
let (i, _) = cond(offset % 2 == 1, take(1_usize))(i)?;
let (i, _) = cond(offset % 2 == 1, take(1_usize)).parse(i)?;
smb_get_unicode_string(i)
}
@ -56,10 +57,10 @@ pub struct SmbParamBlockAndXHeader {
}
pub fn smb1_parse_andx_header(i: &[u8]) -> IResult<&[u8], SmbParamBlockAndXHeader> {
let (i, wct) = le_u8(i)?;
let (i, andx_command) = le_u8(i)?;
let (i, _) = take(1_usize)(i)?; // reserved
let (i, andx_offset) = le_u16(i)?;
let (i, wct) = le_u8.parse(i)?;
let (i, andx_command) = le_u8.parse(i)?;
let (i, _) = take(1_usize).parse(i)?; // reserved
let (i, andx_offset) = le_u16.parse(i)?;
let hdr = SmbParamBlockAndXHeader {
wct,
andx_command,
@ -77,15 +78,15 @@ pub struct Smb1WriteRequestRecord<'a> {
}
pub fn parse_smb1_write_request_record(i: &[u8]) -> IResult<&[u8], Smb1WriteRequestRecord<'_>> {
let (i, _wct) = le_u8(i)?;
let (i, fid) = take(2_usize)(i)?;
let (i, _count) = le_u16(i)?;
let (i, offset) = le_u32(i)?;
let (i, _remaining) = le_u16(i)?;
let (i, _bcc) = le_u16(i)?;
let (i, _buffer_format) = le_u8(i)?;
let (i, data_len) = le_u16(i)?;
let (i, file_data) = take(data_len)(i)?;
let (i, _wct) = le_u8.parse(i)?;
let (i, fid) = take(2_usize).parse(i)?;
let (i, _count) = le_u16.parse(i)?;
let (i, offset) = le_u32.parse(i)?;
let (i, _remaining) = le_u16.parse(i)?;
let (i, _bcc) = le_u16.parse(i)?;
let (i, _buffer_format) = le_u8.parse(i)?;
let (i, data_len) = le_u16.parse(i)?;
let (i, file_data) = take(data_len).parse(i)?;
let record = Smb1WriteRequestRecord {
offset: offset as u64,
len: data_len as u32,
@ -98,25 +99,25 @@ pub fn parse_smb1_write_request_record(i: &[u8]) -> IResult<&[u8], Smb1WriteRequ
pub fn parse_smb1_write_andx_request_record(i : &[u8], andx_offset: usize) -> IResult<&[u8], Smb1WriteRequestRecord<'_>> {
let origin_i = i;
let ax = andx_offset as u16;
let (i, wct) = le_u8(i)?;
let (i, _andx_command) = le_u8(i)?;
let (i, _) = take(1_usize)(i)?; // reserved
let (i, _andx_offset) = le_u16(i)?;
let (i, fid) = take(2_usize)(i)?;
let (i, offset) = le_u32(i)?;
let (i, _) = take(4_usize)(i)?; // reserved
let (i, _write_mode) = le_u16(i)?;
let (i, _remaining) = le_u16(i)?;
let (i, data_len_high) = le_u16(i)?;
let (i, data_len_low) = le_u16(i)?;
let (i, wct) = le_u8.parse(i)?;
let (i, _andx_command) = le_u8.parse(i)?;
let (i, _) = take(1_usize).parse(i)?; // reserved
let (i, _andx_offset) = le_u16.parse(i)?;
let (i, fid) = take(2_usize).parse(i)?;
let (i, offset) = le_u32.parse(i)?;
let (i, _) = take(4_usize).parse(i)?; // reserved
let (i, _write_mode) = le_u16.parse(i)?;
let (i, _remaining) = le_u16.parse(i)?;
let (i, data_len_high) = le_u16.parse(i)?;
let (i, data_len_low) = le_u16.parse(i)?;
let data_len = ((data_len_high as u32) << 16)|(data_len_low as u32);
let (i, data_offset) = le_u16(i)?;
let (i, data_offset) = le_u16.parse(i)?;
if data_offset < 0x3c || data_offset < ax{
return Err(Err::Error(make_error(i, ErrorKind::LengthValue)));
}
let (i, high_offset) = cond(wct == 14, le_u32)(i)?;
let (_i, _bcc) = le_u16(i)?;
let (i, _padding_data) = take(data_offset-ax)(origin_i)?;
let (i, high_offset) = cond(wct == 14, le_u32).parse(i)?;
let (_i, _bcc) = le_u16.parse(i)?;
let (i, _padding_data) = take(data_offset-ax).parse(origin_i)?;
let (i, file_data) = take(std::cmp::min(data_len, i.len() as u32))(i)?;
let record = Smb1WriteRequestRecord {
@ -129,14 +130,14 @@ pub fn parse_smb1_write_andx_request_record(i : &[u8], andx_offset: usize) -> IR
}
pub fn parse_smb1_write_and_close_request_record(i: &[u8]) -> IResult<&[u8], Smb1WriteRequestRecord<'_>> {
let (i, _wct) = le_u8(i)?;
let (i, fid) = take(2_usize)(i)?;
let (i, count) = le_u16(i)?;
let (i, offset) = le_u32(i)?;
let (i, _last_write) = take(4_usize)(i)?;
let (i, bcc) = le_u16(i)?;
let (i, _padding) = cond(bcc > count, |b| take(bcc - count)(b))(i)?;
let (i, file_data) = take(count)(i)?;
let (i, _wct) = le_u8.parse(i)?;
let (i, fid) = take(2_usize).parse(i)?;
let (i, count) = le_u16.parse(i)?;
let (i, offset) = le_u32.parse(i)?;
let (i, _last_write) = take(4_usize).parse(i)?;
let (i, bcc) = le_u16.parse(i)?;
let (i, _padding) = cond(bcc > count, |b| take(bcc - count)(b)).parse(i)?;
let (i, file_data) = take(count).parse(i)?;
let record = Smb1WriteRequestRecord {
offset: offset as u64,
len: count as u32,
@ -154,8 +155,8 @@ pub struct Smb1NegotiateProtocolResponseRecord<'a> {
pub fn parse_smb1_negotiate_protocol_response_record_error(i: &[u8])
-> IResult<&[u8], Smb1NegotiateProtocolResponseRecord<'_>> {
let (i, _wct) = le_u8(i)?;
let (i, _bcc) = le_u16(i)?;
let (i, _wct) = le_u8.parse(i)?;
let (i, _bcc) = le_u16.parse(i)?;
let record = Smb1NegotiateProtocolResponseRecord {
dialect_idx: 0,
server_guid: &[],
@ -165,16 +166,16 @@ pub fn parse_smb1_negotiate_protocol_response_record_error(i: &[u8])
pub fn parse_smb1_negotiate_protocol_response_record_ok(i: &[u8])
-> IResult<&[u8], Smb1NegotiateProtocolResponseRecord<'_>> {
let (i, _wct) = le_u8(i)?;
let (i, dialect_idx) = le_u16(i)?;
let (i, _sec_mode) = le_u8(i)?;
let (i, _) = take(16_usize)(i)?;
let (i, _caps) = le_u32(i)?;
let (i, _sys_time) = le_u64(i)?;
let (i, _server_tz) = le_u16(i)?;
let (i, _challenge_len) = le_u8(i)?;
let (i, bcc) = le_u16(i)?;
let (i, server_guid) = cond(bcc >= 16, take(16_usize))(i)?;
let (i, _wct) = le_u8.parse(i)?;
let (i, dialect_idx) = le_u16.parse(i)?;
let (i, _sec_mode) = le_u8.parse(i)?;
let (i, _) = take(16_usize).parse(i)?;
let (i, _caps) = le_u32.parse(i)?;
let (i, _sys_time) = le_u64.parse(i)?;
let (i, _server_tz) = le_u16.parse(i)?;
let (i, _challenge_len) = le_u8.parse(i)?;
let (i, bcc) = le_u16.parse(i)?;
let (i, server_guid) = cond(bcc >= 16, take(16_usize)).parse(i)?;
let record = Smb1NegotiateProtocolResponseRecord {
dialect_idx,
server_guid: server_guid.unwrap_or(&[]),
@ -184,7 +185,7 @@ pub fn parse_smb1_negotiate_protocol_response_record_ok(i: &[u8])
pub fn parse_smb1_negotiate_protocol_response_record(i: &[u8])
-> IResult<&[u8], Smb1NegotiateProtocolResponseRecord<'_>> {
let (i, wct) = peek(le_u8)(i)?;
let (i, wct) = peek(le_u8).parse(i)?;
match wct {
0 => parse_smb1_negotiate_protocol_response_record_error(i),
_ => parse_smb1_negotiate_protocol_response_record_ok(i),
@ -198,10 +199,10 @@ pub struct Smb1NegotiateProtocolRecord<'a> {
pub fn parse_smb1_negotiate_protocol_record(i: &[u8])
-> IResult<&[u8], Smb1NegotiateProtocolRecord<'_>> {
let (i, _wtc) = le_u8(i)?;
let (i, _bcc) = le_u16(i)?;
let (i, _wtc) = le_u8.parse(i)?;
let (i, _bcc) = le_u16.parse(i)?;
// dialects is a list of [1 byte buffer format][string][0 terminator]
let (i, dialects) = many1(complete(take_until_and_consume(b"\0")))(i)?;
let (i, dialects) = many1(complete(take_until_and_consume(b"\0"))).parse(i)?;
let record = Smb1NegotiateProtocolRecord { dialects };
Ok((i, record))
}
@ -215,15 +216,15 @@ pub struct Smb1ResponseRecordTreeConnectAndX<'a> {
pub fn parse_smb_connect_tree_andx_response_record(i: &[u8])
-> IResult<&[u8], Smb1ResponseRecordTreeConnectAndX<'_>> {
let (i, wct) = le_u8(i)?;
let (i, _andx_command) = le_u8(i)?;
let (i, _) = take(1_usize)(i)?; // reserved
let (i, _andx_offset) = le_u16(i)?;
let (i, _) = cond(wct >= 3, take(2_usize))(i)?; // optional support
let (i, _) = cond(wct == 7, take(8_usize))(i)?; // access masks
let (i, _bcc) = le_u16(i)?;
let (i, service) = take_until_and_consume(b"\x00")(i)?;
let (i, nativefs) = take_until_and_consume(b"\x00")(i)?;
let (i, wct) = le_u8.parse(i)?;
let (i, _andx_command) = le_u8.parse(i)?;
let (i, _) = take(1_usize).parse(i)?; // reserved
let (i, _andx_offset) = le_u16.parse(i)?;
let (i, _) = cond(wct >= 3, take(2_usize)).parse(i)?; // optional support
let (i, _) = cond(wct == 7, take(8_usize)).parse(i)?; // access masks
let (i, _bcc) = le_u16.parse(i)?;
let (i, service) = take_until_and_consume(b"\x00").parse(i)?;
let (i, nativefs) = take_until_and_consume(b"\x00").parse(i)?;
let record = Smb1ResponseRecordTreeConnectAndX {
service,
nativefs
@ -239,12 +240,12 @@ pub struct SmbRecordTreeConnectAndX<'a> {
pub fn parse_smb_connect_tree_andx_record<'a>(i: &'a[u8], r: &SmbRecord)
-> IResult<&'a[u8], SmbRecordTreeConnectAndX<'a>, SmbError> {
let (i, _skip1) = take(7_usize)(i)?;
let (i, pwlen) = le_u16(i)?;
let (i, _bcc) = le_u16(i)?;
let (i, _pw) = take(pwlen)(i)?;
let (i, _skip1) = take(7_usize).parse(i)?;
let (i, pwlen) = le_u16.parse(i)?;
let (i, _bcc) = le_u16.parse(i)?;
let (i, _pw) = take(pwlen).parse(i)?;
let (i, path) = smb1_get_string(i, r, 11 + pwlen as usize)?;
let (i, service) = take_until_and_consume(b"\x00")(i)?;
let (i, service) = take_until_and_consume(b"\x00").parse(i)?;
let record = SmbRecordTreeConnectAndX {
path,
service
@ -268,8 +269,8 @@ pub struct SmbPipeProtocolRecord<'a> {
pub fn parse_smb_trans_request_record_pipe(i: &[u8])
-> IResult<&[u8], SmbPipeProtocolRecord<'_>, SmbError> {
let (i, fun) = le_u16(i)?;
let (i, fid) = take(2_usize)(i)?;
let (i, fun) = le_u16.parse(i)?;
let (i, fid) = take(2_usize).parse(i)?;
let record = SmbPipeProtocolRecord {
function: fun,
fid
@ -291,24 +292,24 @@ pub struct SmbRecordTransRequestParams<> {
pub fn parse_smb_trans_request_record_params(i: &[u8])
-> IResult<&[u8], (SmbRecordTransRequestParams, Option<SmbPipeProtocolRecord<'_>>), SmbError>
{
let (i, wct) = le_u8(i)?;
let (i, _total_param_cnt) = le_u16(i)?;
let (i, _total_data_count) = le_u16(i)?;
let (i, _max_param_cnt) = le_u16(i)?;
let (i, max_data_cnt) = le_u16(i)?;
let (i, _max_setup_cnt) = le_u8(i)?;
let (i, _) = take(1_usize)(i)?; // reserved
let (i, _) = take(2_usize)(i)?; // flags
let (i, _timeout) = le_u32(i)?;
let (i, _) = take(2_usize)(i)?; // reserved
let (i, param_cnt) = le_u16(i)?;
let (i, param_offset) = le_u16(i)?;
let (i, data_cnt) = le_u16(i)?;
let (i, data_offset) = le_u16(i)?;
let (i, setup_cnt) = le_u8(i)?;
let (i, _) = take(1_usize)(i)?; // reserved
let (i, pipe) = cond(wct == 16 && setup_cnt == 2 && data_cnt > 0, parse_smb_trans_request_record_pipe)(i)?;
let (i, bcc) = le_u16(i)?;
let (i, wct) = le_u8.parse(i)?;
let (i, _total_param_cnt) = le_u16.parse(i)?;
let (i, _total_data_count) = le_u16.parse(i)?;
let (i, _max_param_cnt) = le_u16.parse(i)?;
let (i, max_data_cnt) = le_u16.parse(i)?;
let (i, _max_setup_cnt) = le_u8.parse(i)?;
let (i, _) = take(1_usize).parse(i)?; // reserved
let (i, _) = take(2_usize).parse(i)?; // flags
let (i, _timeout) = le_u32.parse(i)?;
let (i, _) = take(2_usize).parse(i)?; // reserved
let (i, param_cnt) = le_u16.parse(i)?;
let (i, param_offset) = le_u16.parse(i)?;
let (i, data_cnt) = le_u16.parse(i)?;
let (i, data_offset) = le_u16.parse(i)?;
let (i, setup_cnt) = le_u8.parse(i)?;
let (i, _) = take(1_usize).parse(i)?; // reserved
let (i, pipe) = cond(wct == 16 && setup_cnt == 2 && data_cnt > 0, parse_smb_trans_request_record_pipe).parse(i)?;
let (i, bcc) = le_u16.parse(i)?;
let params = SmbRecordTransRequestParams {
max_data_cnt,
param_cnt,
@ -329,10 +330,10 @@ pub fn parse_smb_trans_request_record_data(i: &[u8],
pad1: usize, param_cnt: u16, pad2: usize, data_len: u16)
-> IResult<&[u8], SmbRecordTransRequestData<'_>, SmbError>
{
let (i, _) = take(pad1)(i)?;
let (i, _) = take(param_cnt)(i)?;
let (i, _) = take(pad2)(i)?;
let (i, data) = take(data_len)(i)?;
let (i, _) = take(pad1).parse(i)?;
let (i, _) = take(param_cnt).parse(i)?;
let (i, _) = take(pad2).parse(i)?;
let (i, data) = take(data_len).parse(i)?;
let req = SmbRecordTransRequestData { data };
Ok((i, req))
}
@ -396,8 +397,8 @@ pub struct SmbRecordTransResponse<'a> {
}
pub fn parse_smb_trans_response_error_record(i: &[u8]) -> IResult<&[u8], SmbRecordTransResponse<'_>> {
let (i, _wct) = le_u8(i)?;
let (i, bcc) = le_u16(i)?;
let (i, _wct) = le_u8.parse(i)?;
let (i, bcc) = le_u16.parse(i)?;
let resp = SmbRecordTransResponse {
data_cnt: 0,
bcc,
@ -407,25 +408,25 @@ pub fn parse_smb_trans_response_error_record(i: &[u8]) -> IResult<&[u8], SmbReco
}
pub fn parse_smb_trans_response_regular_record(i: &[u8]) -> IResult<&[u8], SmbRecordTransResponse<'_>> {
let (i, wct) = le_u8(i)?;
let (i, _total_param_cnt) = le_u16(i)?;
let (i, _total_data_count) = le_u16(i)?;
let (i, _) = take(2_usize)(i)?; // reserved
let (i, _param_cnt) = le_u16(i)?;
let (i, _param_offset) = le_u16(i)?;
let (i, _param_displacement) = le_u16(i)?;
let (i, data_cnt) = le_u16(i)?;
let (i, data_offset) = le_u16(i)?;
let (i, _data_displacement) = le_u16(i)?;
let (i, _setup_cnt) = le_u8(i)?;
let (i, _) = take(1_usize)(i)?; // reserved
let (i, bcc) = le_u16(i)?;
let (i, _) = take(1_usize)(i)?; // padding
let (i, wct) = le_u8.parse(i)?;
let (i, _total_param_cnt) = le_u16.parse(i)?;
let (i, _total_data_count) = le_u16.parse(i)?;
let (i, _) = take(2_usize).parse(i)?; // reserved
let (i, _param_cnt) = le_u16.parse(i)?;
let (i, _param_offset) = le_u16.parse(i)?;
let (i, _param_displacement) = le_u16.parse(i)?;
let (i, data_cnt) = le_u16.parse(i)?;
let (i, data_offset) = le_u16.parse(i)?;
let (i, _data_displacement) = le_u16.parse(i)?;
let (i, _setup_cnt) = le_u8.parse(i)?;
let (i, _) = take(1_usize).parse(i)?; // reserved
let (i, bcc) = le_u16.parse(i)?;
let (i, _) = take(1_usize).parse(i)?; // padding
let (i, _padding_evasion) = cond(
data_offset > 36+2*(wct as u16),
|b| take(data_offset - (36+2*(wct as u16)))(b)
)(i)?;
let (i, data) = take(data_cnt)(i)?;
).parse(i)?;
let (i, data) = take(data_cnt).parse(i)?;
let resp = SmbRecordTransResponse {
data_cnt,
bcc,
@ -435,7 +436,7 @@ pub fn parse_smb_trans_response_regular_record(i: &[u8]) -> IResult<&[u8], SmbRe
}
pub fn parse_smb_trans_response_record(i: &[u8]) -> IResult<&[u8], SmbRecordTransResponse<'_>> {
let (i, wct) = peek(le_u8)(i)?;
let (i, wct) = peek(le_u8).parse(i)?;
match wct {
0 => parse_smb_trans_response_error_record(i),
_ => parse_smb_trans_response_regular_record(i),
@ -448,11 +449,11 @@ pub struct SmbRecordSetupAndX<'a> {
}
pub fn parse_smb_setup_andx_record(i: &[u8]) -> IResult<&[u8], SmbRecordSetupAndX<'_>> {
let (i, _skip1) = take(15_usize)(i)?;
let (i, sec_blob_len) = le_u16(i)?;
let (i, _skip2) = take(8_usize)(i)?;
let (i, _bcc) = le_u16(i)?;
let (i, sec_blob) = take(sec_blob_len)(i)?;
let (i, _skip1) = take(15_usize).parse(i)?;
let (i, sec_blob_len) = le_u16.parse(i)?;
let (i, _skip2) = take(8_usize).parse(i)?;
let (i, _bcc) = le_u16.parse(i)?;
let (i, sec_blob) = take(sec_blob_len).parse(i)?;
let record = SmbRecordSetupAndX { sec_blob };
Ok((i, record))
}
@ -463,17 +464,17 @@ pub struct SmbResponseRecordSetupAndX<'a> {
}
fn response_setup_andx_record(i: &[u8]) -> IResult<&[u8], SmbResponseRecordSetupAndX<'_>> {
let (i, _skip1) = take(7_usize)(i)?;
let (i, sec_blob_len) = le_u16(i)?;
let (i, _bcc) = le_u16(i)?;
let (i, sec_blob) = take(sec_blob_len)(i)?;
let (i, _skip1) = take(7_usize).parse(i)?;
let (i, sec_blob_len) = le_u16.parse(i)?;
let (i, _bcc) = le_u16.parse(i)?;
let (i, sec_blob) = take(sec_blob_len).parse(i)?;
let record = SmbResponseRecordSetupAndX { sec_blob };
Ok((i, record))
}
fn response_setup_andx_wct3_record(i: &[u8]) -> IResult<&[u8], SmbResponseRecordSetupAndX<'_>> {
let (i, _skip1) = take(7_usize)(i)?;
let (i, _bcc) = le_u16(i)?;
let (i, _skip1) = take(7_usize).parse(i)?;
let (i, _bcc) = le_u16.parse(i)?;
let record = SmbResponseRecordSetupAndX {
sec_blob: &[],
};
@ -481,8 +482,8 @@ fn response_setup_andx_wct3_record(i: &[u8]) -> IResult<&[u8], SmbResponseRecord
}
fn response_setup_andx_error_record(i: &[u8]) -> IResult<&[u8], SmbResponseRecordSetupAndX<'_>> {
let (i, _wct) = le_u8(i)?;
let (i, _bcc) = le_u16(i)?;
let (i, _wct) = le_u8.parse(i)?;
let (i, _bcc) = le_u16.parse(i)?;
let record = SmbResponseRecordSetupAndX {
sec_blob: &[],
};
@ -490,7 +491,7 @@ fn response_setup_andx_error_record(i: &[u8]) -> IResult<&[u8], SmbResponseRecor
}
pub fn parse_smb_response_setup_andx_record(i: &[u8]) -> IResult<&[u8], SmbResponseRecordSetupAndX<'_>> {
let (i, wct) = peek(le_u8)(i)?;
let (i, wct) = peek(le_u8).parse(i)?;
match wct {
0 => response_setup_andx_error_record(i),
3 => response_setup_andx_wct3_record(i),
@ -506,17 +507,17 @@ pub struct SmbRequestReadAndXRecord<'a> {
}
pub fn parse_smb_read_andx_request_record(i: &[u8]) -> IResult<&[u8], SmbRequestReadAndXRecord<'_>> {
let (i, wct) = le_u8(i)?;
let (i, _andx_command) = le_u8(i)?;
let (i, _) = take(1_usize)(i)?; // reserved
let (i, _andx_offset) = le_u16(i)?;
let (i, fid) = take(2_usize)(i)?;
let (i, offset) = le_u32(i)?;
let (i, max_count_low) = le_u16(i)?;
let (i, _) = take(2_usize)(i)?;
let (i, max_count_high) = le_u32(i)?;
let (i, _) = take(2_usize)(i)?;
let (i, high_offset) = cond(wct == 12,le_u32)(i)?; // only from wct ==12?
let (i, wct) = le_u8.parse(i)?;
let (i, _andx_command) = le_u8.parse(i)?;
let (i, _) = take(1_usize).parse(i)?; // reserved
let (i, _andx_offset) = le_u16.parse(i)?;
let (i, fid) = take(2_usize).parse(i)?;
let (i, offset) = le_u32.parse(i)?;
let (i, max_count_low) = le_u16.parse(i)?;
let (i, _) = take(2_usize).parse(i)?;
let (i, max_count_high) = le_u32.parse(i)?;
let (i, _) = take(2_usize).parse(i)?;
let (i, high_offset) = cond(wct == 12, le_u32).parse(i)?; // only from wct ==12?
let record = SmbRequestReadAndXRecord {
fid,
size: (((max_count_high as u64) << 16)|max_count_low as u64),
@ -532,25 +533,25 @@ pub struct SmbResponseReadAndXRecord<'a> {
}
pub fn parse_smb_read_andx_response_record(i: &[u8]) -> IResult<&[u8], SmbResponseReadAndXRecord<'_>> {
let (i, wct) = le_u8(i)?;
let (i, _andx_command) = le_u8(i)?;
let (i, _) = take(1_usize)(i)?; // reserved
let (i, _andx_offset) = le_u16(i)?;
let (i, _) = take(6_usize)(i)?;
let (i, data_len_low) = le_u16(i)?;
let (i, data_offset) = le_u16(i)?;
let (i, data_len_high) = le_u32(i)?;
let (i, _) = take(6_usize)(i)?; // reserved
let (i, bcc) = le_u16(i)?;
let (i, wct) = le_u8.parse(i)?;
let (i, _andx_command) = le_u8.parse(i)?;
let (i, _) = take(1_usize).parse(i)?; // reserved
let (i, _andx_offset) = le_u16.parse(i)?;
let (i, _) = take(6_usize).parse(i)?;
let (i, data_len_low) = le_u16.parse(i)?;
let (i, data_offset) = le_u16.parse(i)?;
let (i, data_len_high) = le_u32.parse(i)?;
let (i, _) = take(6_usize).parse(i)?; // reserved
let (i, bcc) = le_u16.parse(i)?;
let (i, _padding) = cond(
bcc > data_len_low,
|b| take(bcc - data_len_low)(b)
)(i)?; // TODO figure out how this works with data_len_high
).parse(i)?; // TODO figure out how this works with data_len_high
let (i, _padding_evasion) = cond(
data_offset > 36+2*(wct as u16),
|b| take(data_offset - (36+2*(wct as u16)))(b)
)(i)?;
let (i, file_data) = rest(i)?;
).parse(i)?;
let (i, file_data) = rest.parse(i)?;
let record = SmbResponseReadAndXRecord {
len: ((data_len_high << 16)|data_len_low as u32),
@ -566,12 +567,12 @@ pub struct SmbRequestRenameRecord {
}
pub fn parse_smb_rename_request_record(i: &[u8]) -> IResult<&[u8], SmbRequestRenameRecord, SmbError> {
let (i, _wct) = le_u8(i)?;
let (i, _search_attr) = le_u16(i)?;
let (i, _bcc) = le_u16(i)?;
let (i, _oldtype) = le_u8(i)?;
let (i, _wct) = le_u8.parse(i)?;
let (i, _search_attr) = le_u16.parse(i)?;
let (i, _bcc) = le_u16.parse(i)?;
let (i, _oldtype) = le_u8.parse(i)?;
let (i, oldname) = smb_get_unicode_string(i)?;
let (i, _newtype) = le_u8(i)?;
let (i, _newtype) = le_u8.parse(i)?;
let (i, newname) = smb_get_unicode_string_with_offset(i, 1)?; // HACK if we assume oldname is a series of utf16 chars offset would be 1
let record = SmbRequestRenameRecord {
oldname,
@ -590,18 +591,18 @@ pub struct SmbRequestCreateAndXRecord<> {
pub fn parse_smb_create_andx_request_record<'a>(i: &'a[u8], r: &SmbRecord)
-> IResult<&'a[u8], SmbRequestCreateAndXRecord<>, SmbError>
{
let (i, _skip1) = take(6_usize)(i)?;
let (i, file_name_len) = le_u16(i)?;
let (i, _skip3) = take(28_usize)(i)?;
let (i, disposition) = le_u32(i)?;
let (i, create_options) = le_u32(i)?;
let (i, _skip2) = take(5_usize)(i)?;
let (i, bcc) = le_u16(i)?;
let (i, _skip1) = take(6_usize).parse(i)?;
let (i, file_name_len) = le_u16.parse(i)?;
let (i, _skip3) = take(28_usize).parse(i)?;
let (i, disposition) = le_u32.parse(i)?;
let (i, create_options) = le_u32.parse(i)?;
let (i, _skip2) = take(5_usize).parse(i)?;
let (i, bcc) = le_u16.parse(i)?;
let (i, file_name) = cond(
bcc >= file_name_len,
|b| smb1_get_string(b, r, (bcc - file_name_len) as usize)
)(i)?;
let (i, _skip3) = rest(i)?;
).parse(i)?;
let (i, _skip3) = rest.parse(i)?;
let record = SmbRequestCreateAndXRecord {
disposition,
create_options,
@ -617,7 +618,7 @@ pub struct Trans2RecordParamSetFileInfoDisposition<> {
pub fn parse_trans2_request_data_set_file_info_disposition(i: &[u8])
-> IResult<&[u8], Trans2RecordParamSetFileInfoDisposition> {
let (i, delete) = le_u8(i)?;
let (i, delete) = le_u8.parse(i)?;
let record = Trans2RecordParamSetFileInfoDisposition {
delete: delete & 1 == 1,
};
@ -631,8 +632,8 @@ pub struct Trans2RecordParamSetFileInfo<'a> {
}
pub fn parse_trans2_request_params_set_file_info(i: &[u8]) -> IResult<&[u8], Trans2RecordParamSetFileInfo<'_>> {
let (i, fid) = take(2_usize)(i)?;
let (i, loi) = le_u16(i)?;
let (i, fid) = take(2_usize).parse(i)?;
let (i, loi) = le_u16.parse(i)?;
let record = Trans2RecordParamSetFileInfo { fid, loi };
Ok((i, record))
}
@ -644,11 +645,11 @@ pub struct Trans2RecordParamSetFileInfoRename<'a> {
}
pub fn parse_trans2_request_data_set_file_info_rename(i: &[u8]) -> IResult<&[u8], Trans2RecordParamSetFileInfoRename<'_>> {
let (i, replace) = le_u8(i)?;
let (i, _reserved) = take(3_usize)(i)?;
let (i, _root_dir) = take(4_usize)(i)?;
let (i, newname_len) = le_u32(i)?;
let (i, newname) = take(newname_len)(i)?;
let (i, replace) = le_u8.parse(i)?;
let (i, _reserved) = take(3_usize).parse(i)?;
let (i, _root_dir) = take(4_usize).parse(i)?;
let (i, newname_len) = le_u32.parse(i)?;
let (i, newname) = take(newname_len).parse(i)?;
let record = Trans2RecordParamSetFileInfoRename {
replace: replace==1,
newname,
@ -663,8 +664,8 @@ pub struct Trans2RecordParamSetPathInfo<> {
}
pub fn parse_trans2_request_params_set_path_info(i: &[u8]) -> IResult<&[u8], Trans2RecordParamSetPathInfo, SmbError> {
let (i, loi) = le_u16(i)?;
let (i, _reserved) = take(4_usize)(i)?;
let (i, loi) = le_u16.parse(i)?;
let (i, _reserved) = take(4_usize).parse(i)?;
let (i, oldname) = smb_get_unicode_string(i)?;
let record = Trans2RecordParamSetPathInfo { loi, oldname };
Ok((i, record))
@ -677,11 +678,11 @@ pub struct Trans2RecordParamSetPathInfoRename<'a> {
}
pub fn parse_trans2_request_data_set_path_info_rename(i: &[u8]) -> IResult<&[u8], Trans2RecordParamSetPathInfoRename<'_>> {
let (i, replace) = le_u8(i)?;
let (i, _reserved) = take(3_usize)(i)?;
let (i, _root_dir) = take(4_usize)(i)?;
let (i, newname_len) = le_u32(i)?;
let (i, newname) = take(newname_len)(i)?;
let (i, replace) = le_u8.parse(i)?;
let (i, _reserved) = take(3_usize).parse(i)?;
let (i, _root_dir) = take(4_usize).parse(i)?;
let (i, newname_len) = le_u32.parse(i)?;
let (i, newname) = take(newname_len).parse(i)?;
let record = Trans2RecordParamSetPathInfoRename {
replace: replace==1,
newname
@ -697,32 +698,32 @@ pub struct SmbRequestTrans2Record<'a> {
}
pub fn parse_smb_trans2_request_record(i: &[u8]) -> IResult<&[u8], SmbRequestTrans2Record<'_>> {
let (i, _wct) = le_u8(i)?;
let (i, _total_param_cnt) = le_u16(i)?;
let (i, _total_data_cnt) = le_u16(i)?;
let (i, _max_param_cnt) = le_u16(i)?;
let (i, _max_data_cnt) = le_u16(i)?;
let (i, _max_setup_cnt) = le_u8(i)?;
let (i, _reserved1) = take(1_usize)(i)?;
let (i, _flags) = le_u16(i)?;
let (i, _timeout) = le_u32(i)?;
let (i, _reserved2) = take(2_usize)(i)?;
let (i, param_cnt) = le_u16(i)?;
let (i, param_offset) = verify(le_u16, |&v| v <= (u16::MAX - param_cnt))(i)?;
let (i, data_cnt) = le_u16(i)?;
let (i, data_offset) = le_u16(i)?;
let (i, _setup_cnt) = le_u8(i)?;
let (i, _reserved3) = take(1_usize)(i)?;
let (i, subcmd) = le_u16(i)?;
let (i, _bcc) = le_u16(i)?;
let (i, _wct) = le_u8.parse(i)?;
let (i, _total_param_cnt) = le_u16.parse(i)?;
let (i, _total_data_cnt) = le_u16.parse(i)?;
let (i, _max_param_cnt) = le_u16.parse(i)?;
let (i, _max_data_cnt) = le_u16.parse(i)?;
let (i, _max_setup_cnt) = le_u8.parse(i)?;
let (i, _reserved1) = take(1_usize).parse(i)?;
let (i, _flags) = le_u16.parse(i)?;
let (i, _timeout) = le_u32.parse(i)?;
let (i, _reserved2) = take(2_usize).parse(i)?;
let (i, param_cnt) = le_u16.parse(i)?;
let (i, param_offset) = verify(le_u16, |&v| v <= (u16::MAX - param_cnt)).parse(i)?;
let (i, data_cnt) = le_u16.parse(i)?;
let (i, data_offset) = le_u16.parse(i)?;
let (i, _setup_cnt) = le_u8.parse(i)?;
let (i, _reserved3) = take(1_usize).parse(i)?;
let (i, subcmd) = le_u16.parse(i)?;
let (i, _bcc) = le_u16.parse(i)?;
//TODO test and use param_offset
let (i, _padding) = take(3_usize)(i)?;
let (i, setup_blob) = take(param_cnt)(i)?;
let (i, _padding) = take(3_usize).parse(i)?;
let (i, setup_blob) = take(param_cnt).parse(i)?;
let (i, _padding2) = cond(
data_offset > param_offset + param_cnt,
|b| take(data_offset - param_offset - param_cnt)(b)
)(i)?;
let (i, data_blob) = take(data_cnt)(i)?;
).parse(i)?;
let (i, data_blob) = take(data_cnt).parse(i)?;
let record = SmbRequestTrans2Record {
subcmd,
@ -743,25 +744,25 @@ pub struct SmbResponseCreateAndXRecord<'a> {
}
pub fn parse_smb_create_andx_response_record(i: &[u8]) -> IResult<&[u8], SmbResponseCreateAndXRecord<'_>> {
let (i, wct) = le_u8(i)?;
let (i, _andx_command) = le_u8(i)?;
let (i, _) = take(1_usize)(i)?; // reserved
let (i, _andx_offset) = le_u16(i)?;
let (i, _oplock_level) = le_u8(i)?;
let (i, fid) = take(2_usize)(i)?;
let (i, _create_action) = le_u32(i)?;
let (i, create_ts) = le_u64(i)?;
let (i, last_access_ts) = le_u64(i)?;
let (i, last_write_ts) = le_u64(i)?;
let (i, last_change_ts) = le_u64(i)?;
let (i, _) = take(4_usize)(i)?;
let (i, file_size) = le_u64(i)?;
let (i, _eof) = le_u64(i)?;
let (i, _file_type) = le_u16(i)?;
let (i, _ipc_state) = le_u16(i)?;
let (i, _is_dir) = le_u8(i)?;
let (i, _) = cond(wct == 42, take(32_usize))(i)?;
let (i, _bcc) = le_u16(i)?;
let (i, wct) = le_u8.parse(i)?;
let (i, _andx_command) = le_u8.parse(i)?;
let (i, _) = take(1_usize).parse(i)?; // reserved
let (i, _andx_offset) = le_u16.parse(i)?;
let (i, _oplock_level) = le_u8.parse(i)?;
let (i, fid) = take(2_usize).parse(i)?;
let (i, _create_action) = le_u32.parse(i)?;
let (i, create_ts) = le_u64.parse(i)?;
let (i, last_access_ts) = le_u64.parse(i)?;
let (i, last_write_ts) = le_u64.parse(i)?;
let (i, last_change_ts) = le_u64.parse(i)?;
let (i, _) = take(4_usize).parse(i)?;
let (i, file_size) = le_u64.parse(i)?;
let (i, _eof) = le_u64.parse(i)?;
let (i, _file_type) = le_u16.parse(i)?;
let (i, _ipc_state) = le_u16.parse(i)?;
let (i, _is_dir) = le_u8.parse(i)?;
let (i, _) = cond(wct == 42, take(32_usize)).parse(i)?;
let (i, _bcc) = le_u16.parse(i)?;
let record = SmbResponseCreateAndXRecord {
fid,
create_ts: SMBFiletime::new(create_ts),
@ -779,8 +780,8 @@ pub struct SmbRequestCloseRecord<'a> {
}
pub fn parse_smb1_close_request_record(i: &[u8]) -> IResult<&[u8], SmbRequestCloseRecord<'_>> {
let (i, _) = take(1_usize)(i)?;
let (i, fid) = take(2_usize)(i)?;
let (i, _) = take(1_usize).parse(i)?;
let (i, fid) = take(2_usize).parse(i)?;
let record = SmbRequestCloseRecord {
fid,
};
@ -793,8 +794,8 @@ pub struct SmbVersion<> {
}
pub fn parse_smb_version(i: &[u8]) -> IResult<&[u8], SmbVersion> {
let (i, version) = le_u8(i)?;
let (i, _) = tag(b"SMB")(i)?;
let (i, version) = le_u8.parse(i)?;
let (i, _) = tag(&b"SMB"[..]).parse(i)?;
let version = SmbVersion { version };
Ok((i, version))
}
@ -834,19 +835,19 @@ impl SmbRecord<'_> {
}
pub fn parse_smb_record(i: &[u8]) -> IResult<&[u8], SmbRecord<'_>> {
let (i, _) = tag(b"\xffSMB")(i)?;
let (i, command) = le_u8(i)?;
let (i, nt_status) = le_u32(i)?;
let (i, flags) = le_u8(i)?;
let (i, flags2) = le_u16(i)?;
let (i, process_id_high) = le_u16(i)?;
let (i, _signature) = take(8_usize)(i)?;
let (i, _reserved) = take(2_usize)(i)?;
let (i, tree_id) = le_u16(i)?;
let (i, process_id) = le_u16(i)?;
let (i, user_id) = le_u16(i)?;
let (i, multiplex_id) = le_u16(i)?;
let (i, data) = rest(i)?;
let (i, _) = tag(&b"\xffSMB"[..]).parse(i)?;
let (i, command) = le_u8.parse(i)?;
let (i, nt_status) = le_u32.parse(i)?;
let (i, flags) = le_u8.parse(i)?;
let (i, flags2) = le_u16.parse(i)?;
let (i, process_id_high) = le_u16.parse(i)?;
let (i, _signature) = take(8_usize).parse(i)?;
let (i, _reserved) = take(2_usize).parse(i)?;
let (i, tree_id) = le_u16.parse(i)?;
let (i, process_id) = le_u16.parse(i)?;
let (i, user_id) = le_u16.parse(i)?;
let (i, multiplex_id) = le_u16.parse(i)?;
let (i, data) = rest.parse(i)?;
let record = SmbRecord {
command,

@ -15,7 +15,7 @@
* 02110-1301, USA.
*/
use nom7::Err;
use nom8::Err;
use crate::direction::Direction;
use crate::smb::smb::*;

@ -17,12 +17,13 @@
use crate::smb::nbss_records::NBSS_MSGTYPE_SESSION_MESSAGE;
use crate::smb::smb::*;
use nom7::bytes::streaming::{tag, take};
use nom7::combinator::{cond, map_parser, rest};
use nom7::error::{make_error, ErrorKind};
use nom7::multi::count;
use nom7::number::streaming::{le_u16, le_u32, le_u64, le_u8};
use nom7::{Err, IResult, Needed};
use nom8::bytes::streaming::{tag, take};
use nom8::combinator::{cond, map_parser, rest};
use nom8::error::{make_error, ErrorKind};
use nom8::multi::count;
use nom8::number::streaming::{le_u16, le_u32, le_u64, le_u8};
use nom8::Parser;
use nom8::{Err, IResult, Needed};
const SMB2_FLAGS_SERVER_TO_REDIR: u32 = 0x0000_0001;
const SMB2_FLAGS_ASYNC_COMMAND: u32 = 0x0000_0002;
@ -38,9 +39,9 @@ pub struct Smb2RecordDir {
}
pub fn parse_smb2_record_direction(i: &[u8]) -> IResult<&[u8], Smb2RecordDir> {
let (i, _server_component) = tag(b"\xfeSMB")(i)?;
let (i, _skip) = take(12_usize)(i)?;
let (i, flags) = le_u8(i)?;
let (i, _server_component) = tag(&b"\xfeSMB"[..]).parse(i)?;
let (i, _skip) = take(12_usize).parse(i)?;
let (i, flags) = le_u8.parse(i)?;
let record = Smb2RecordDir {
request: flags & 0x01 == 0,
};
@ -77,7 +78,7 @@ struct SmbFlags {
}
fn parse_smb2_flags(i: &[u8]) -> IResult<&[u8], SmbFlags> {
let (i, val) = le_u32(i)?;
let (i, val) = le_u32.parse(i)?;
let direction = u8::from(val & SMB2_FLAGS_SERVER_TO_REDIR != 0);
let async_command = u8::from(val & SMB2_FLAGS_ASYNC_COMMAND != 0);
Ok((
@ -90,24 +91,24 @@ fn parse_smb2_flags(i: &[u8]) -> IResult<&[u8], SmbFlags> {
}
pub fn parse_smb2_request_record(i: &[u8]) -> IResult<&[u8], Smb2Record<'_>> {
let (i, _server_component) = tag(b"\xfeSMB")(i)?;
let (i, hlen) = le_u16(i)?;
let (i, _credit_charge) = le_u16(i)?;
let (i, _channel_seq) = le_u16(i)?;
let (i, _reserved) = take(2_usize)(i)?;
let (i, command) = le_u16(i)?;
let (i, _credits_requested) = le_u16(i)?;
let (i, _server_component) = tag(&b"\xfeSMB"[..]).parse(i)?;
let (i, hlen) = le_u16.parse(i)?;
let (i, _credit_charge) = le_u16.parse(i)?;
let (i, _channel_seq) = le_u16.parse(i)?;
let (i, _reserved) = take(2_usize).parse(i)?;
let (i, command) = le_u16.parse(i)?;
let (i, _credits_requested) = le_u16.parse(i)?;
let (i, flags) = parse_smb2_flags(i)?;
let (i, chain_offset) = le_u32(i)?;
let (i, message_id) = le_u64(i)?;
let (i, _process_id) = le_u32(i)?;
let (i, tree_id) = le_u32(i)?;
let (i, session_id) = le_u64(i)?;
let (i, _signature) = take(16_usize)(i)?;
let (i, chain_offset) = le_u32.parse(i)?;
let (i, message_id) = le_u64.parse(i)?;
let (i, _process_id) = le_u32.parse(i)?;
let (i, tree_id) = le_u32.parse(i)?;
let (i, session_id) = le_u64.parse(i)?;
let (i, _signature) = take(16_usize).parse(i)?;
let (i, data) = if chain_offset > hlen as u32 {
take(chain_offset - hlen as u32)(i)?
take(chain_offset - hlen as u32).parse(i)?
} else {
rest(i)?
rest.parse(i)?
};
let record = Smb2Record {
direction: flags.direction,
@ -132,16 +133,16 @@ pub struct Smb2NegotiateProtocolRequestRecord<'a> {
pub fn parse_smb2_request_negotiate_protocol(
i: &[u8],
) -> IResult<&[u8], Smb2NegotiateProtocolRequestRecord<'_>> {
let (i, _struct_size) = take(2_usize)(i)?;
let (i, dialects_count) = le_u16(i)?;
let (i, _sec_mode) = le_u16(i)?;
let (i, _reserved1) = le_u16(i)?;
let (i, _capabilities) = le_u32(i)?;
let (i, client_guid) = take(16_usize)(i)?;
let (i, _ctx_offset) = le_u32(i)?;
let (i, _ctx_cnt) = le_u16(i)?;
let (i, _reserved2) = le_u16(i)?;
let (i, dia_vec) = count(le_u16, dialects_count as usize)(i)?;
let (i, _struct_size) = take(2_usize).parse(i)?;
let (i, dialects_count) = le_u16.parse(i)?;
let (i, _sec_mode) = le_u16.parse(i)?;
let (i, _reserved1) = le_u16.parse(i)?;
let (i, _capabilities) = le_u32.parse(i)?;
let (i, client_guid) = take(16_usize).parse(i)?;
let (i, _ctx_offset) = le_u32.parse(i)?;
let (i, _ctx_cnt) = le_u16.parse(i)?;
let (i, _reserved2) = le_u16.parse(i)?;
let (i, dia_vec) = count(le_u16, dialects_count as usize).parse(i)?;
let record = Smb2NegotiateProtocolRequestRecord {
dialects_vec: dia_vec,
client_guid,
@ -161,15 +162,15 @@ pub struct Smb2NegotiateProtocolResponseRecord<'a> {
pub fn parse_smb2_response_negotiate_protocol(
i: &[u8],
) -> IResult<&[u8], Smb2NegotiateProtocolResponseRecord<'_>> {
let (i, _struct_size) = take(2_usize)(i)?;
let (i, _skip1) = take(2_usize)(i)?;
let (i, dialect) = le_u16(i)?;
let (i, _ctx_cnt) = le_u16(i)?;
let (i, server_guid) = take(16_usize)(i)?;
let (i, _capabilities) = le_u32(i)?;
let (i, max_trans_size) = le_u32(i)?;
let (i, max_read_size) = le_u32(i)?;
let (i, max_write_size) = le_u32(i)?;
let (i, _struct_size) = take(2_usize).parse(i)?;
let (i, _skip1) = take(2_usize).parse(i)?;
let (i, dialect) = le_u16.parse(i)?;
let (i, _ctx_cnt) = le_u16.parse(i)?;
let (i, server_guid) = take(16_usize).parse(i)?;
let (i, _capabilities) = le_u32.parse(i)?;
let (i, max_trans_size) = le_u32.parse(i)?;
let (i, max_read_size) = le_u32.parse(i)?;
let (i, max_write_size) = le_u32.parse(i)?;
let record = Smb2NegotiateProtocolResponseRecord {
dialect,
server_guid,
@ -183,8 +184,8 @@ pub fn parse_smb2_response_negotiate_protocol(
pub fn parse_smb2_response_negotiate_protocol_error(
i: &[u8],
) -> IResult<&[u8], Smb2NegotiateProtocolResponseRecord<'_>> {
let (i, _struct_size) = take(2_usize)(i)?;
let (i, _skip1) = take(2_usize)(i)?;
let (i, _struct_size) = take(2_usize).parse(i)?;
let (i, _skip1) = take(2_usize).parse(i)?;
let record = Smb2NegotiateProtocolResponseRecord {
dialect: 0,
server_guid: &[],
@ -201,15 +202,15 @@ pub struct Smb2SessionSetupRequestRecord<'a> {
}
pub fn parse_smb2_request_session_setup(i: &[u8]) -> IResult<&[u8], Smb2SessionSetupRequestRecord<'_>> {
let (i, _struct_size) = take(2_usize)(i)?;
let (i, _flags) = le_u8(i)?;
let (i, _security_mode) = le_u8(i)?;
let (i, _capabilities) = le_u32(i)?;
let (i, _channel) = le_u32(i)?;
let (i, _sec_offset) = le_u16(i)?;
let (i, _sec_len) = le_u16(i)?;
let (i, _prev_ssn_id) = take(8_usize)(i)?;
let (i, data) = rest(i)?;
let (i, _struct_size) = take(2_usize).parse(i)?;
let (i, _flags) = le_u8.parse(i)?;
let (i, _security_mode) = le_u8.parse(i)?;
let (i, _capabilities) = le_u32.parse(i)?;
let (i, _channel) = le_u32.parse(i)?;
let (i, _sec_offset) = le_u16.parse(i)?;
let (i, _sec_len) = le_u16.parse(i)?;
let (i, _prev_ssn_id) = take(8_usize).parse(i)?;
let (i, data) = rest.parse(i)?;
let record = Smb2SessionSetupRequestRecord { data };
Ok((i, record))
}
@ -220,9 +221,9 @@ pub struct Smb2TreeConnectRequestRecord<'a> {
}
pub fn parse_smb2_request_tree_connect(i: &[u8]) -> IResult<&[u8], Smb2TreeConnectRequestRecord<'_>> {
let (i, _struct_size) = take(2_usize)(i)?;
let (i, _offset_length) = take(4_usize)(i)?;
let (i, data) = rest(i)?;
let (i, _struct_size) = take(2_usize).parse(i)?;
let (i, _offset_length) = take(4_usize).parse(i)?;
let (i, data) = rest.parse(i)?;
let record = Smb2TreeConnectRequestRecord { share_name: data };
Ok((i, record))
}
@ -233,11 +234,11 @@ pub struct Smb2TreeConnectResponseRecord {
}
pub fn parse_smb2_response_tree_connect(i: &[u8]) -> IResult<&[u8], Smb2TreeConnectResponseRecord> {
let (i, _struct_size) = take(2_usize)(i)?;
let (i, share_type) = le_u8(i)?;
let (i, _share_flags) = le_u32(i)?;
let (i, _share_caps) = le_u32(i)?;
let (i, _access_mask) = le_u32(i)?;
let (i, _struct_size) = take(2_usize).parse(i)?;
let (i, share_type) = le_u8.parse(i)?;
let (i, _share_flags) = le_u32.parse(i)?;
let (i, _share_caps) = le_u32.parse(i)?;
let (i, _access_mask) = le_u32.parse(i)?;
let record = Smb2TreeConnectResponseRecord { share_type };
Ok((i, record))
}
@ -250,14 +251,14 @@ pub struct Smb2CreateRequestRecord<'a> {
}
pub fn parse_smb2_request_create(i: &[u8]) -> IResult<&[u8], Smb2CreateRequestRecord<'_>> {
let (i, _skip1) = take(36_usize)(i)?;
let (i, disposition) = le_u32(i)?;
let (i, create_options) = le_u32(i)?;
let (i, _file_name_offset) = le_u16(i)?;
let (i, file_name_length) = le_u16(i)?;
let (i, _skip2) = take(8_usize)(i)?;
let (i, data) = take(file_name_length)(i)?;
let (i, _skip3) = rest(i)?;
let (i, _skip1) = take(36_usize).parse(i)?;
let (i, disposition) = le_u32.parse(i)?;
let (i, create_options) = le_u32.parse(i)?;
let (i, _file_name_offset) = le_u16.parse(i)?;
let (i, file_name_length) = le_u16.parse(i)?;
let (i, _skip2) = take(8_usize).parse(i)?;
let (i, data) = take(file_name_length).parse(i)?;
let (i, _skip3) = rest.parse(i)?;
let record = Smb2CreateRequestRecord {
disposition,
create_options,
@ -275,17 +276,17 @@ pub struct Smb2IOCtlRequestRecord<'a> {
}
pub fn parse_smb2_request_ioctl(i: &[u8]) -> IResult<&[u8], Smb2IOCtlRequestRecord<'_>> {
let (i, _skip) = take(2_usize)(i)?; // structure size
let (i, _) = take(2_usize)(i)?; // reserved
let (i, func) = le_u32(i)?;
let (i, guid) = take(16_usize)(i)?;
let (i, _indata_offset) = le_u32(i)?;
let (i, indata_len) = le_u32(i)?;
let (i, _) = take(4_usize)(i)?;
let (i, _outdata_offset) = le_u32(i)?;
let (i, _outdata_len) = le_u32(i)?;
let (i, _) = take(12_usize)(i)?;
let (i, data) = take(indata_len)(i)?;
let (i, _skip) = take(2_usize).parse(i)?; // structure size
let (i, _) = take(2_usize).parse(i)?; // reserved
let (i, func) = le_u32.parse(i)?;
let (i, guid) = take(16_usize).parse(i)?;
let (i, _indata_offset) = le_u32.parse(i)?;
let (i, indata_len) = le_u32.parse(i)?;
let (i, _) = take(4_usize).parse(i)?;
let (i, _outdata_offset) = le_u32.parse(i)?;
let (i, _outdata_len) = le_u32.parse(i)?;
let (i, _) = take(12_usize).parse(i)?;
let (i, data) = take(indata_len).parse(i)?;
let record = Smb2IOCtlRequestRecord {
is_pipe: (func == 0x0011c017),
function: func,
@ -307,17 +308,17 @@ pub struct Smb2IOCtlResponseRecord<'a> {
}
pub fn parse_smb2_response_ioctl(i: &[u8]) -> IResult<&[u8], Smb2IOCtlResponseRecord<'_>> {
let (i, _skip) = take(2_usize)(i)?; // structure size
let (i, _) = take(2_usize)(i)?; // reserved
let (i, func) = le_u32(i)?;
let (i, guid) = take(16_usize)(i)?;
let (i, indata_offset) = le_u32(i)?;
let (i, indata_len) = le_u32(i)?;
let (i, outdata_offset) = le_u32(i)?;
let (i, outdata_len) = le_u32(i)?;
let (i, _) = take(8_usize)(i)?;
let (i, _) = take(indata_len)(i)?;
let (i, data) = take(outdata_len)(i)?;
let (i, _skip) = take(2_usize).parse(i)?; // structure size
let (i, _) = take(2_usize).parse(i)?; // reserved
let (i, func) = le_u32.parse(i)?;
let (i, guid) = take(16_usize).parse(i)?;
let (i, indata_offset) = le_u32.parse(i)?;
let (i, indata_len) = le_u32.parse(i)?;
let (i, outdata_offset) = le_u32.parse(i)?;
let (i, outdata_len) = le_u32.parse(i)?;
let (i, _) = take(8_usize).parse(i)?;
let (i, _) = take(indata_len).parse(i)?;
let (i, data) = take(outdata_len).parse(i)?;
let record = Smb2IOCtlResponseRecord {
is_pipe: (func == 0x0011c017),
guid,
@ -336,8 +337,8 @@ pub struct Smb2CloseRequestRecord<'a> {
}
pub fn parse_smb2_request_close(i: &[u8]) -> IResult<&[u8], Smb2CloseRequestRecord<'_>> {
let (i, _skip) = take(8_usize)(i)?;
let (i, guid) = take(16_usize)(i)?;
let (i, _skip) = take(8_usize).parse(i)?;
let (i, guid) = take(16_usize).parse(i)?;
let record = Smb2CloseRequestRecord { guid };
Ok((i, record))
}
@ -348,11 +349,11 @@ pub struct Smb2SetInfoRequestRenameRecord<'a> {
}
pub fn parse_smb2_request_setinfo_rename(i: &[u8]) -> IResult<&[u8], Smb2SetInfoRequestData<'_>> {
let (i, _replace) = le_u8(i)?;
let (i, _reserved) = take(7_usize)(i)?;
let (i, _root_handle) = take(8_usize)(i)?;
let (i, name_len) = le_u32(i)?;
let (i, name) = take(name_len)(i)?;
let (i, _replace) = le_u8.parse(i)?;
let (i, _reserved) = take(7_usize).parse(i)?;
let (i, _root_handle) = take(8_usize).parse(i)?;
let (i, name_len) = le_u32.parse(i)?;
let (i, name) = take(name_len).parse(i)?;
let record = Smb2SetInfoRequestData::RENAME(Smb2SetInfoRequestRenameRecord { name });
Ok((i, record))
}
@ -363,7 +364,7 @@ pub struct Smb2SetInfoRequestDispoRecord {
}
pub fn parse_smb2_request_setinfo_disposition(i: &[u8]) -> IResult<&[u8], Smb2SetInfoRequestData<'_>> {
let (i, info) = le_u8(i)?;
let (i, info) = le_u8.parse(i)?;
let record = Smb2SetInfoRequestData::DISPOSITION(Smb2SetInfoRequestDispoRecord {
delete: info & 1 != 0,
});
@ -404,17 +405,17 @@ fn parse_smb2_request_setinfo_data(
}
pub fn parse_smb2_request_setinfo(i: &[u8]) -> IResult<&[u8], Smb2SetInfoRequestRecord<'_>> {
let (i, _struct_size) = le_u16(i)?;
let (i, class) = le_u8(i)?;
let (i, infolvl) = le_u8(i)?;
let (i, setinfo_size) = le_u32(i)?;
let (i, _setinfo_offset) = le_u16(i)?;
let (i, _reserved) = take(2_usize)(i)?;
let (i, _additional_info) = le_u32(i)?;
let (i, guid) = take(16_usize)(i)?;
let (i, _struct_size) = le_u16.parse(i)?;
let (i, class) = le_u8.parse(i)?;
let (i, infolvl) = le_u8.parse(i)?;
let (i, setinfo_size) = le_u32.parse(i)?;
let (i, _setinfo_offset) = le_u16.parse(i)?;
let (i, _reserved) = take(2_usize).parse(i)?;
let (i, _additional_info) = le_u32.parse(i)?;
let (i, guid) = take(16_usize).parse(i)?;
let (i, data) = map_parser(take(setinfo_size), |b| {
parse_smb2_request_setinfo_data(b, class, infolvl)
})(i)?;
}).parse(i)?;
let record = Smb2SetInfoRequestRecord {
guid,
class,
@ -434,14 +435,14 @@ pub struct Smb2WriteRequestRecord<'a> {
// can be called on incomplete records
pub fn parse_smb2_request_write(i: &[u8]) -> IResult<&[u8], Smb2WriteRequestRecord<'_>> {
let (i, _skip1) = take(4_usize)(i)?;
let (i, wr_len) = le_u32(i)?;
let (i, wr_offset) = le_u64(i)?;
let (i, guid) = take(16_usize)(i)?;
let (i, _channel) = le_u32(i)?;
let (i, _remaining_bytes) = le_u32(i)?;
let (i, _write_flags) = le_u32(i)?;
let (i, _skip2) = take(4_usize)(i)?;
let (i, _skip1) = take(4_usize).parse(i)?;
let (i, wr_len) = le_u32.parse(i)?;
let (i, wr_offset) = le_u64.parse(i)?;
let (i, guid) = take(16_usize).parse(i)?;
let (i, _channel) = le_u32.parse(i)?;
let (i, _remaining_bytes) = le_u32.parse(i)?;
let (i, _write_flags) = le_u32.parse(i)?;
let (i, _skip2) = take(4_usize).parse(i)?;
let (i, data) = parse_smb2_data(i, wr_len)?;
let record = Smb2WriteRequestRecord {
wr_len,
@ -460,14 +461,14 @@ pub struct Smb2ReadRequestRecord<'a> {
}
pub fn parse_smb2_request_read(i: &[u8]) -> IResult<&[u8], Smb2ReadRequestRecord<'_>> {
let (i, _skip1) = take(4_usize)(i)?;
let (i, rd_len) = le_u32(i)?;
let (i, rd_offset) = le_u64(i)?;
let (i, guid) = take(16_usize)(i)?;
let (i, _min_count) = le_u32(i)?;
let (i, _channel) = le_u32(i)?;
let (i, _remaining_bytes) = le_u32(i)?;
let (i, _skip2) = take(4_usize)(i)?;
let (i, _skip1) = take(4_usize).parse(i)?;
let (i, rd_len) = le_u32.parse(i)?;
let (i, rd_offset) = le_u64.parse(i)?;
let (i, guid) = take(16_usize).parse(i)?;
let (i, _min_count) = le_u32.parse(i)?;
let (i, _channel) = le_u32.parse(i)?;
let (i, _remaining_bytes) = le_u32.parse(i)?;
let (i, _skip2) = take(4_usize).parse(i)?;
let record = Smb2ReadRequestRecord {
rd_len,
rd_offset,
@ -495,11 +496,11 @@ fn parse_smb2_data(i: &[u8], len: u32) -> IResult<&[u8], &[u8]> {
// can be called on incomplete records
pub fn parse_smb2_response_read(i: &[u8]) -> IResult<&[u8], Smb2ReadResponseRecord<'_>> {
let (i, _struct_size) = le_u16(i)?;
let (i, _data_offset) = le_u16(i)?;
let (i, rd_len) = le_u32(i)?;
let (i, _rd_rem) = le_u32(i)?;
let (i, _padding) = take(4_usize)(i)?;
let (i, _struct_size) = le_u16.parse(i)?;
let (i, _data_offset) = le_u16.parse(i)?;
let (i, rd_len) = le_u32.parse(i)?;
let (i, _rd_rem) = le_u32.parse(i)?;
let (i, _padding) = take(4_usize).parse(i)?;
let (i, data) = parse_smb2_data(i, rd_len)?;
let record = Smb2ReadResponseRecord { len: rd_len, data };
Ok((i, record))
@ -516,20 +517,20 @@ pub struct Smb2CreateResponseRecord<'a> {
}
pub fn parse_smb2_response_create(i: &[u8]) -> IResult<&[u8], Smb2CreateResponseRecord<'_>> {
let (i, _ssize) = le_u16(i)?;
let (i, _oplock) = le_u8(i)?;
let (i, _resp_flags) = le_u8(i)?;
let (i, _create_action) = le_u32(i)?;
let (i, create_ts) = le_u64(i)?;
let (i, last_access_ts) = le_u64(i)?;
let (i, last_write_ts) = le_u64(i)?;
let (i, last_change_ts) = le_u64(i)?;
let (i, _alloc_size) = le_u64(i)?;
let (i, eof) = le_u64(i)?;
let (i, _attrs) = le_u32(i)?;
let (i, _padding) = take(4_usize)(i)?;
let (i, guid) = take(16_usize)(i)?;
let (i, _skip2) = take(8_usize)(i)?;
let (i, _ssize) = le_u16.parse(i)?;
let (i, _oplock) = le_u8.parse(i)?;
let (i, _resp_flags) = le_u8.parse(i)?;
let (i, _create_action) = le_u32.parse(i)?;
let (i, create_ts) = le_u64.parse(i)?;
let (i, last_access_ts) = le_u64.parse(i)?;
let (i, last_write_ts) = le_u64.parse(i)?;
let (i, last_change_ts) = le_u64.parse(i)?;
let (i, _alloc_size) = le_u64.parse(i)?;
let (i, eof) = le_u64.parse(i)?;
let (i, _attrs) = le_u32.parse(i)?;
let (i, _padding) = take(4_usize).parse(i)?;
let (i, guid) = take(16_usize).parse(i)?;
let (i, _skip2) = take(8_usize).parse(i)?;
let record = Smb2CreateResponseRecord {
guid,
create_ts: SMBFiletime::new(create_ts),
@ -547,32 +548,32 @@ pub struct Smb2WriteResponseRecord {
}
pub fn parse_smb2_response_write(i: &[u8]) -> IResult<&[u8], Smb2WriteResponseRecord> {
let (i, _skip1) = take(4_usize)(i)?;
let (i, wr_cnt) = le_u32(i)?;
let (i, _skip2) = take(6_usize)(i)?;
let (i, _skip1) = take(4_usize).parse(i)?;
let (i, wr_cnt) = le_u32.parse(i)?;
let (i, _skip2) = take(6_usize).parse(i)?;
let record = Smb2WriteResponseRecord { wr_cnt };
Ok((i, record))
}
pub fn parse_smb2_response_record(i: &[u8]) -> IResult<&[u8], Smb2Record<'_>> {
let (i, _) = tag(b"\xfeSMB")(i)?;
let (i, hlen) = le_u16(i)?;
let (i, _credit_charge) = le_u16(i)?;
let (i, nt_status) = le_u32(i)?;
let (i, command) = le_u16(i)?;
let (i, _credit_granted) = le_u16(i)?;
let (i, _) = tag(&b"\xfeSMB"[..]).parse(i)?;
let (i, hlen) = le_u16.parse(i)?;
let (i, _credit_charge) = le_u16.parse(i)?;
let (i, nt_status) = le_u32.parse(i)?;
let (i, command) = le_u16.parse(i)?;
let (i, _credit_granted) = le_u16.parse(i)?;
let (i, flags) = parse_smb2_flags(i)?;
let (i, chain_offset) = le_u32(i)?;
let (i, message_id) = le_u64(i)?;
let (i, _process_id) = cond(flags.async_command == 0, le_u32)(i)?;
let (i, tree_id) = cond(flags.async_command == 0, le_u32)(i)?;
let (i, async_id) = cond(flags.async_command == 1, le_u64)(i)?;
let (i, session_id) = le_u64(i)?;
let (i, _signature) = take(16_usize)(i)?;
let (i, chain_offset) = le_u32.parse(i)?;
let (i, message_id) = le_u64.parse(i)?;
let (i, _process_id) = cond(flags.async_command == 0, le_u32).parse(i)?;
let (i, tree_id) = cond(flags.async_command == 0, le_u32).parse(i)?;
let (i, async_id) = cond(flags.async_command == 1, le_u64).parse(i)?;
let (i, session_id) = le_u64.parse(i)?;
let (i, _signature) = take(16_usize).parse(i)?;
let (i, data) = if chain_offset > hlen as u32 {
take(chain_offset - hlen as u32)(i)?
take(chain_offset - hlen as u32).parse(i)?
} else {
rest(i)?
rest.parse(i)?
};
let record = Smb2Record {
direction: flags.direction,

@ -15,9 +15,10 @@
* 02110-1301, USA.
*/
use nom7::bytes::streaming::{tag, take};
use nom7::number::streaming::{le_u16, le_u32, le_u64};
use nom7::IResult;
use nom8::bytes::streaming::{tag, take};
use nom8::number::streaming::{le_u16, le_u32, le_u64};
use nom8::Parser;
use nom8::IResult;
#[derive(Debug,PartialEq, Eq)]
pub struct Smb3TransformRecord<'a> {
@ -27,14 +28,14 @@ pub struct Smb3TransformRecord<'a> {
}
pub fn parse_smb3_transform_record(i: &[u8]) -> IResult<&[u8], Smb3TransformRecord<'_>> {
let (i, _) = tag(b"\xfdSMB")(i)?;
let (i, _signature) = take(16_usize)(i)?;
let (i, _nonce) = take(16_usize)(i)?;
let (i, msg_size) = le_u32(i)?;
let (i, _reserved) = le_u16(i)?;
let (i, enc_algo) = le_u16(i)?;
let (i, session_id) = le_u64(i)?;
let (i, enc_data) = take(msg_size)(i)?;
let (i, _) = tag(&b"\xfdSMB"[..]).parse(i)?;
let (i, _signature) = take(16_usize).parse(i)?;
let (i, _nonce) = take(16_usize).parse(i)?;
let (i, msg_size) = le_u32.parse(i)?;
let (i, _reserved) = le_u16.parse(i)?;
let (i, enc_algo) = le_u16.parse(i)?;
let (i, session_id) = le_u64.parse(i)?;
let (i, enc_data) = take(msg_size).parse(i)?;
let record = Smb3TransformRecord {
session_id,
enc_algo,

@ -15,9 +15,10 @@
* 02110-1301, USA.
*/
use crate::common::nom7::take_until_and_consume;
use crate::common::nom8::take_until_and_consume;
use crate::smb::error::SmbError;
use nom7::{Err, IResult};
use nom8::Parser;
use nom8::{Err, IResult};
/// parse a UTF16 string that is null terminated. Normally by 2 null
/// bytes, but at the end of the data it can also be a single null.
@ -47,7 +48,7 @@ pub fn smb_get_unicode_string(blob: &[u8]) -> IResult<&[u8], Vec<u8>, SmbError>
// parse an ASCII string that is null terminated
pub fn smb_get_ascii_string(i: &[u8]) -> IResult<&[u8], Vec<u8>, SmbError> {
let (i, s) = take_until_and_consume(b"\x00")(i)?;
let (i, s) = take_until_and_consume(b"\x00").parse(i)?;
Ok((i, s.to_vec()))
}

Loading…
Cancel
Save