pub version: Option<NTLMSSPVersion>,
}
-fn parse_ntlm_auth_nego_flags(i:&[u8]) -> IResult<&[u8],(u8,u8,u32)> {
- bits!(i, tuple!(take_bits!(6u8),take_bits!(1u8),take_bits!(25u32)))
+#[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;
let (i, _ssnkey_blob_offset) = le_u32(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)?;
data:data,
})
));
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use nom::Err;
+ #[test]
+ fn test_parse_auth_nego_flags() {
+ // ntlmssp.negotiateflags 1
+ let blob = [0x15, 0x82, 0x88, 0xe2];
+ let result = parse_ntlm_auth_nego_flags(&blob);
+ match result {
+ 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);
+ }
+ 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)) => {
+ panic!("Result should not be an error: {:?}.", err);
+ }
+ Err(Err::Incomplete(_)) => {
+ panic!("Result should not have been incomplete.");
+ }
+ _ => {
+ panic!("Unexpected behavior!");
+ }
+ }
+ }
+}