ironrdp_pdu/
rdp.rs

1use std::io;
2
3use ironrdp_core::{
4    ensure_fixed_part_size, invalid_field_err, Decode, DecodeResult, Encode, EncodeResult, ReadCursor, WriteCursor,
5};
6use thiserror::Error;
7
8use crate::input::InputEventError;
9use crate::rdp::capability_sets::CapabilitySetsError;
10use crate::rdp::client_info::{ClientInfo, ClientInfoError};
11use crate::rdp::headers::{BasicSecurityHeader, BasicSecurityHeaderFlags, ShareControlPduType, ShareDataPduType};
12use crate::rdp::server_license::ServerLicenseError;
13use crate::PduError;
14
15pub mod capability_sets;
16pub mod client_info;
17pub mod finalization_messages;
18pub mod headers;
19pub mod refresh_rectangle;
20pub mod server_error_info;
21pub mod server_license;
22pub mod session_info;
23pub mod suppress_output;
24pub mod vc;
25
26#[derive(Debug, Clone, PartialEq, Eq)]
27pub struct ClientInfoPdu {
28    pub security_header: BasicSecurityHeader,
29    pub client_info: ClientInfo,
30}
31
32impl ClientInfoPdu {
33    const NAME: &'static str = "ClientInfoPDU";
34
35    const FIXED_PART_SIZE: usize = BasicSecurityHeader::FIXED_PART_SIZE + ClientInfo::FIXED_PART_SIZE;
36}
37
38impl Encode for ClientInfoPdu {
39    fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
40        ensure_fixed_part_size!(in: dst);
41
42        self.security_header.encode(dst)?;
43        self.client_info.encode(dst)?;
44
45        Ok(())
46    }
47
48    fn name(&self) -> &'static str {
49        Self::NAME
50    }
51
52    fn size(&self) -> usize {
53        self.security_header.size() + self.client_info.size()
54    }
55}
56
57impl<'de> Decode<'de> for ClientInfoPdu {
58    fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
59        ensure_fixed_part_size!(in: src);
60
61        let security_header = BasicSecurityHeader::decode(src)?;
62        if !security_header.flags.contains(BasicSecurityHeaderFlags::INFO_PKT) {
63            return Err(invalid_field_err!("securityHeader", "got invalid security header"));
64        }
65
66        let client_info = ClientInfo::decode(src)?;
67
68        Ok(Self {
69            security_header,
70            client_info,
71        })
72    }
73}
74
75#[derive(Debug, Error)]
76pub enum RdpError {
77    #[error("IO error")]
78    IOError(#[from] io::Error),
79    #[error("client Info PDU error")]
80    ClientInfoError(#[from] ClientInfoError),
81    #[error("server License PDU error")]
82    ServerLicenseError(#[from] ServerLicenseError),
83    #[error("capability sets error")]
84    CapabilitySetsError(#[from] CapabilitySetsError),
85    #[error("invalid RDP security header")]
86    InvalidSecurityHeader,
87    #[error("invalid RDP Share Control Header: {0}")]
88    InvalidShareControlHeader(String),
89    #[error("invalid RDP Share Data Header: {0}")]
90    InvalidShareDataHeader(String),
91    #[error("invalid RDP Connection Sequence PDU")]
92    InvalidPdu(String),
93    #[error("unexpected RDP Share Control Header PDU type: {0:?}")]
94    UnexpectedShareControlPdu(ShareControlPduType),
95    #[error("unexpected RDP Share Data Header PDU type: {0:?}")]
96    UnexpectedShareDataPdu(ShareDataPduType),
97    #[error("save session info PDU error")]
98    SaveSessionInfoError(#[from] session_info::SessionError),
99    #[error("input event PDU error")]
100    InputEventError(#[from] InputEventError),
101    #[error("not enough bytes")]
102    NotEnoughBytes,
103    #[error("PDU error: {0}")]
104    Pdu(PduError),
105}
106
107impl From<PduError> for RdpError {
108    fn from(e: PduError) -> Self {
109        Self::Pdu(e)
110    }
111}
112
113impl From<RdpError> for io::Error {
114    fn from(e: RdpError) -> io::Error {
115        io::Error::other(format!("RDP Connection Sequence error: {e}"))
116    }
117}