smb/ntlmssp: fix parsing of negotiate flags

Ticket: #5783
pull/8815/head
tianjinshan 3 years ago committed by Victor Julien
parent 38b3fffbc7
commit 2c0c6cb0a5

@ -15,13 +15,11 @@
* 02110-1301, USA. * 02110-1301, USA.
*/ */
use crate::common::nom7::{bits, take_until_and_consume}; use crate::common::nom7::take_until_and_consume;
use nom7::bits::streaming::take as take_bits;
use nom7::bytes::streaming::take; use nom7::bytes::streaming::take;
use nom7::combinator::{cond, rest, verify}; use nom7::combinator::{cond, rest, verify};
use nom7::error::{make_error, ErrorKind}; use nom7::error::{make_error, ErrorKind};
use nom7::number::streaming::{le_u16, le_u32, le_u8}; use nom7::number::streaming::{le_u16, le_u32, le_u8};
use nom7::sequence::tuple;
use nom7::Err; use nom7::Err;
use nom7::IResult; use nom7::IResult;
use std::fmt; use std::fmt;
@ -68,8 +66,15 @@ pub struct NTLMSSPAuthRecord<'a> {
pub warning: bool, pub warning: bool,
} }
fn parse_ntlm_auth_nego_flags(i: &[u8]) -> IResult<&[u8], (u32, u8, u8)> { #[derive(Debug, PartialEq, Eq)]
bits(tuple((take_bits(25u8), take_bits(1u8), take_bits(6u32))))(i) 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; 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, _ssnkey_blob_offset) = verify(le_u32, |&v| (v as usize) < record_len)(i)?;
let (i, nego_flags) = parse_ntlm_auth_nego_flags(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... // Caller does not care about remaining input...
let (_, domain_blob) = extract_ntlm_substring(orig_i, domain_blob_offset, domain_blob_len)?; let (_, domain_blob) = extract_ntlm_substring(orig_i, domain_blob_offset, domain_blob_len)?;
@ -161,12 +166,30 @@ mod tests {
use nom7::Err; use nom7::Err;
#[test] #[test]
fn test_parse_auth_nego_flags() { fn test_parse_auth_nego_flags() {
// ntlmssp.negotiateflags // ntlmssp.negotiateflags 1
let blob = [0x15, 0x82, 0x88, 0xe2]; let blob = [0x15, 0x82, 0x88, 0xe2];
let result = parse_ntlm_auth_nego_flags(&blob); let result = parse_ntlm_auth_nego_flags(&blob);
match result { match result {
Ok((remainder, (_, version_flag, _))) => { Ok((remainder, flags)) => {
assert_eq!(version_flag, 1); 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); assert_eq!(remainder.len(), 0);
} }
Err(Err::Error(err)) => { Err(Err::Error(err)) => {

Loading…
Cancel
Save