rust: format rdp files

Ticket: 3836
pull/15521/head
Philippe Antoine 1 month 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)> {
bits(
|i| (
bits(|i| {
(
verify(take_bits(4u8), |&x| x <= 4),
verify(take_bits(4u8), |&x| x <= 3),
).parse(i)
).parse(i)
)
.parse(i)
})
.parse(i)
}
/// 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, bytes) = take_until_and_consume(b"\r\n")(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 cookie = RdpCookie{ mstshash: String::from(s) };
let 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))
}
// rdp-spec, section 2.2.1.1.1
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)?;
// u8, u8, u16, and u32 give _length of 8
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)?;
// it will be one of a response message or a failure message
let opt1: Option<NegotiationFromServer> = match opt(parse_negotiation_response).parse(data) {
Ok((_remainder, opt)) => opt.map(NegotiationFromServer::Response),
Err(e) => return Err(e),
};
let opt1: Option<NegotiationFromServer> =
match opt(parse_negotiation_response).parse(data) {
Ok((_remainder, opt)) => opt.map(NegotiationFromServer::Response),
Err(e) => return Err(e),
};
let opt2: Option<NegotiationFromServer> = match opt1 {
Some(x) => Some(x),
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
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)?;
// u8, u8, u16, and u32 give _length of 8
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
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)?;
// u8, u8, u16, and u32 give _length of 8
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
fn parse_x223_data_class_0(input: &[u8]) -> IResult<&[u8], X223Data, RdpError> {
fn parser(i: &[u8]) -> IResult<&[u8], (u8, u8, u8)> {
bits(
|i| (
bits(|i| {
(
verify(take_bits(4u8), |&x| x == 0xf),
verify(take_bits(3u8), |&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 (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(
le_u8,
// BER: 0b01=application, 0b1=non-primitive, 0b11111
|&x| x == 0x7f
).parse(input)?;
let (i2, _t125_type) = verify(le_u8, |&x| x
== T125Type::T125TypeMcsConnectRequest as u8).parse(i1)?;
|&x| x == 0x7f,
)
.parse(input)?;
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
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;
}
},
Err(Err::Incomplete(i)) => {
return Err(Err::Incomplete(i))
}
Err(Err::Incomplete(i)) => return Err(Err::Incomplete(i)),
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 {
None => (j15, None),
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),
_ => (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 {
None => (j16, None),
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),
_ => (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 {
None => (j17, None),
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),
_ => (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 {
None => (j24, None),
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),
_ => (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 {
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),
_ => (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 {
None => (j26, None),
Some(_) => match opt(map_opt(le_u32, device_scale_to_opt)).parse(j26) as IResult<&[u8], _> {
Ok((rem, obj)) => (rem, obj),
_ => (j26, None),
},
Some(_) => {
match opt(map_opt(le_u32, device_scale_to_opt)).parse(j26) as IResult<&[u8], _> {
Ok((rem, obj)) => (rem, obj),
_ => (j26, None),
}
}
};
return Ok((
@ -1012,11 +1035,18 @@ fn parse_cs_unknown(i: &[u8]) -> IResult<&[u8], CsUnknown> {
Some(_) => None,
None => Some(x),
}
}).parse(i)?;
})
.parse(i)?;
// less u16, u16
let (i, sz) = map_opt(le_u16, |x: u16| x.checked_sub(4)).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
@ -1024,8 +1054,11 @@ fn parse_mcs_connect_response(i: &[u8]) -> IResult<&[u8], McsConnectResponse, Rd
let (i, _ber_type) = verify(
le_u8,
// BER: 0b01=application, 0b1=non-primitive, 0b11111
|&x| x == 0x7f).parse(i)?;
let (i, _t125_type) = verify(le_u8, |&x| x == T125Type::T125TypeMcsConnectResponse as u8).parse(i)?;
|&x| x == 0x7f,
)
.parse(i)?;
let (i, _t125_type) =
verify(le_u8, |&x| x == T125Type::T125TypeMcsConnectResponse as u8).parse(i)?;
Ok((i, McsConnectResponse {}))
}
@ -1089,7 +1122,9 @@ mod tests_negotiate_49350 {
cookie: None,
negotiation_request: Some(NegotiationRequest {
flags: NegotiationRequestFlags::empty(),
protocols: ProtocolFlags { bits: Protocol::ProtocolRdp as u32 },
protocols: ProtocolFlags {
bits: Protocol::ProtocolRdp as u32,
},
}),
data: Vec::new(),
}),
@ -1179,7 +1214,9 @@ mod tests_core_49350 {
),
client_dig_product_id: Some(String::from("")),
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_height: None,
desktop_orientation: None,
@ -1196,7 +1233,12 @@ mod tests_core_49350 {
typ: 0xc002,
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 }));
let t123_tpkt: T123Tpkt = T123Tpkt {
child: T123TpktChild::Data(X223Data {
@ -1346,7 +1388,7 @@ mod tests_negotiate_incomplete_49350 {
assert_eq!(
// fails: expr_opt!(i5, length.checked_sub(6))?
// 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)
)
}

@ -609,7 +609,10 @@ mod tests {
fn test_parse_ts_other() {
let buf: &[u8] = &[0x03, 0x00, 0x00, 0x01, 0x00];
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]
@ -637,7 +640,10 @@ mod tests {
fn test_parse_tc_other() {
let buf: &[u8] = &[0x03, 0x00, 0x00, 0x01, 0x00];
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]

@ -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/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/nfs/*.rs rust/src/pgsql/*.rs
rust/src/nfs/*.rs rust/src/pgsql/*.rs rust/src/rdp/*.rs

Loading…
Cancel
Save