1use model::data::{Component, U32, U16, Trame, to_vec, Message, DataType, DynOption, MessageOption, Check, Array};
2use model::unicode::Unicode;
3use model::error::{RdpResult, RdpError, RdpErrorKind, Error};
4use core::per;
5use std::io::{Cursor, Read};
6use std::collections::HashMap;
7
8
9const T124_02_98_OID: [u8; 6] = [ 0, 0, 20, 124, 0, 1 ];
10const H221_CS_KEY: [u8; 4] = *b"Duca";
11const H221_SC_KEY: [u8; 4] = *b"McDn";
12#[repr(u32)]
15#[allow(dead_code)]
16#[derive(Copy, Clone, Eq, PartialEq)]
17pub enum Version {
18 RdpVersion = 0x00080001,
19 RdpVersion5plus = 0x00080004,
20 Unknown
21}
22
23impl From<u32> for Version {
24 fn from(e: u32) -> Self {
25 match e {
26 0x00080001 => Version::RdpVersion5plus,
27 0x00080004 => Version::RdpVersion,
28 _ => Version::Unknown
29 }
30 }
31}
32
33#[repr(u16)]
37#[allow(dead_code)]
38enum ColorDepth {
39 RnsUdColor8BPP = 0xCA01,
40 RnsUdColor16BPP555 = 0xCA02,
41 RnsUdColor16BPP565 = 0xCA03,
42 RnsUdColor24BPP = 0xCA04
43}
44
45#[repr(u16)]
46enum Sequence {
47 RnsUdSasDel = 0xAA03
48}
49
50#[repr(u32)]
53#[derive(Copy, Clone)]
54pub enum KeyboardLayout {
55 Arabic = 0x00000401,
56 Bulgarian = 0x00000402,
57 ChineseUsKeyboard = 0x00000404,
58 Czech = 0x00000405,
59 Danish = 0x00000406,
60 German = 0x00000407,
61 Greek = 0x00000408,
62 US = 0x00000409,
63 Spanish = 0x0000040a,
64 Finnish = 0x0000040b,
65 French = 0x0000040c,
66 Hebrew = 0x0000040d,
67 Hungarian = 0x0000040e,
68 Icelandic = 0x0000040f,
69 Italian = 0x00000410,
70 Japanese = 0x00000411,
71 Korean = 0x00000412,
72 Dutch = 0x00000413,
73 Norwegian = 0x00000414
74}
75
76#[repr(u32)]
79#[allow(dead_code)]
80pub enum KeyboardType {
81 IbmPcXt83Key = 0x00000001,
82 Olivetti = 0x00000002,
83 IbmPcAt84Key = 0x00000003,
84 Ibm101102Keys = 0x00000004,
85 Nokia1050 = 0x00000005,
86 Nokia9140 = 0x00000006,
87 Japanese = 0x00000007
88}
89
90#[repr(u16)]
91#[allow(dead_code)]
92enum HighColor {
93 HighColor4BPP = 0x0004,
94 HighColor8BPP = 0x0008,
95 HighColor15BPP = 0x000f,
96 HighColor16BPP = 0x0010,
97 HighColor24BPP = 0x0018
98}
99
100
101#[repr(u16)]
104#[allow(dead_code)]
105enum Support {
106 RnsUd24BPPSupport = 0x0001,
107 RnsUd16BPPSupport = 0x0002,
108 RnsUd15BPPSupport = 0x0004,
109 RnsUd32BPPSupport = 0x0008
110}
111
112#[repr(u16)]
115#[allow(dead_code)]
116enum CapabilityFlag {
117 RnsUdCsSupportErrinfoPDU = 0x0001,
118 RnsUdCsWant32BPPSession = 0x0002,
119 RnsUdCsSupportStatusInfoPdu = 0x0004,
120 RnsUdCsStrongAsymmetricKeys = 0x0008,
121 RnsUdCsUnused = 0x0010,
122 RnsUdCsValidConnectionType = 0x0020,
123 RnsUdCsSupportMonitorLayoutPDU = 0x0040,
124 RnsUdCsSupportNetcharAutodetect = 0x0080,
125 RnsUdCsSupportDynvcGFXProtocol = 0x0100,
126 RnsUdCsSupportDynamicTimezone = 0x0200,
127 RnsUdCsSupportHeartbeatPDU = 0x0400
128}
129
130#[repr(u32)]
133#[allow(dead_code)]
134enum EncryptionMethod {
135 EncryptionFlag40bit = 0x00000001,
136 EncryptionFlag128bit = 0x00000002,
137 EncryptionFlag56bit = 0x00000008,
138 FipsEncryptionFlag = 0x00000010
139}
140
141#[allow(dead_code)]
144enum EncryptionLevel {
145 None = 0x00000000,
146 Low = 0x00000001,
147 ClientCompatible = 0x00000002,
148 High = 0x00000003,
149 Fips = 0x00000004
150}
151
152#[repr(u16)]
153#[derive(Eq, PartialEq, Hash)]
154pub enum MessageType {
155 ScCore = 0x0C01,
157 ScSecurity = 0x0C02,
158 ScNet = 0x0C03,
159 CsCore = 0xC001,
161 CsSecurity = 0xC002,
162 CsNet = 0xC003,
163 CsCluster = 0xC004,
164 CsMonitor = 0xC005,
165 Unknown = 0
166}
167
168impl From<u16> for MessageType {
169 fn from(e: u16) -> Self {
170 match e {
171 0x0C01 => MessageType::ScCore,
172 0x0C02 => MessageType::ScSecurity,
173 0x0C03 => MessageType::ScNet,
174 0xC001 => MessageType::CsCore,
175 0xC002 => MessageType::CsSecurity,
176 0xC003 => MessageType::CsNet,
177 0xC004 => MessageType::CsCluster,
178 0xC005 => MessageType::CsMonitor,
179 _ => MessageType::Unknown
180 }
181 }
182}
183
184#[derive(Clone)]
187pub struct ClientData {
188 pub width: u16,
189 pub height: u16,
190 pub layout: KeyboardLayout,
191 pub server_selected_protocol: u32,
192 pub rdp_version: Version,
193 pub name: String
194}
195
196pub fn client_core_data(parameter: Option<ClientData>) -> Component {
202 let client_parameter = parameter.unwrap_or(
203 ClientData {
204 width: 0,
205 height: 0,
206 layout: KeyboardLayout::French,
207 server_selected_protocol: 0,
208 rdp_version: Version::RdpVersion5plus,
209 name: "".to_string()
210 });
211
212 let client_name = if client_parameter.name.len() >= 16 {
213 (&client_parameter.name[0..16]).to_string()
214 } else {
215 client_parameter.name.clone() + &"\x00".repeat(16 - client_parameter.name.len())
216 };
217
218 component![
219 "version" => U32::LE(client_parameter.rdp_version as u32),
220 "desktopWidth" => U16::LE(client_parameter.width),
221 "desktopHeight" => U16::LE(client_parameter.height),
222 "colorDepth" => U16::LE(ColorDepth::RnsUdColor8BPP as u16),
223 "sasSequence" => U16::LE(Sequence::RnsUdSasDel as u16),
224 "kbdLayout" => U32::LE(client_parameter.layout as u32),
225 "clientBuild" => U32::LE(3790),
226 "clientName" => client_name.to_string().to_unicode(),
227 "keyboardType" => U32::LE(KeyboardType::Ibm101102Keys as u32),
228 "keyboardSubType" => U32::LE(0),
229 "keyboardFnKeys" => U32::LE(12),
230 "imeFileName" => vec![0 as u8; 64],
231 "postBeta2ColorDepth" => U16::LE(ColorDepth::RnsUdColor8BPP as u16),
232 "clientProductId" => U16::LE(1),
233 "serialNumber" => U32::LE(0),
234 "highColorDepth" => U16::LE(HighColor::HighColor24BPP as u16),
235 "supportedColorDepths" => U16::LE(
236 Support::RnsUd16BPPSupport as u16 |
238 Support::RnsUd32BPPSupport as u16
240 ),
241 "earlyCapabilityFlags" => U16::LE(CapabilityFlag::RnsUdCsSupportErrinfoPDU as u16),
242 "clientDigProductId" => vec![0; 64],
243 "connectionType" => 0 as u8,
244 "pad1octet" => 0 as u8,
245 "serverSelectedProtocol" => U32::LE(client_parameter.server_selected_protocol)
246 ]
247}
248
249pub fn server_core_data() -> Component{
250 component![
251 "rdpVersion" => U32::LE(0),
252 "clientRequestedProtocol" => Some(U32::LE(0)),
253 "earlyCapabilityFlags" => Some(U32::LE(0))
254 ]
255}
256
257pub fn client_security_data() -> Component {
260 component![
261 "encryptionMethods" => U32::LE(
262 EncryptionMethod::EncryptionFlag40bit as u32 |
263 EncryptionMethod::EncryptionFlag56bit as u32 |
264 EncryptionMethod::EncryptionFlag128bit as u32
265 ),
266 "extEncryptionMethods" => U32::LE(0)
267 ]
268}
269
270pub fn server_security_data() -> Component {
273 component![
274 "encryptionMethod" => U32::LE(0),
275 "encryptionLevel" => U32::LE(0)
276 ]
277}
278
279pub fn channel_def(name: &String, options: u32) -> Component {
281 component![
282 "name"=> name.as_bytes().to_vec(),
283 "options" => U32::LE(options)
284 ]
285}
286
287pub fn client_network_data(channel_def_array: Trame) -> Component {
289 component![
290 "channelCount" => U32::LE(channel_def_array.len() as u32),
291 "channelDefArray" => to_vec(&channel_def_array)
292 ]
293}
294
295pub fn server_network_data() -> Component {
296 component![
297 "MCSChannelId" => Check::new(U16::LE(1003)),
298 "channelCount" => DynOption::new(U16::LE(0), |count| MessageOption::Size("channelIdArray".to_string(), count.inner() as usize * 2)),
299 "channelIdArray" => Array::new(|| U16::LE(0))
300 ]
301}
302
303pub fn block_header(data_type: Option<MessageType>, length: Option<u16>) -> Component {
304 component![
305 "type" => U16::LE(data_type.unwrap_or(MessageType::CsCore) as u16),
306 "length" => U16::LE(length.unwrap_or(0) as u16 + 4)
307 ]
308}
309
310pub fn write_conference_create_request(user_data: &[u8]) ->RdpResult<Vec<u8>> {
311 let mut result = Cursor::new(vec![]);
312 per::write_choice(0, &mut result)?;
313 per::write_object_identifier(&T124_02_98_OID, &mut result)?;
314 per::write_length(user_data.len() as u16 + 14)?.write(&mut result)?;
315 per::write_choice(0, &mut result)?;
316 per::write_selection(0x08, &mut result)?;
317 per::write_numeric_string(b"1", 1, &mut result)?;
318 per::write_padding(1, &mut result)?;
319 per::write_number_of_set(1, &mut result)?;
320 per::write_choice(0xc0, &mut result)?;
321 per::write_octet_stream(&H221_CS_KEY, 4,&mut result)?;
322 per::write_octet_stream(user_data, 0, &mut result)?;
323 Ok(result.into_inner())
324}
325
326pub struct ServerData {
327 pub channel_ids: Vec<u16>,
328 pub rdp_version : Version
329}
330
331pub fn read_conference_create_response(cc_response: &mut dyn Read) -> RdpResult<ServerData> {
333 per::read_choice(cc_response)?;
334 per::read_object_identifier(&T124_02_98_OID, cc_response)?;
335 per::read_length(cc_response)?;
336 per::read_choice(cc_response)?;
337 per::read_integer_16(1001, cc_response)?;
338 per::read_integer(cc_response)?;
339 per::read_enumerates(cc_response)?;
340 per::read_number_of_set(cc_response)?;
341 per::read_choice(cc_response)?;
342 per::read_octet_stream(&H221_SC_KEY, 4, cc_response)?;
343
344 let length = per::read_length(cc_response)?;
345 let mut result = HashMap::new();
346 let mut sub = cc_response.take(length as u64);
347 loop {
348
349 let mut header = block_header(None, None);
350 if header.read(&mut sub).is_err() {
352 break;
353 }
354
355 let mut buffer = vec![0 as u8; (cast!(DataType::U16, header["length"])? - header.length() as u16) as usize];
356 sub.read_exact(&mut buffer)?;
357
358 match MessageType::from(cast!(DataType::U16, header["type"])?) {
359 MessageType::ScCore => {
360 let mut server_core = server_core_data();
361 server_core.read(&mut Cursor::new(buffer))?;
362 result.insert(MessageType::ScCore, server_core);
363 },
364 MessageType::ScSecurity => {
365 let mut server_security = server_security_data();
366 server_security.read(&mut Cursor::new(buffer))?;
367 result.insert(MessageType::ScSecurity, server_security);
368 },
369 MessageType::ScNet => {
370 let mut server_net = server_network_data();
371 server_net.read(&mut Cursor::new(buffer))?;
372 result.insert(MessageType::ScNet, server_net);
373 }
374 _ => println!("GCC: Unknown server block {:?}", cast!(DataType::U16, header["type"])?)
375 }
376 }
377
378 Ok(ServerData{
380 channel_ids: cast!(DataType::Trame, result[&MessageType::ScNet]["channelIdArray"])?.into_iter().map(|x| cast!(DataType::U16, x).unwrap()).collect(),
381 rdp_version: Version::from(cast!(DataType::U32, result[&MessageType::ScCore]["rdpVersion"])?)
382 })
383}