rust: format rdp files

Ticket: 3836
pull/15521/head
Philippe Antoine 2 months ago committed by Victor Julien
parent c8a86cdffa
commit 9d9d8df4cd

@ -479,12 +479,14 @@ fn take_4_4_bits(input: &[u8]) -> IResult<&[u8], (u8, u8), RdpError> {
} }
fn parse_class_options(i: &[u8]) -> IResult<&[u8], (u8, u8)> { fn parse_class_options(i: &[u8]) -> IResult<&[u8], (u8, u8)> {
bits( bits(|i| {
|i| ( (
verify(take_bits(4u8), |&x| x <= 4), verify(take_bits(4u8), |&x| x <= 4),
verify(take_bits(4u8), |&x| x <= 3), verify(take_bits(4u8), |&x| x <= 3),
).parse(i) )
).parse(i) .parse(i)
})
.parse(i)
} }
/// rdp-spec, section 2.2.1.1 /// rdp-spec, section 2.2.1.1
@ -575,14 +577,20 @@ fn parse_rdp_cookie(i: &[u8]) -> IResult<&[u8], RdpCookie, RdpError> {
let (i, _name) = tag(&b"mstshash="[..])(i)?; let (i, _name) = tag(&b"mstshash="[..])(i)?;
let (i, bytes) = take_until_and_consume(b"\r\n")(i)?; let (i, bytes) = take_until_and_consume(b"\r\n")(i)?;
// let (i, s) = map_res(value!(bytes), std::str::from_utf8)(i)?; // let (i, s) = map_res(value!(bytes), std::str::from_utf8)(i)?;
let s = std::str::from_utf8(bytes).map_err(|_| Err::Error(make_error(bytes, ErrorKind::MapRes)))?; let s =
let cookie = RdpCookie{ mstshash: String::from(s) }; std::str::from_utf8(bytes).map_err(|_| Err::Error(make_error(bytes, ErrorKind::MapRes)))?;
let cookie = RdpCookie {
mstshash: String::from(s),
};
Ok((i, cookie)) Ok((i, cookie))
} }
// rdp-spec, section 2.2.1.1.1 // rdp-spec, section 2.2.1.1.1
fn parse_negotiation_request(i: &[u8]) -> IResult<&[u8], NegotiationRequest, RdpError> { fn parse_negotiation_request(i: &[u8]) -> IResult<&[u8], NegotiationRequest, RdpError> {
let (i, _typ) = verify(le_u8, |&x| x == X224ConnectionRequestType::NegotiationRequest as u8).parse(i)?; let (i, _typ) = verify(le_u8, |&x| {
x == X224ConnectionRequestType::NegotiationRequest as u8
})
.parse(i)?;
let (i, flags) = map_opt(le_u8, NegotiationRequestFlags::from_bits).parse(i)?; let (i, flags) = map_opt(le_u8, NegotiationRequestFlags::from_bits).parse(i)?;
// u8, u8, u16, and u32 give _length of 8 // u8, u8, u16, and u32 give _length of 8
let (i, _length) = verify(le_u16, |&x| x == 8).parse(i)?; let (i, _length) = verify(le_u16, |&x| x == 8).parse(i)?;
@ -618,10 +626,11 @@ fn parse_x224_connection_confirm(input: &[u8]) -> IResult<&[u8], X224ConnectionC
let (i7, data) = take(sz).parse(i6)?; let (i7, data) = take(sz).parse(i6)?;
// it will be one of a response message or a failure message // it will be one of a response message or a failure message
let opt1: Option<NegotiationFromServer> = match opt(parse_negotiation_response).parse(data) { let opt1: Option<NegotiationFromServer> =
Ok((_remainder, opt)) => opt.map(NegotiationFromServer::Response), match opt(parse_negotiation_response).parse(data) {
Err(e) => return Err(e), Ok((_remainder, opt)) => opt.map(NegotiationFromServer::Response),
}; Err(e) => return Err(e),
};
let opt2: Option<NegotiationFromServer> = match opt1 { let opt2: Option<NegotiationFromServer> = match opt1 {
Some(x) => Some(x), Some(x) => Some(x),
None => match opt(parse_negotiation_failure).parse(data) { None => match opt(parse_negotiation_failure).parse(data) {
@ -664,7 +673,10 @@ fn parse_x224_connection_confirm_class_0(
// rdp-spec, section 2.2.1.1.1 // rdp-spec, section 2.2.1.1.1
fn parse_negotiation_response(i: &[u8]) -> IResult<&[u8], NegotiationResponse, RdpError> { fn parse_negotiation_response(i: &[u8]) -> IResult<&[u8], NegotiationResponse, RdpError> {
let (i, _typ) = verify(le_u8, |&x| x == X224ConnectionRequestType::NegotiationResponse as u8).parse(i)?; let (i, _typ) = verify(le_u8, |&x| {
x == X224ConnectionRequestType::NegotiationResponse as u8
})
.parse(i)?;
let (i, flags) = map_opt(le_u8, NegotiationResponseFlags::from_bits).parse(i)?; let (i, flags) = map_opt(le_u8, NegotiationResponseFlags::from_bits).parse(i)?;
// u8, u8, u16, and u32 give _length of 8 // u8, u8, u16, and u32 give _length of 8
let (i, _length) = verify(le_u16, |&x| x == 8).parse(i)?; let (i, _length) = verify(le_u16, |&x| x == 8).parse(i)?;
@ -674,7 +686,10 @@ fn parse_negotiation_response(i: &[u8]) -> IResult<&[u8], NegotiationResponse, R
// rdp-spec, section 2.2.1.1.1 // rdp-spec, section 2.2.1.1.1
fn parse_negotiation_failure(i: &[u8]) -> IResult<&[u8], NegotiationFailure, RdpError> { fn parse_negotiation_failure(i: &[u8]) -> IResult<&[u8], NegotiationFailure, RdpError> {
let (i, _typ) = verify(le_u8, |&x| x == X224ConnectionRequestType::NegotiationFailure as u8).parse(i)?; let (i, _typ) = verify(le_u8, |&x| {
x == X224ConnectionRequestType::NegotiationFailure as u8
})
.parse(i)?;
let (i, _flags) = le_u8(i)?; let (i, _flags) = le_u8(i)?;
// u8, u8, u16, and u32 give _length of 8 // u8, u8, u16, and u32 give _length of 8
let (i, _length) = verify(le_u16, |&x| x == 8).parse(i)?; let (i, _length) = verify(le_u16, |&x| x == 8).parse(i)?;
@ -685,13 +700,14 @@ fn parse_negotiation_failure(i: &[u8]) -> IResult<&[u8], NegotiationFailure, Rdp
/// x224-spec, section 13.7 /// x224-spec, section 13.7
fn parse_x223_data_class_0(input: &[u8]) -> IResult<&[u8], X223Data, RdpError> { fn parse_x223_data_class_0(input: &[u8]) -> IResult<&[u8], X223Data, RdpError> {
fn parser(i: &[u8]) -> IResult<&[u8], (u8, u8, u8)> { fn parser(i: &[u8]) -> IResult<&[u8], (u8, u8, u8)> {
bits( bits(|i| {
|i| ( (
verify(take_bits(4u8), |&x| x == 0xf), verify(take_bits(4u8), |&x| x == 0xf),
verify(take_bits(3u8), |&x| x == 0), verify(take_bits(3u8), |&x| x == 0),
verify(take_bits(1u8), |&x| x == 0), verify(take_bits(1u8), |&x| x == 0),
).parse(i) )
)(i) .parse(i)
})(i)
} }
let (i1, _length) = verify(be_u8, |&x| x == 2).parse(input)?; let (i1, _length) = verify(be_u8, |&x| x == 2).parse(input)?;
let (i2, _dt_x_roa) = parser(i1).map_err(Err::convert)?; let (i2, _dt_x_roa) = parser(i1).map_err(Err::convert)?;
@ -727,10 +743,11 @@ fn parse_mcs_connect(input: &[u8]) -> IResult<&[u8], McsConnectRequest, RdpError
let (i1, _ber_type) = verify( let (i1, _ber_type) = verify(
le_u8, le_u8,
// BER: 0b01=application, 0b1=non-primitive, 0b11111 // BER: 0b01=application, 0b1=non-primitive, 0b11111
|&x| x == 0x7f |&x| x == 0x7f,
).parse(input)?; )
let (i2, _t125_type) = verify(le_u8, |&x| x .parse(input)?;
== T125Type::T125TypeMcsConnectRequest as u8).parse(i1)?; let (i2, _t125_type) =
verify(le_u8, |&x| x == T125Type::T125TypeMcsConnectRequest as u8).parse(i1)?;
// skip to, and consume, H.221 client-to-server key // skip to, and consume, H.221 client-to-server key
let (i3, _skipped) = take_until_and_consume(b"Duca")(i2)?; let (i3, _skipped) = take_until_and_consume(b"Duca")(i2)?;
@ -768,9 +785,7 @@ fn parse_mcs_connect(input: &[u8]) -> IResult<&[u8], McsConnectRequest, RdpError
break; break;
} }
}, },
Err(Err::Incomplete(i)) => { Err(Err::Incomplete(i)) => return Err(Err::Incomplete(i)),
return Err(Err::Incomplete(i))
}
Err(Err::Failure(_)) | Err(Err::Error(_)) => break, Err(Err::Failure(_)) | Err(Err::Error(_)) => break,
} }
} }
@ -838,7 +853,8 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> {
let (j16, high_color_depth) = match serial_number { let (j16, high_color_depth) = match serial_number {
None => (j15, None), None => (j15, None),
Some(_) => { Some(_) => {
match opt(map_opt(le_u16, num::FromPrimitive::from_u16)).parse(j15) as IResult<&[u8], _> { match opt(map_opt(le_u16, num::FromPrimitive::from_u16)).parse(j15) as IResult<&[u8], _>
{
Ok((rem, obj)) => (rem, obj), Ok((rem, obj)) => (rem, obj),
_ => (j15, None), _ => (j15, None),
} }
@ -848,7 +864,9 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> {
let (j17, supported_color_depth) = match high_color_depth { let (j17, supported_color_depth) = match high_color_depth {
None => (j16, None), None => (j16, None),
Some(_) => { Some(_) => {
match opt(map_opt(le_u16, SupportedColorDepth::from_bits)).parse(j16) as IResult<&[u8], _> { match opt(map_opt(le_u16, SupportedColorDepth::from_bits)).parse(j16)
as IResult<&[u8], _>
{
Ok((rem, obj)) => (rem, obj), Ok((rem, obj)) => (rem, obj),
_ => (j16, None), _ => (j16, None),
} }
@ -858,7 +876,8 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> {
let (j18, early_capability_flags) = match supported_color_depth { let (j18, early_capability_flags) = match supported_color_depth {
None => (j17, None), None => (j17, None),
Some(_) => { Some(_) => {
match opt(map_opt(le_u16, EarlyCapabilityFlags::from_bits)).parse(j17) as IResult<&[u8], _> match opt(map_opt(le_u16, EarlyCapabilityFlags::from_bits)).parse(j17)
as IResult<&[u8], _>
{ {
Ok((rem, obj)) => (rem, obj), Ok((rem, obj)) => (rem, obj),
_ => (j17, None), _ => (j17, None),
@ -923,7 +942,8 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> {
let (j25, desktop_orientation) = match desktop_physical_height { let (j25, desktop_orientation) = match desktop_physical_height {
None => (j24, None), None => (j24, None),
Some(_) => { Some(_) => {
match opt(map_opt(le_u16, num::FromPrimitive::from_u16)).parse(j24) as IResult<&[u8], _> { match opt(map_opt(le_u16, num::FromPrimitive::from_u16)).parse(j24) as IResult<&[u8], _>
{
Ok((rem, obj)) => (rem, obj), Ok((rem, obj)) => (rem, obj),
_ => (j24, None), _ => (j24, None),
} }
@ -932,7 +952,8 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> {
let (j26, desktop_scale_factor) = match desktop_orientation { let (j26, desktop_scale_factor) = match desktop_orientation {
None => (j25, None), None => (j25, None),
Some(_) => match opt(map_opt(le_u32, desktop_scale_to_opt)).parse(j25) as IResult<&[u8], _> { Some(_) => match opt(map_opt(le_u32, desktop_scale_to_opt)).parse(j25) as IResult<&[u8], _>
{
Ok((rem, obj)) => (rem, obj), Ok((rem, obj)) => (rem, obj),
_ => (j25, None), _ => (j25, None),
}, },
@ -940,10 +961,12 @@ fn parse_cs_client_core_data(input: &[u8]) -> IResult<&[u8], CsClientCoreData> {
let (_j27, device_scale_factor) = match desktop_scale_factor { let (_j27, device_scale_factor) = match desktop_scale_factor {
None => (j26, None), None => (j26, None),
Some(_) => match opt(map_opt(le_u32, device_scale_to_opt)).parse(j26) as IResult<&[u8], _> { Some(_) => {
Ok((rem, obj)) => (rem, obj), match opt(map_opt(le_u32, device_scale_to_opt)).parse(j26) as IResult<&[u8], _> {
_ => (j26, None), Ok((rem, obj)) => (rem, obj),
}, _ => (j26, None),
}
}
}; };
return Ok(( return Ok((
@ -1012,11 +1035,18 @@ fn parse_cs_unknown(i: &[u8]) -> IResult<&[u8], CsUnknown> {
Some(_) => None, Some(_) => None,
None => Some(x), None => Some(x),
} }
}).parse(i)?; })
.parse(i)?;
// less u16, u16 // less u16, u16
let (i, sz) = map_opt(le_u16, |x: u16| x.checked_sub(4)).parse(i)?; let (i, sz) = map_opt(le_u16, |x: u16| x.checked_sub(4)).parse(i)?;
let (i, data) = take(sz).parse(i)?; let (i, data) = take(sz).parse(i)?;
Ok((i, CsUnknown { typ, data: data.to_vec() })) Ok((
i,
CsUnknown {
typ,
data: data.to_vec(),
},
))
} }
// rdp-spec, section 2.2.1.4 // rdp-spec, section 2.2.1.4
@ -1024,8 +1054,11 @@ fn parse_mcs_connect_response(i: &[u8]) -> IResult<&[u8], McsConnectResponse, Rd
let (i, _ber_type) = verify( let (i, _ber_type) = verify(
le_u8, le_u8,
// BER: 0b01=application, 0b1=non-primitive, 0b11111 // BER: 0b01=application, 0b1=non-primitive, 0b11111
|&x| x == 0x7f).parse(i)?; |&x| x == 0x7f,
let (i, _t125_type) = verify(le_u8, |&x| x == T125Type::T125TypeMcsConnectResponse as u8).parse(i)?; )
.parse(i)?;
let (i, _t125_type) =
verify(le_u8, |&x| x == T125Type::T125TypeMcsConnectResponse as u8).parse(i)?;
Ok((i, McsConnectResponse {})) Ok((i, McsConnectResponse {}))
} }
@ -1089,7 +1122,9 @@ mod tests_negotiate_49350 {
cookie: None, cookie: None,
negotiation_request: Some(NegotiationRequest { negotiation_request: Some(NegotiationRequest {
flags: NegotiationRequestFlags::empty(), flags: NegotiationRequestFlags::empty(),
protocols: ProtocolFlags { bits: Protocol::ProtocolRdp as u32 }, protocols: ProtocolFlags {
bits: Protocol::ProtocolRdp as u32,
},
}), }),
data: Vec::new(), data: Vec::new(),
}), }),
@ -1179,7 +1214,9 @@ mod tests_core_49350 {
), ),
client_dig_product_id: Some(String::from("")), client_dig_product_id: Some(String::from("")),
connection_hint: Some(ConnectionHint::ConnectionHintNotProvided), connection_hint: Some(ConnectionHint::ConnectionHintNotProvided),
server_selected_protocol: Some(ProtocolFlags { bits: Protocol::ProtocolRdp as u32 }), server_selected_protocol: Some(ProtocolFlags {
bits: Protocol::ProtocolRdp as u32,
}),
desktop_physical_width: None, desktop_physical_width: None,
desktop_physical_height: None, desktop_physical_height: None,
desktop_orientation: None, desktop_orientation: None,
@ -1196,7 +1233,12 @@ mod tests_core_49350 {
typ: 0xc002, typ: 0xc002,
data: BYTES[0x16c..0x16c + 0x8].to_vec(), data: BYTES[0x16c..0x16c + 0x8].to_vec(),
})); }));
let channels = vec![String::from("rdpdr"), String::from("rdpsnd"), String::from("drdynvc"), String::from("cliprdr")]; let channels = vec![
String::from("rdpdr"),
String::from("rdpsnd"),
String::from("drdynvc"),
String::from("cliprdr"),
];
children.push(McsConnectRequestChild::CsNet(CsNet { channels })); children.push(McsConnectRequestChild::CsNet(CsNet { channels }));
let t123_tpkt: T123Tpkt = T123Tpkt { let t123_tpkt: T123Tpkt = T123Tpkt {
child: T123TpktChild::Data(X223Data { child: T123TpktChild::Data(X223Data {
@ -1346,7 +1388,7 @@ mod tests_negotiate_incomplete_49350 {
assert_eq!( assert_eq!(
// fails: expr_opt!(i5, length.checked_sub(6))? // fails: expr_opt!(i5, length.checked_sub(6))?
// not counting a u8 length read, which was also successful // not counting a u8 length read, which was also successful
Err(Err::Incomplete(Needed::new( 1))), Err(Err::Incomplete(Needed::new(1))),
parse_x224_connection_request_class_0(x224_bytes) parse_x224_connection_request_class_0(x224_bytes)
) )
} }

@ -609,7 +609,10 @@ mod tests {
fn test_parse_ts_other() { fn test_parse_ts_other() {
let buf: &[u8] = &[0x03, 0x00, 0x00, 0x01, 0x00]; let buf: &[u8] = &[0x03, 0x00, 0x00, 0x01, 0x00];
let mut state = RdpState::new(); let mut state = RdpState::new();
assert_eq!(AppLayerResult::err(), state.parse_ts(std::ptr::null_mut(), buf)); assert_eq!(
AppLayerResult::err(),
state.parse_ts(std::ptr::null_mut(), buf)
);
} }
#[test] #[test]
@ -637,7 +640,10 @@ mod tests {
fn test_parse_tc_other() { fn test_parse_tc_other() {
let buf: &[u8] = &[0x03, 0x00, 0x00, 0x01, 0x00]; let buf: &[u8] = &[0x03, 0x00, 0x00, 0x01, 0x00];
let mut state = RdpState::new(); let mut state = RdpState::new();
assert_eq!(AppLayerResult::err(), state.parse_tc(std::ptr::null_mut(), buf)); assert_eq!(
AppLayerResult::err(),
state.parse_tc(std::ptr::null_mut(), buf)
);
} }
#[test] #[test]

@ -39,4 +39,4 @@ rustfmt --check rust/src/dns/*.rs rust/src/applayertemplate/*.rs rust/src/asn1/*
rust/src/rfb/*.rs rust/src/ssh/*.rs rust/src/utils/*.rs rust/src/websocket/*.rs \ rust/src/rfb/*.rs rust/src/ssh/*.rs rust/src/utils/*.rs rust/src/websocket/*.rs \
rust/src/dhcp/*.rs rust/src/krb/*.rs rust/src/mdns/*.rs rust/src/pop3/*.rs \ rust/src/dhcp/*.rs rust/src/krb/*.rs rust/src/mdns/*.rs rust/src/pop3/*.rs \
rust/src/http2/*.rs rust/src/ike/*.rs rust/src/modbus/*.rs rust/src/mqtt/*.rs \ rust/src/http2/*.rs rust/src/ike/*.rs rust/src/modbus/*.rs rust/src/mqtt/*.rs \
rust/src/nfs/*.rs rust/src/pgsql/*.rs rust/src/nfs/*.rs rust/src/pgsql/*.rs rust/src/rdp/*.rs

Loading…
Cancel
Save