ironrdp_pdu/gcc/core_data/
server.rs

1use bitflags::bitflags;
2use ironrdp_core::{
3    ensure_fixed_part_size, ensure_size, invalid_field_err, Decode, DecodeResult, Encode, EncodeResult, ReadCursor,
4    WriteCursor,
5};
6use tap::Pipe as _;
7
8use super::RdpVersion;
9use crate::nego::SecurityProtocol;
10
11const CLIENT_REQUESTED_PROTOCOL_SIZE: usize = 4;
12const EARLY_CAPABILITY_FLAGS_SIZE: usize = 4;
13
14#[derive(Debug, Clone, PartialEq, Eq)]
15pub struct ServerCoreData {
16    pub version: RdpVersion,
17    pub optional_data: ServerCoreOptionalData,
18}
19
20impl ServerCoreData {
21    const NAME: &'static str = "ServerCoreData";
22
23    const FIXED_PART_SIZE: usize = 4 /* rdpVersion */;
24}
25
26impl Encode for ServerCoreData {
27    fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
28        ensure_size!(in: dst, size: self.size());
29
30        dst.write_u32(self.version.0);
31        self.optional_data.encode(dst)
32    }
33
34    fn name(&self) -> &'static str {
35        Self::NAME
36    }
37
38    fn size(&self) -> usize {
39        Self::FIXED_PART_SIZE + self.optional_data.size()
40    }
41}
42
43impl<'de> Decode<'de> for ServerCoreData {
44    fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
45        ensure_fixed_part_size!(in: src);
46
47        let version = src.read_u32().pipe(RdpVersion);
48        let optional_data = ServerCoreOptionalData::decode(src)?;
49
50        Ok(Self { version, optional_data })
51    }
52}
53
54#[derive(Debug, Clone, PartialEq, Eq, Default)]
55pub struct ServerCoreOptionalData {
56    pub client_requested_protocols: Option<SecurityProtocol>,
57    pub early_capability_flags: Option<ServerEarlyCapabilityFlags>,
58}
59
60impl ServerCoreOptionalData {
61    const NAME: &'static str = "ServerCoreOptionalData";
62}
63
64impl Encode for ServerCoreOptionalData {
65    fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
66        ensure_size!(in: dst, size: self.size());
67
68        if let Some(value) = self.client_requested_protocols {
69            dst.write_u32(value.bits());
70        };
71
72        if let Some(value) = self.early_capability_flags {
73            dst.write_u32(value.bits());
74        }
75
76        Ok(())
77    }
78
79    fn name(&self) -> &'static str {
80        Self::NAME
81    }
82
83    fn size(&self) -> usize {
84        let mut size = 0;
85
86        if self.client_requested_protocols.is_some() {
87            size += CLIENT_REQUESTED_PROTOCOL_SIZE;
88        }
89        if self.early_capability_flags.is_some() {
90            size += EARLY_CAPABILITY_FLAGS_SIZE;
91        }
92
93        size
94    }
95}
96
97macro_rules! try_or_return {
98    ($expr:expr, $ret:expr) => {
99        match $expr {
100            Ok(v) => v,
101            Err(_) => return Ok($ret),
102        }
103    };
104}
105
106impl<'de> Decode<'de> for ServerCoreOptionalData {
107    fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
108        let mut optional_data = Self::default();
109
110        optional_data.client_requested_protocols = Some(
111            SecurityProtocol::from_bits(try_or_return!(src.try_read_u32(), optional_data))
112                .ok_or_else(|| invalid_field_err!("clientReqProtocols", "invalid server security protocol"))?,
113        );
114
115        optional_data.early_capability_flags = Some(
116            ServerEarlyCapabilityFlags::from_bits(try_or_return!(src.try_read_u32(), optional_data))
117                .ok_or_else(|| invalid_field_err!("earlyCapFlags", "invalid early capability flags"))?,
118        );
119
120        Ok(optional_data)
121    }
122}
123
124bitflags! {
125    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
126    pub struct ServerEarlyCapabilityFlags: u32 {
127        const EDGE_ACTIONS_SUPPORTED_V1 = 0x0000_0001;
128        const DYNAMIC_DST_SUPPORTED = 0x0000_0002;
129        const EDGE_ACTIONS_SUPPORTED_V2 = 0x0000_0004;
130        const SKIP_CHANNELJOIN_SUPPORTED = 0x0000_0008;
131        // The source may set any bits
132        const _ = !0;
133    }
134}