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}