1use std::io;
2
3use ironrdp_core::{
4 cast_length, decode, ensure_fixed_part_size, ensure_size, invalid_field_err, Decode, DecodeErrorKind, DecodeResult,
5 Encode, EncodeResult, ReadCursor, WriteCursor,
6};
7use num_derive::{FromPrimitive, ToPrimitive};
8use num_traits::{FromPrimitive, ToPrimitive};
9use thiserror::Error;
10
11use crate::PduError;
12
13pub mod conference_create;
14
15mod cluster_data;
16mod core_data;
17mod message_channel_data;
18mod monitor_data;
19mod monitor_extended_data;
20mod multi_transport_channel_data;
21mod network_data;
22mod security_data;
23
24pub use self::cluster_data::{ClientClusterData, ClusterDataError, RedirectionFlags, RedirectionVersion};
25pub use self::conference_create::{ConferenceCreateRequest, ConferenceCreateResponse};
26pub use self::core_data::client::{
27 ClientColorDepth, ClientCoreData, ClientCoreOptionalData, ClientEarlyCapabilityFlags, ColorDepth, ConnectionType,
28 HighColorDepth, KeyboardType, SecureAccessSequence, SupportedColorDepths, IME_FILE_NAME_SIZE,
29};
30pub use self::core_data::server::{ServerCoreData, ServerCoreOptionalData, ServerEarlyCapabilityFlags};
31pub use self::core_data::{CoreDataError, RdpVersion};
32pub use self::message_channel_data::{ClientMessageChannelData, ServerMessageChannelData};
33pub use self::monitor_data::{
34 ClientMonitorData, Monitor, MonitorFlags, MONITOR_COUNT_SIZE, MONITOR_FLAGS_SIZE, MONITOR_SIZE,
35};
36pub use self::monitor_extended_data::{ClientMonitorExtendedData, ExtendedMonitorInfo, MonitorOrientation};
37pub use self::multi_transport_channel_data::{MultiTransportChannelData, MultiTransportFlags};
38pub use self::network_data::{
39 ChannelDef, ChannelName, ChannelOptions, ClientNetworkData, NetworkDataError, ServerNetworkData,
40};
41pub use self::security_data::{
42 ClientSecurityData, EncryptionLevel, EncryptionMethod, SecurityDataError, ServerSecurityData,
43};
44
45macro_rules! user_header_try {
46 ($e:expr) => {
47 match $e {
48 Ok(user_header) => user_header,
49 Err(e) if matches!(e.kind(), DecodeErrorKind::NotEnoughBytes { .. }) => break,
50 Err(e) => return Err(e),
51 }
52 };
53}
54
55const USER_DATA_HEADER_SIZE: usize = 4;
56
57#[derive(Debug, Clone, PartialEq, Eq)]
61pub struct ClientGccBlocks {
62 pub core: ClientCoreData,
63 pub security: ClientSecurityData,
64 pub network: Option<ClientNetworkData>,
70 pub cluster: Option<ClientClusterData>,
71 pub monitor: Option<ClientMonitorData>,
72 pub message_channel: Option<ClientMessageChannelData>,
73 pub multi_transport_channel: Option<MultiTransportChannelData>,
74 pub monitor_extended: Option<ClientMonitorExtendedData>,
75}
76
77impl ClientGccBlocks {
78 const NAME: &'static str = "ClientGccBlocks";
79
80 pub fn channel_names(&self) -> Option<Vec<ChannelDef>> {
81 self.network.as_ref().map(|network| network.channels.clone())
82 }
83}
84
85impl Encode for ClientGccBlocks {
86 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
87 ensure_size!(in: dst, size: self.size());
88
89 UserDataHeader::encode(dst, ClientGccType::CoreData, &self.core)?;
90 UserDataHeader::encode(dst, ClientGccType::SecurityData, &self.security)?;
91
92 if let Some(ref network) = self.network {
93 UserDataHeader::encode(dst, ClientGccType::NetworkData, network)?;
94 }
95 if let Some(ref cluster) = self.cluster {
96 UserDataHeader::encode(dst, ClientGccType::ClusterData, cluster)?;
97 }
98 if let Some(ref monitor) = self.monitor {
99 UserDataHeader::encode(dst, ClientGccType::MonitorData, monitor)?;
100 }
101 if let Some(ref message_channel) = self.message_channel {
102 UserDataHeader::encode(dst, ClientGccType::MessageChannelData, message_channel)?;
103 }
104 if let Some(ref multi_transport_channel) = self.multi_transport_channel {
105 UserDataHeader::encode(dst, ClientGccType::MultiTransportChannelData, multi_transport_channel)?;
106 }
107 if let Some(ref monitor_extended) = self.monitor_extended {
108 UserDataHeader::encode(dst, ClientGccType::MonitorExtendedData, monitor_extended)?;
109 }
110
111 Ok(())
112 }
113
114 fn name(&self) -> &'static str {
115 Self::NAME
116 }
117
118 fn size(&self) -> usize {
119 let mut size = self.core.size() + self.security.size() + USER_DATA_HEADER_SIZE * 2;
120
121 if let Some(ref network) = self.network {
122 size += network.size() + USER_DATA_HEADER_SIZE;
123 }
124 if let Some(ref cluster) = self.cluster {
125 size += cluster.size() + USER_DATA_HEADER_SIZE;
126 }
127 if let Some(ref monitor) = self.monitor {
128 size += monitor.size() + USER_DATA_HEADER_SIZE;
129 }
130 if let Some(ref message_channel) = self.message_channel {
131 size += message_channel.size() + USER_DATA_HEADER_SIZE;
132 }
133 if let Some(ref multi_transport_channel) = self.multi_transport_channel {
134 size += multi_transport_channel.size() + USER_DATA_HEADER_SIZE;
135 }
136 if let Some(ref monitor_extended) = self.monitor_extended {
137 size += monitor_extended.size() + USER_DATA_HEADER_SIZE;
138 }
139
140 size
141 }
142}
143
144impl<'de> Decode<'de> for ClientGccBlocks {
145 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
146 let mut core = None;
147 let mut security = None;
148 let mut network = None;
149 let mut cluster = None;
150 let mut monitor = None;
151 let mut message_channel = None;
152 let mut multi_transport_channel = None;
153 let mut monitor_extended = None;
154
155 loop {
156 let (ty, cur) = user_header_try!(UserDataHeader::decode(src));
157
158 match ty {
159 ClientGccType::CoreData => core = Some(decode(cur)?),
160 ClientGccType::SecurityData => security = Some(decode(cur)?),
161 ClientGccType::NetworkData => network = Some(decode(cur)?),
162 ClientGccType::ClusterData => cluster = Some(decode(cur)?),
163 ClientGccType::MonitorData => monitor = Some(decode(cur)?),
164 ClientGccType::MessageChannelData => message_channel = Some(decode(cur)?),
165 ClientGccType::MonitorExtendedData => monitor_extended = Some(decode(cur)?),
166 ClientGccType::MultiTransportChannelData => multi_transport_channel = Some(decode(cur)?),
167 };
168 }
169
170 Ok(Self {
171 core: core.ok_or_else(|| invalid_field_err!("core", "required GCC core is absent"))?,
172 security: security.ok_or_else(|| invalid_field_err!("security", "required GCC security is absent"))?,
173 network,
174 cluster,
175 monitor,
176 message_channel,
177 multi_transport_channel,
178 monitor_extended,
179 })
180 }
181}
182
183#[derive(Debug, Clone, PartialEq, Eq)]
184pub struct ServerGccBlocks {
185 pub core: ServerCoreData,
186 pub network: ServerNetworkData,
187 pub security: ServerSecurityData,
188 pub message_channel: Option<ServerMessageChannelData>,
189 pub multi_transport_channel: Option<MultiTransportChannelData>,
190}
191
192impl ServerGccBlocks {
193 const NAME: &'static str = "ServerGccBlocks";
194
195 pub fn channel_ids(&self) -> Vec<u16> {
196 self.network.channel_ids.clone()
197 }
198 pub fn global_channel_id(&self) -> u16 {
199 self.network.io_channel
200 }
201}
202
203impl Encode for ServerGccBlocks {
204 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
205 UserDataHeader::encode(dst, ServerGccType::CoreData, &self.core)?;
206 UserDataHeader::encode(dst, ServerGccType::NetworkData, &self.network)?;
207 UserDataHeader::encode(dst, ServerGccType::SecurityData, &self.security)?;
208
209 if let Some(ref message_channel) = self.message_channel {
210 UserDataHeader::encode(dst, ServerGccType::MessageChannelData, message_channel)?;
211 }
212 if let Some(ref multi_transport_channel) = self.multi_transport_channel {
213 UserDataHeader::encode(dst, ServerGccType::MultiTransportChannelData, multi_transport_channel)?;
214 }
215
216 Ok(())
217 }
218
219 fn name(&self) -> &'static str {
220 Self::NAME
221 }
222
223 fn size(&self) -> usize {
224 let mut size = self.core.size() + self.network.size() + self.security.size() + USER_DATA_HEADER_SIZE * 3;
225
226 if let Some(ref message_channel) = self.message_channel {
227 size += message_channel.size() + USER_DATA_HEADER_SIZE;
228 }
229 if let Some(ref multi_transport_channel) = self.multi_transport_channel {
230 size += multi_transport_channel.size() + USER_DATA_HEADER_SIZE;
231 }
232
233 size
234 }
235}
236
237impl<'de> Decode<'de> for ServerGccBlocks {
238 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
239 let mut core = None;
240 let mut network = None;
241 let mut security = None;
242 let mut message_channel = None;
243 let mut multi_transport_channel = None;
244
245 loop {
246 let (ty, cur) = user_header_try!(UserDataHeader::decode(src));
247
248 match ty {
249 ServerGccType::CoreData => core = Some(decode(cur)?),
250 ServerGccType::NetworkData => network = Some(decode(cur)?),
251 ServerGccType::SecurityData => security = Some(decode(cur)?),
252 ServerGccType::MessageChannelData => message_channel = Some(decode(cur)?),
253 ServerGccType::MultiTransportChannelData => multi_transport_channel = Some(decode(cur)?),
254 };
255 }
256
257 Ok(Self {
258 core: core.ok_or_else(|| invalid_field_err!("core", "required GCC core is absent"))?,
259 network: network.ok_or_else(|| invalid_field_err!("network", "required GCC network is absent"))?,
260 security: security.ok_or_else(|| invalid_field_err!("security", "required GCC security is absent"))?,
261 message_channel,
262 multi_transport_channel,
263 })
264 }
265}
266
267#[repr(u16)]
268#[derive(Debug, Copy, Clone, FromPrimitive, ToPrimitive)]
269pub enum ClientGccType {
270 CoreData = 0xC001,
271 SecurityData = 0xC002,
272 NetworkData = 0xC003,
273 ClusterData = 0xC004,
274 MonitorData = 0xC005,
275 MessageChannelData = 0xC006,
276 MonitorExtendedData = 0xC008,
277 MultiTransportChannelData = 0xC00A,
278}
279
280#[repr(u16)]
281#[derive(Debug, Copy, Clone, FromPrimitive, ToPrimitive)]
282pub enum ServerGccType {
283 CoreData = 0x0C01,
284 SecurityData = 0x0C02,
285 NetworkData = 0x0C03,
286 MessageChannelData = 0x0C04,
287 MultiTransportChannelData = 0x0C08,
288}
289
290#[derive(Debug)]
291pub struct UserDataHeader;
292
293impl UserDataHeader {
294 const FIXED_PART_SIZE: usize = 2 + 2 ;
295
296 pub fn encode<T, B>(dst: &mut WriteCursor<'_>, block_type: T, block: &B) -> EncodeResult<()>
297 where
298 T: ToPrimitive,
299 B: Encode,
300 {
301 ensure_fixed_part_size!(in: dst);
302
303 dst.write_u16(block_type.to_u16().unwrap());
304 dst.write_u16(cast_length!("blockLen", block.size() + USER_DATA_HEADER_SIZE)?);
305 block.encode(dst)?;
306
307 Ok(())
308 }
309
310 pub fn decode<'de, T>(src: &mut ReadCursor<'de>) -> DecodeResult<(T, &'de [u8])>
311 where
312 T: FromPrimitive,
313 {
314 ensure_fixed_part_size!(in: src);
315
316 let block_type =
317 T::from_u16(src.read_u16()).ok_or_else(|| invalid_field_err!("blockType", "invalid GCC type"))?;
318 let block_length: usize = cast_length!("blockLen", src.read_u16())?;
319
320 if block_length <= USER_DATA_HEADER_SIZE {
321 return Err(invalid_field_err!("blockLen", "invalid UserDataHeader length"));
322 }
323
324 let len = block_length - USER_DATA_HEADER_SIZE;
325 ensure_size!(in: src, size: len);
326
327 Ok((block_type, src.read_slice(len)))
328 }
329}
330
331#[derive(Debug, Error)]
332pub enum GccError {
333 #[error("IO error")]
334 IOError(#[from] io::Error),
335 #[error("core data block error")]
336 CoreError(#[from] CoreDataError),
337 #[error("security data block error")]
338 SecurityError(#[from] SecurityDataError),
339 #[error("network data block error")]
340 NetworkError(#[from] NetworkDataError),
341 #[error("cluster data block error")]
342 ClusterError(#[from] ClusterDataError),
343 #[error("invalid GCC block type")]
344 InvalidGccType,
345 #[error("invalid conference create request: {0}")]
346 InvalidConferenceCreateRequest(String),
347 #[error("invalid Conference create response: {0}")]
348 InvalidConferenceCreateResponse(String),
349 #[error("a server did not send the required GCC data block: {0:?}")]
350 RequiredClientDataBlockIsAbsent(ClientGccType),
351 #[error("a client did not send the required GCC data block: {0:?}")]
352 RequiredServerDataBlockIsAbsent(ServerGccType),
353 #[error("PDU error: {0}")]
354 Pdu(PduError),
355}
356
357impl From<PduError> for GccError {
358 fn from(e: PduError) -> Self {
359 Self::Pdu(e)
360 }
361}