//! * x.691-spec: <https://www.itu.int/rec/T-REC-X.691/en>
use nom::IResult;
-use nom::error::{make_error, ErrorKind};
+use nom::bytes::complete::take;
+use nom::combinator::{opt, map_opt, map_res};
use nom::number::complete::{be_u16, be_u8, le_u16, le_u32, le_u8};
use crate::rdp::error::RdpError;
use crate::rdp::util::{
return Ok((i4, T123Tpkt { child }));
}
+fn take_4_4_bits(input: &[u8]) -> IResult<&[u8], (u8,u8), RdpError> {
+ map!(input, be_u8, |b| (b >> 4, b & 0xf))
+}
+
/// rdp-spec, section 2.2.1.1
fn parse_x224_connection_request(
input: &[u8],
) -> IResult<&[u8], X224ConnectionRequest, RdpError> {
let (i1, length) = verify!(input, be_u8, |&x| x != 0xff)?; // 0xff is reserved
- let (i2, cr_cdt) = bits!(
- i1,
- tuple!(
- verify!(take_bits!(4u8), |&x| x
- == X224Type::ConnectionRequest as u8),
- verify!(take_bits!(4u8), |&x| x == 0 || x == 1)
- )
- )?;
+ let (i2, cr_cdt) = take_4_4_bits(input)?;
+ let _ = verify!(i1, value!(cr_cdt.0), |&x| x
+ == X224Type::ConnectionRequest as u8)?;
+ let _ = verify!(i1, value!(cr_cdt.1), |&x| x == 0 || x == 1)?;
let (i3, dst_ref) = verify!(i2, be_u16, |&x| x == 0)?;
let (i4, src_ref) = try_parse!(i3, be_u16);
let (i5, class_options) = bits!(
)
)?;
// less cr_cdt (u8), dst_ref (u16), src_ref (u16), class_options (u8)
- if length < 6 {
- return make_error(i5, ErrorKind::Verify)?;
- }
+ let _ = verify!(i1, value!(length), |&x| x >= 6)?;
let i6 = i5;
let sz = length - 6;
fn parse_rdp_cookie(input: &[u8]) -> IResult<&[u8], RdpCookie, RdpError> {
do_parse! {
input,
- _key: verify!(
- take!(8),
- |x| x == b"Cookie: ")
- >> _name: verify!(
- take!(9),
- |x| x == b"mstshash=")
+ _key: tag!(b"Cookie: ")
+ >> _name: tag!(b"mstshash=")
>> bytes: take_until_and_consume!("\r\n")
>> s: map_res!(value!(bytes), std::str::from_utf8)
>> (RdpCookie{ mstshash: String::from(s) })
input: &[u8],
) -> IResult<&[u8], X224ConnectionConfirm, RdpError> {
let (i1, length) = verify!(input, be_u8, |&x| x != 0xff)?; // 0xff is reserved
- let (i2, cr_cdt) = bits!(
- i1,
- tuple!(
- verify!(take_bits!(4u8), |&x| x
- == X224Type::ConnectionConfirm as u8),
- verify!(take_bits!(4u8), |&x| x == 0 || x == 1)
- )
- )?;
+ let (i2, cr_cdt) = take_4_4_bits(input)?;
+ let _ = verify!(i1, value!(cr_cdt.0), |&x| x
+ == X224Type::ConnectionConfirm as u8)?;
+ let _ = verify!(i1, value!(cr_cdt.1), |&x| x == 0 || x == 1)?;
let (i3, dst_ref) = verify!(i2, be_u16, |&x| x == 0)?;
let (i4, src_ref) = try_parse!(i3, be_u16);
let (i5, class_options) = bits!(
)?;
// less cr_cdt (u8), dst_ref (u16), src_ref (u16), class_options (u8)
- if length < 6 {
- return make_error(i5, ErrorKind::Verify)?;
- }
+ let _ = verify!(i1, value!(length), |&x| x >= 6)?;
let i6 = i5;
let sz = length - 6;
/// x224-spec, section 13.7
fn parse_x223_data_class_0(input: &[u8]) -> IResult<&[u8], X223Data, RdpError> {
- let (i1, _length) = verify!(input, be_u8, |&x| x == 2)?;
- let (i2, _dt_x_roa) = bits!(
- i1,
- tuple!(
- verify!(take_bits!(4u8), |&x| x == 0xf),
- verify!(take_bits!(3u8), |&x| x == 0),
- verify!(take_bits!(1u8), |&x| x == 0)
+ fn parser(input: &[u8]) -> IResult<&[u8], (u8,u8,u8), RdpError> {
+ bits!(
+ input,
+ tuple!(
+ verify!(take_bits!(4u8), |&x| x == 0xf),
+ verify!(take_bits!(3u8), |&x| x == 0),
+ verify!(take_bits!(1u8), |&x| x == 0)
+ )
)
- )?;
+ }
+ let (i1, _length) = verify!(input, be_u8, |&x| x == 2)?;
+ let (i2, _dt_x_roa) = parser(i1)?;
let (i3, _eot) = verify!(i2, be_u8, |&x| x == 0x80)?;
//
//
let (j13, post_beta2_color_depth) =
- match opt!(j12, map_opt!(le_u16, num::FromPrimitive::from_u16)) {
+ match opt!(j12, map_opt!(le_u16, num::FromPrimitive::from_u16)) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j12, None),
};
let (j14, client_product_id) = match post_beta2_color_depth {
None => (j13, None),
- Some(_) => match opt!(j13, le_u16) {
+ Some(_) => match opt!(j13, le_u16) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j13, None),
},
let (j15, serial_number) = match client_product_id {
None => (j14, None),
- Some(_) => match opt!(j14, le_u32) {
+ Some(_) => match opt!(j14, le_u32) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j14, None),
},
let (j16, high_color_depth) = match serial_number {
None => (j15, None),
Some(_) => {
- match opt!(j15, map_opt!(le_u16, num::FromPrimitive::from_u16)) {
+ match opt!(j15, map_opt!(le_u16, num::FromPrimitive::from_u16)) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j15, None),
}
let (j17, supported_color_depth) = match high_color_depth {
None => (j16, None),
Some(_) => {
- match opt!(j16, map_opt!(le_u16, SupportedColorDepth::from_bits)) {
+ match opt!(j16, map_opt!(le_u16, SupportedColorDepth::from_bits)) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j16, None),
}
let (j18, early_capability_flags) = match supported_color_depth {
None => (j17, None),
Some(_) => {
- match opt!(j17, map_opt!(le_u16, EarlyCapabilityFlags::from_bits)) {
+ match opt!(j17, map_opt!(le_u16, EarlyCapabilityFlags::from_bits)) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j17, None),
}
let (j19, client_dig_product_id) = match early_capability_flags {
None => (j18, None),
- Some(_) => match opt!(j18, map_res!(take!(64), le_slice_to_string)) {
+ Some(_) => match opt(map_res(take(64usize), le_slice_to_string))(j18) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j18, None),
},
let (j20, connection_hint) = match client_dig_product_id {
None => (j19, None),
Some(_) => {
- match opt!(j19, map_opt!(le_u8, num::FromPrimitive::from_u8)) {
+ match opt(map_opt(le_u8, num::FromPrimitive::from_u8))(j19) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j19, None),
}
let (j21, pad) = match connection_hint {
None => (j20, None),
- Some(_) => match opt!(j20, take!(1)) {
+ Some(_) => match opt(take(1usize))(j20) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j20, None),
},
let (j22, server_selected_protocol) = match pad {
None => (j21, None),
Some(_) => {
- match opt!(j21, map_opt!(le_u32, ProtocolFlags::from_bits)) {
+ match opt!(j21, map_opt!(le_u32, ProtocolFlags::from_bits)) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j21, None),
}
let (j23, desktop_physical_width) = match server_selected_protocol {
None => (j22, None),
- Some(_) => match opt!(j22, map_opt!(le_u32, millimeters_to_opt)) {
+ Some(_) => match opt!(j22, map_opt!(le_u32, millimeters_to_opt)) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j22, None),
},
let (j24, desktop_physical_height) = match desktop_physical_width {
None => (j23, None),
- Some(_) => match opt!(j23, map_opt!(le_u32, millimeters_to_opt)) {
+ Some(_) => match opt!(j23, map_opt!(le_u32, millimeters_to_opt)) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j23, None),
},
let (j25, desktop_orientation) = match desktop_physical_height {
None => (j24, None),
Some(_) => {
- match opt!(j24, map_opt!(le_u16, num::FromPrimitive::from_u16)) {
+ match opt!(j24, map_opt!(le_u16, num::FromPrimitive::from_u16)) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j24, None),
}
let (j26, desktop_scale_factor) = match desktop_orientation {
None => (j25, None),
- Some(_) => match opt!(j25, map_opt!(le_u32, desktop_scale_to_opt)) {
+ Some(_) => match opt!(j25, map_opt!(le_u32, desktop_scale_to_opt)) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j25, None),
},
let (_j27, device_scale_factor) = match desktop_scale_factor {
None => (j26, None),
- Some(_) => match opt!(j26, map_opt!(le_u32, device_scale_to_opt)) {
+ Some(_) => match opt!(j26, map_opt!(le_u32, device_scale_to_opt)) as IResult<&[u8],_> {
Ok((rem, obj)) => (rem, obj),
_ => (j26, None),
},
}
}
+fn parse_smb2_request_flags(i:&[u8]) -> IResult<&[u8],(u8,u8,u8,u32,u8,u8,u8,u8)> {
+ bits!(i,
+ tuple!(
+ take_bits!(2u8), // reserved / unused
+ take_bits!(1u8), // replay op
+ take_bits!(1u8), // dfs op
+ take_bits!(24u32), // reserved / unused
+ take_bits!(1u8), // signing
+ take_bits!(1u8), // chained
+ take_bits!(1u8), // async
+ take_bits!(1u8) // response
+ ))
+}
+
named!(pub parse_smb2_request_record<Smb2Record>,
do_parse!(
_server_component: tag!(b"\xfeSMB")
>> _reserved: take!(2)
>> command: le_u16
>> _credits_requested: le_u16
- >> flags: bits!(tuple!(
- take_bits!(2u8), // reserved / unused
- take_bits!(1u8), // replay op
- take_bits!(1u8), // dfs op
- take_bits!(24u32), // reserved / unused
- take_bits!(1u8), // signing
- take_bits!(1u8), // chained
- take_bits!(1u8), // async
- take_bits!(1u8) // response
- ))
+ >> flags: parse_smb2_request_flags
>> chain_offset: le_u32
>> message_id: le_u64
>> _process_id: le_u32
>> nt_status: le_u32
>> command: le_u16
>> _credit_granted: le_u16
- >> flags: bits!(tuple!(
- take_bits!(2u8), // reserved / unused
- take_bits!(1u8), // replay op
- take_bits!(1u8), // dfs op
- take_bits!(24u32), // reserved / unused
- take_bits!(1u8), // signing
- take_bits!(1u8), // chained
- take_bits!(1u8), // async
- take_bits!(1u8) // response
- ))
+ >> flags: parse_smb2_request_flags
>> chain_offset: le_u32
>> message_id: le_u64
>> _process_id: cond!(flags.6==0, le_u32)