diff --git a/rust/src/smb/ntlmssp_records.rs b/rust/src/smb/ntlmssp_records.rs index cde31cecc5..b99d74dc07 100644 --- a/rust/src/smb/ntlmssp_records.rs +++ b/rust/src/smb/ntlmssp_records.rs @@ -15,13 +15,11 @@ * 02110-1301, USA. */ -use crate::common::nom7::{bits, take_until_and_consume}; -use nom7::bits::streaming::take as take_bits; +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::sequence::tuple; use nom7::Err; use nom7::IResult; use std::fmt; @@ -68,8 +66,15 @@ pub struct NTLMSSPAuthRecord<'a> { pub warning: bool, } -fn parse_ntlm_auth_nego_flags(i: &[u8]) -> IResult<&[u8], (u32, u8, u8)> { - bits(tuple((take_bits(25u8), take_bits(1u8), take_bits(6u32))))(i) +#[derive(Debug, PartialEq, Eq)] +pub struct NTLMSSPNegotiateFlags { + pub version: bool, + // others fields not done because not interesting yet +} + +fn parse_ntlm_auth_nego_flags(i: &[u8]) -> IResult<&[u8], NTLMSSPNegotiateFlags> { + let (i, raw) = le_u32(i)?; + return Ok((i, NTLMSSPNegotiateFlags{version: (raw & 0x2000000) != 0})); } const NTLMSSP_IDTYPE_LEN: usize = 12; @@ -115,7 +120,7 @@ pub fn parse_ntlm_auth_record(i: &[u8]) -> IResult<&[u8], NTLMSSPAuthRecord> { let (i, _ssnkey_blob_offset) = verify(le_u32, |&v| (v as usize) < record_len)(i)?; let (i, nego_flags) = parse_ntlm_auth_nego_flags(i)?; - let (_, version) = cond(nego_flags.1 == 1, parse_ntlm_auth_version)(i)?; + let (_, version) = cond(nego_flags.version, parse_ntlm_auth_version)(i)?; // Caller does not care about remaining input... let (_, domain_blob) = extract_ntlm_substring(orig_i, domain_blob_offset, domain_blob_len)?; @@ -161,12 +166,30 @@ mod tests { use nom7::Err; #[test] fn test_parse_auth_nego_flags() { - // ntlmssp.negotiateflags + // ntlmssp.negotiateflags 1 let blob = [0x15, 0x82, 0x88, 0xe2]; let result = parse_ntlm_auth_nego_flags(&blob); match result { - Ok((remainder, (_, version_flag, _))) => { - assert_eq!(version_flag, 1); + Ok((remainder, flags)) => { + assert_eq!(flags.version, true); + assert_eq!(remainder.len(), 0); + } + Err(Err::Error(err)) => { + panic!("Result should not be an error: {:?}.", err.code); + } + Err(Err::Incomplete(_)) => { + panic!("Result should not have been incomplete."); + } + _ => { + panic!("Unexpected behavior!"); + } + } + // ntlmssp.negotiateflags 0 + let blob = [0x15, 0x82, 0x88, 0xe0]; + let result = parse_ntlm_auth_nego_flags(&blob); + match result { + Ok((remainder, flags)) => { + assert_eq!(flags.version, false); assert_eq!(remainder.len(), 0); } Err(Err::Error(err)) => {