mirror of
https://github.com/netbirdio/IronRDP.git
synced 2026-05-22 18:43:12 -07:00
refactor(pdu): return whether hint::find_size() matches the expected hint
When compiled in debug mode, the code checks the expected Action hint. But in release mode, no checks are done and the it will have to fail later. Instead, return whether the PDU is matching the hint, so the caller can decide what to do in this case. Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
committed by
Benoît Cortier
parent
d8f2d10558
commit
46b703e813
@@ -170,7 +170,7 @@ where
|
||||
.find_size(self.peek())
|
||||
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?
|
||||
{
|
||||
Some(length) => {
|
||||
Some((_matched, length)) => {
|
||||
return Ok(self.read_exact(length).await?.freeze());
|
||||
}
|
||||
None => {
|
||||
|
||||
@@ -93,7 +93,7 @@ where
|
||||
.find_size(self.peek())
|
||||
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?
|
||||
{
|
||||
Some(length) => {
|
||||
Some((_matched, length)) => {
|
||||
return Ok(self.read_exact(length)?.freeze());
|
||||
}
|
||||
None => {
|
||||
|
||||
@@ -43,9 +43,9 @@ struct CredsspTsRequestHint;
|
||||
const CREDSSP_TS_REQUEST_HINT: CredsspTsRequestHint = CredsspTsRequestHint;
|
||||
|
||||
impl PduHint for CredsspTsRequestHint {
|
||||
fn find_size(&self, bytes: &[u8]) -> ironrdp_pdu::PduResult<Option<usize>> {
|
||||
fn find_size(&self, bytes: &[u8]) -> ironrdp_pdu::PduResult<Option<(bool, usize)>> {
|
||||
match credssp::TsRequest::read_length(bytes) {
|
||||
Ok(length) => Ok(Some(length)),
|
||||
Ok(length) => Ok(Some((true, length))),
|
||||
Err(e) if e.kind() == std::io::ErrorKind::UnexpectedEof => Ok(None),
|
||||
Err(e) => Err(ironrdp_pdu::custom_err!("CredsspTsRequestHint", e)),
|
||||
}
|
||||
@@ -58,8 +58,8 @@ struct CredsspEarlyUserAuthResultHint;
|
||||
const CREDSSP_EARLY_USER_AUTH_RESULT_HINT: CredsspEarlyUserAuthResultHint = CredsspEarlyUserAuthResultHint;
|
||||
|
||||
impl PduHint for CredsspEarlyUserAuthResultHint {
|
||||
fn find_size(&self, _: &[u8]) -> ironrdp_pdu::PduResult<Option<usize>> {
|
||||
Ok(Some(credssp::EARLY_USER_AUTH_RESULT_PDU_SIZE))
|
||||
fn find_size(&self, _: &[u8]) -> ironrdp_pdu::PduResult<Option<(bool, usize)>> {
|
||||
Ok(Some((true, credssp::EARLY_USER_AUTH_RESULT_PDU_SIZE)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -333,7 +333,10 @@ pub fn find_size(bytes: &[u8]) -> PduResult<Option<PduInfo>> {
|
||||
|
||||
pub trait PduHint: Send + Sync + fmt::Debug + 'static {
|
||||
/// Finds next PDU size by reading the next few bytes.
|
||||
fn find_size(&self, bytes: &[u8]) -> PduResult<Option<usize>>;
|
||||
///
|
||||
/// Returns `Some((hint_matching, size))` if the size is known.
|
||||
/// Returns `None` if the size cannot be determined yet.
|
||||
fn find_size(&self, bytes: &[u8]) -> PduResult<Option<(bool, usize)>>;
|
||||
}
|
||||
|
||||
// Matches both X224 and FastPath pdus
|
||||
@@ -343,8 +346,8 @@ pub struct RdpHint;
|
||||
pub const RDP_HINT: RdpHint = RdpHint;
|
||||
|
||||
impl PduHint for RdpHint {
|
||||
fn find_size(&self, bytes: &[u8]) -> PduResult<Option<usize>> {
|
||||
find_size(bytes).map(|opt| opt.map(|info| info.length))
|
||||
fn find_size(&self, bytes: &[u8]) -> PduResult<Option<(bool, usize)>> {
|
||||
find_size(bytes).map(|opt| opt.map(|info| (true, info.length)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,11 +357,11 @@ pub struct X224Hint;
|
||||
pub const X224_HINT: X224Hint = X224Hint;
|
||||
|
||||
impl PduHint for X224Hint {
|
||||
fn find_size(&self, bytes: &[u8]) -> PduResult<Option<usize>> {
|
||||
fn find_size(&self, bytes: &[u8]) -> PduResult<Option<(bool, usize)>> {
|
||||
match find_size(bytes)? {
|
||||
Some(pdu_info) => {
|
||||
debug_assert_eq!(pdu_info.action, Action::X224);
|
||||
Ok(Some(pdu_info.length))
|
||||
let res = (pdu_info.action == Action::X224, pdu_info.length);
|
||||
Ok(Some(res))
|
||||
}
|
||||
None => Ok(None),
|
||||
}
|
||||
@@ -371,11 +374,11 @@ pub struct FastPathHint;
|
||||
pub const FAST_PATH_HINT: FastPathHint = FastPathHint;
|
||||
|
||||
impl PduHint for FastPathHint {
|
||||
fn find_size(&self, bytes: &[u8]) -> PduResult<Option<usize>> {
|
||||
fn find_size(&self, bytes: &[u8]) -> PduResult<Option<(bool, usize)>> {
|
||||
match find_size(bytes)? {
|
||||
Some(pdu_info) => {
|
||||
debug_assert_eq!(pdu_info.action, Action::FastPath);
|
||||
Ok(Some(pdu_info.length))
|
||||
let res = (pdu_info.action == Action::FastPath, pdu_info.length);
|
||||
Ok(Some(res))
|
||||
}
|
||||
None => Ok(None),
|
||||
}
|
||||
|
||||
@@ -894,9 +894,9 @@ where
|
||||
const RDCLEANPATH_HINT: RDCleanPathHint = RDCleanPathHint;
|
||||
|
||||
impl ironrdp::pdu::PduHint for RDCleanPathHint {
|
||||
fn find_size(&self, bytes: &[u8]) -> ironrdp::pdu::PduResult<Option<usize>> {
|
||||
fn find_size(&self, bytes: &[u8]) -> ironrdp::pdu::PduResult<Option<(bool, usize)>> {
|
||||
match ironrdp_rdcleanpath::RDCleanPathPdu::detect(bytes) {
|
||||
ironrdp_rdcleanpath::DetectionResult::Detected { total_length, .. } => Ok(Some(total_length)),
|
||||
ironrdp_rdcleanpath::DetectionResult::Detected { total_length, .. } => Ok(Some((true, total_length))),
|
||||
ironrdp_rdcleanpath::DetectionResult::NotEnoughBytes => Ok(None),
|
||||
ironrdp_rdcleanpath::DetectionResult::Failed => Err(ironrdp::pdu::other_err!(
|
||||
"RDCleanPathHint",
|
||||
|
||||
@@ -17,7 +17,7 @@ public partial struct PduHint
|
||||
private const string NativeLib = "DevolutionsIronRdp";
|
||||
|
||||
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "PduHint_find_size", ExactSpelling = true)]
|
||||
public static unsafe extern ConnectorFfiResultBoxOptionalUsizeBoxIronRdpError FindSize(PduHint* self, byte* bytes, nuint bytesSz);
|
||||
public static unsafe extern ConnectorFfiResultBoxOptionalUsizeBoxIronRdpError FindSize(PduHint* self, byte* bytes, nuint bytesSz, bool* matched);
|
||||
|
||||
[DllImport(NativeLib, CallingConvention = CallingConvention.Cdecl, EntryPoint = "PduHint_destroy", ExactSpelling = true)]
|
||||
public static unsafe extern void Destroy(PduHint* self);
|
||||
|
||||
@@ -160,7 +160,8 @@ pub mod ffi {
|
||||
impl<'a> PduHint<'a> {
|
||||
pub fn find_size(&'a self, bytes: &[u8]) -> Result<Box<crate::utils::ffi::OptionalUsize>, Box<IronRdpError>> {
|
||||
let pdu_hint = self.0;
|
||||
let size = pdu_hint.find_size(bytes)?;
|
||||
// TODO C# NuGet is only used on client-side so we probably don’t need to break the ABI for that just now.
|
||||
let size = pdu_hint.find_size(bytes)?.map(|(_match, size)| size);
|
||||
Ok(Box::new(crate::utils::ffi::OptionalUsize(size)))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user