ironrdp_pdu/
rdp.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
use std::io;

use ironrdp_core::{
    ensure_fixed_part_size, invalid_field_err, Decode, DecodeResult, Encode, EncodeResult, ReadCursor, WriteCursor,
};
use thiserror::Error;

use crate::input::InputEventError;
use crate::rdp::capability_sets::CapabilitySetsError;
use crate::rdp::client_info::{ClientInfo, ClientInfoError};
use crate::rdp::headers::{BasicSecurityHeader, BasicSecurityHeaderFlags, ShareControlPduType, ShareDataPduType};
use crate::rdp::server_license::ServerLicenseError;
use crate::PduError;

pub mod capability_sets;
pub mod client_info;
pub mod finalization_messages;
pub mod headers;
pub mod refresh_rectangle;
pub mod server_error_info;
pub mod server_license;
pub mod session_info;
pub mod suppress_output;
pub mod vc;

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ClientInfoPdu {
    pub security_header: BasicSecurityHeader,
    pub client_info: ClientInfo,
}

impl ClientInfoPdu {
    const NAME: &'static str = "ClientInfoPDU";

    const FIXED_PART_SIZE: usize = BasicSecurityHeader::FIXED_PART_SIZE + ClientInfo::FIXED_PART_SIZE;
}

impl Encode for ClientInfoPdu {
    fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
        ensure_fixed_part_size!(in: dst);

        self.security_header.encode(dst)?;
        self.client_info.encode(dst)?;

        Ok(())
    }

    fn name(&self) -> &'static str {
        Self::NAME
    }

    fn size(&self) -> usize {
        self.security_header.size() + self.client_info.size()
    }
}

impl<'de> Decode<'de> for ClientInfoPdu {
    fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
        ensure_fixed_part_size!(in: src);

        let security_header = BasicSecurityHeader::decode(src)?;
        if !security_header.flags.contains(BasicSecurityHeaderFlags::INFO_PKT) {
            return Err(invalid_field_err!("securityHeader", "got invalid security header"));
        }

        let client_info = ClientInfo::decode(src)?;

        Ok(Self {
            security_header,
            client_info,
        })
    }
}

#[derive(Debug, Error)]
pub enum RdpError {
    #[error("IO error")]
    IOError(#[from] io::Error),
    #[error("client Info PDU error")]
    ClientInfoError(#[from] ClientInfoError),
    #[error("server License PDU error")]
    ServerLicenseError(#[from] ServerLicenseError),
    #[error("capability sets error")]
    CapabilitySetsError(#[from] CapabilitySetsError),
    #[error("invalid RDP security header")]
    InvalidSecurityHeader,
    #[error("invalid RDP Share Control Header: {0}")]
    InvalidShareControlHeader(String),
    #[error("invalid RDP Share Data Header: {0}")]
    InvalidShareDataHeader(String),
    #[error("invalid RDP Connection Sequence PDU")]
    InvalidPdu(String),
    #[error("unexpected RDP Share Control Header PDU type: {0:?}")]
    UnexpectedShareControlPdu(ShareControlPduType),
    #[error("unexpected RDP Share Data Header PDU type: {0:?}")]
    UnexpectedShareDataPdu(ShareDataPduType),
    #[error("save session info PDU error")]
    SaveSessionInfoError(#[from] session_info::SessionError),
    #[error("input event PDU error")]
    InputEventError(#[from] InputEventError),
    #[error("not enough bytes")]
    NotEnoughBytes,
    #[error("PDU error: {0}")]
    Pdu(PduError),
}

impl From<PduError> for RdpError {
    fn from(e: PduError) -> Self {
        Self::Pdu(e)
    }
}

impl From<RdpError> for io::Error {
    fn from(e: RdpError) -> io::Error {
        io::Error::new(io::ErrorKind::Other, format!("RDP Connection Sequence error: {e}"))
    }
}