EverydayTech Platform - Developer Reference
Complete Source Code Documentation - All Applications
Loading...
Searching...
No Matches
gcc.js
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014-2015 Sylvain Peyrefitte
3 *
4 * This file is part of node-rdpjs.
5 *
6 * node-rdpjs is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20var type = require('../../core').type;
21var log = require('../../core').log;
22var error = require('../../core').error;
23var per = require('./per');
24
25
26var t124_02_98_oid = [ 0, 0, 20, 124, 0, 1 ];
27var h221_cs_key = "Duca";
28var h221_sc_key = "McDn";
29
30
31/**
32 * @see http://msdn.microsoft.com/en-us/library/cc240509.aspx
33 */
34var MessageType = {
35 //server -> client
36 SC_CORE : 0x0C01,
37 SC_SECURITY : 0x0C02,
38 SC_NET : 0x0C03,
39 //client -> server
40 CS_CORE : 0xC001,
41 CS_SECURITY : 0xC002,
42 CS_NET : 0xC003,
43 CS_CLUSTER : 0xC004,
44 CS_MONITOR : 0xC005
45};
46
47/**
48 * @see http://msdn.microsoft.com/en-us/library/cc240510.aspx
49 */
50var ColorDepth = {
51 RNS_UD_COLOR_8BPP : 0xCA01,
52 RNS_UD_COLOR_16BPP_555 : 0xCA02,
53 RNS_UD_COLOR_16BPP_565 : 0xCA03,
54 RNS_UD_COLOR_24BPP : 0xCA04
55};
56
57/**
58 * @see http://msdn.microsoft.com/en-us/library/cc240510.aspx
59 */
60var HighColor = {
61 HIGH_COLOR_4BPP : 0x0004,
62 HIGH_COLOR_8BPP : 0x0008,
63 HIGH_COLOR_15BPP : 0x000f,
64 HIGH_COLOR_16BPP : 0x0010,
65 HIGH_COLOR_24BPP : 0x0018
66};
67
68/**
69 * @see http://msdn.microsoft.com/en-us/library/cc240510.aspx
70 */
71var Support = {
72 RNS_UD_24BPP_SUPPORT : 0x0001,
73 RNS_UD_16BPP_SUPPORT : 0x0002,
74 RNS_UD_15BPP_SUPPORT : 0x0004,
75 RNS_UD_32BPP_SUPPORT : 0x0008
76};
77
78/**
79 * @see http://msdn.microsoft.com/en-us/library/cc240510.aspx
80 */
81var CapabilityFlag = {
82 RNS_UD_CS_SUPPORT_ERRINFO_PDU : 0x0001,
83 RNS_UD_CS_WANT_32BPP_SESSION : 0x0002,
84 RNS_UD_CS_SUPPORT_STATUSINFO_PDU : 0x0004,
85 RNS_UD_CS_STRONG_ASYMMETRIC_KEYS : 0x0008,
86 RNS_UD_CS_UNUSED : 0x0010,
87 RNS_UD_CS_VALID_CONNECTION_TYPE : 0x0020,
88 RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU : 0x0040,
89 RNS_UD_CS_SUPPORT_NETCHAR_AUTODETECT : 0x0080,
90 RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL : 0x0100,
91 RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE : 0x0200,
92 RNS_UD_CS_SUPPORT_HEARTBEAT_PDU : 0x0400
93};
94
95/**
96 * @see http://msdn.microsoft.com/en-us/library/cc240510.aspx
97 */
98var ConnectionType = {
99 CONNECTION_TYPE_MODEM : 0x01,
100 CONNECTION_TYPE_BROADBAND_LOW : 0x02,
101 CONNECTION_TYPE_SATELLITE : 0x03,
102 CONNECTION_TYPE_BROADBAND_HIGH : 0x04,
103 CONNECTION_TYPE_WAN : 0x05,
104 CONNECTION_TYPE_LAN : 0x06,
105 CONNECTION_TYPE_AUTODETECT : 0x07
106};
107
108/**
109 * @see http://msdn.microsoft.com/en-us/library/cc240510.aspx
110 */
111var VERSION = {
112 RDP_VERSION_4 : 0x00080001,
113 RDP_VERSION_5_PLUS : 0x00080004
114};
115
116var Sequence = {
117 RNS_UD_SAS_DEL : 0xAA03
118};
119
120/**
121 * @see http://msdn.microsoft.com/en-us/library/cc240511.aspx
122 */
123var EncryptionMethod = {
124 ENCRYPTION_FLAG_40BIT : 0x00000001,
125 ENCRYPTION_FLAG_128BIT : 0x00000002,
126 ENCRYPTION_FLAG_56BIT : 0x00000008,
127 FIPS_ENCRYPTION_FLAG : 0x00000010
128};
129
130/**
131 * @see http://msdn.microsoft.com/en-us/library/cc240518.aspx
132 */
133var EncryptionLevel = {
134 ENCRYPTION_LEVEL_NONE : 0x00000000,
135 ENCRYPTION_LEVEL_LOW : 0x00000001,
136 ENCRYPTION_LEVEL_CLIENT_COMPATIBLE : 0x00000002,
137 ENCRYPTION_LEVEL_HIGH : 0x00000003,
138 ENCRYPTION_LEVEL_FIPS : 0x00000004
139};
140
141/**
142 * @see http://msdn.microsoft.com/en-us/library/cc240513.aspx
143 */
144var ChannelOptions = {
145 CHANNEL_OPTION_INITIALIZED : 0x80000000,
146 CHANNEL_OPTION_ENCRYPT_RDP : 0x40000000,
147 CHANNEL_OPTION_ENCRYPT_SC : 0x20000000,
148 CHANNEL_OPTION_ENCRYPT_CS : 0x10000000,
149 CHANNEL_OPTION_PRI_HIGH : 0x08000000,
150 CHANNEL_OPTION_PRI_MED : 0x04000000,
151 CHANNEL_OPTION_PRI_LOW : 0x02000000,
152 CHANNEL_OPTION_COMPRESS_RDP : 0x00800000,
153 CHANNEL_OPTION_COMPRESS : 0x00400000,
154 CHANNEL_OPTION_SHOW_PROTOCOL : 0x00200000,
155 REMOTE_CONTROL_PERSISTENT : 0x00100000
156};
157
158/**
159 * IBM_101_102_KEYS is the most common keyboard type
160 */
161var KeyboardType = {
162 IBM_PC_XT_83_KEY : 0x00000001,
163 OLIVETTI : 0x00000002,
164 IBM_PC_AT_84_KEY : 0x00000003,
165 IBM_101_102_KEYS : 0x00000004,
166 NOKIA_1050 : 0x00000005,
167 NOKIA_9140 : 0x00000006,
168 JAPANESE : 0x00000007
169};
170
171/**
172 * @see http://technet.microsoft.com/en-us/library/cc766503%28WS.10%29.aspx
173 */
174var KeyboardLayout = {
175 ARABIC : 0x00000401,
176 BULGARIAN : 0x00000402,
177 CHINESE_US_KEYBOARD : 0x00000404,
178 CZECH : 0x00000405,
179 DANISH : 0x00000406,
180 GERMAN : 0x00000407,
181 GREEK : 0x00000408,
182 US : 0x00000409,
183 SPANISH : 0x0000040a,
184 FINNISH : 0x0000040b,
185 FRENCH : 0x0000040c,
186 HEBREW : 0x0000040d,
187 HUNGARIAN : 0x0000040e,
188 ICELANDIC : 0x0000040f,
189 ITALIAN : 0x00000410,
190 JAPANESE : 0x00000411,
191 KOREAN : 0x00000412,
192 DUTCH : 0x00000413,
193 NORWEGIAN : 0x00000414
194};
195
196/**
197 * @see http://msdn.microsoft.com/en-us/library/cc240521.aspx
198 */
199var CertificateType = {
200 CERT_CHAIN_VERSION_1 : 0x00000001,
201 CERT_CHAIN_VERSION_2 : 0x00000002
202};
203
204/**
205 * @param {type.Type} data
206 * @returns {type.Component}
207 */
208function block(data) {
209 var self = {
210 // type of data block
211 type : new type.UInt16Le(function() {
212 return self.data.obj.__TYPE__;
213 }),
214 // length of entire packet
215 length : new type.UInt16Le(function() {
216 return new type.Component(self).size();
217 }),
218 // data block
219 data : data || new type.Factory(function(s){
220 var options = {
221 readLength : new type.CallableValue( function () {
222 return self.length.value - 4;
223 })
224 };
225 switch(self.type.value) {
226 case MessageType.SC_CORE:
227 self.data = serverCoreData(options).read(s);
228 break;
229 case MessageType.SC_SECURITY:
230 self.data = serverSecurityData(options).read(s);
231 break;
232 case MessageType.SC_NET:
233 self.data = serverNetworkData(null, options).read(s);
234 break;
235 case MessageType.CS_CORE:
236 self.data = clientCoreData(options).read(s);
237 break;
238 case MessageType.CS_SECURITY:
239 self.data = clientSecurityData(options).read(s);
240 break;
241 case MessageType.CS_NET:
242 self.data = clientNetworkData(null, options).read(s);
243 break;
244 default:
245 log.debug("unknown gcc block type " + self.type.value);
246 self.data = new type.BinaryString(null, options).read(s);
247 }
248 })
249 };
250
251 return new type.Component(self);
252}
253
254/**
255 * Main client informations
256 * keyboard
257 * screen definition
258 * color depth
259 * @see http://msdn.microsoft.com/en-us/library/cc240510.aspx
260 * @param opt {object} Classic type options
261 * @returns {type.Component}
262 */
263function clientCoreData(opt) {
264 var self = {
265 __TYPE__ : MessageType.CS_CORE,
266 rdpVersion : new type.UInt32Le(VERSION.RDP_VERSION_5_PLUS),
267 desktopWidth : new type.UInt16Le(1280),
268 desktopHeight : new type.UInt16Le(800),
269 colorDepth : new type.UInt16Le(ColorDepth.RNS_UD_COLOR_8BPP),
270 sasSequence : new type.UInt16Le(Sequence.RNS_UD_SAS_DEL),
271 kbdLayout : new type.UInt32Le(KeyboardLayout.FRENCH),
272 clientBuild : new type.UInt32Le(3790),
273 clientName : new type.BinaryString(Buffer.from('node-rdpjs\x00\x00\x00\x00\x00\x00', 'ucs2'), { readLength : new type.CallableValue(32) }),
274 keyboardType : new type.UInt32Le(KeyboardType.IBM_101_102_KEYS),
275 keyboardSubType : new type.UInt32Le(0),
276 keyboardFnKeys : new type.UInt32Le(12),
277 imeFileName : new type.BinaryString(Buffer.from(Array(64 + 1).join('\x00')), { readLength : new type.CallableValue(64), optional : true }),
278 postBeta2ColorDepth : new type.UInt16Le(ColorDepth.RNS_UD_COLOR_8BPP, { optional : true }),
279 clientProductId : new type.UInt16Le(1, { optional : true }),
280 serialNumber : new type.UInt32Le(0, { optional : true }),
281 highColorDepth : new type.UInt16Le(HighColor.HIGH_COLOR_24BPP, { optional : true }),
282 supportedColorDepths : new type.UInt16Le(Support.RNS_UD_15BPP_SUPPORT | Support.RNS_UD_16BPP_SUPPORT | Support.RNS_UD_24BPP_SUPPORT | Support.RNS_UD_32BPP_SUPPORT, { optional : true }),
283 earlyCapabilityFlags : new type.UInt16Le(CapabilityFlag.RNS_UD_CS_SUPPORT_ERRINFO_PDU, { optional : true }),
284 clientDigProductId : new type.BinaryString(Buffer.from(Array(64 + 1).join('\x00')), { optional : true, readLength : new type.CallableValue(64) }),
285 connectionType : new type.UInt8(0, { optional : true }),
286 pad1octet : new type.UInt8(0, { optional : true }),
287 serverSelectedProtocol : new type.UInt32Le(0, { optional : true })
288 };
289
290 return new type.Component(self, opt);
291}
292
293/**
294 * @see http://msdn.microsoft.com/en-us/library/cc240517.aspx
295 * @param opt {object} Classic type options
296 * @returns {type.Component}
297 */
298function serverCoreData(opt) {
299 var self = {
300 __TYPE__ : MessageType.SC_CORE,
301 rdpVersion : new type.UInt32Le(VERSION.RDP_VERSION_5_PLUS),
302 clientRequestedProtocol : new type.UInt32Le(null, { optional : true }),
303 earlyCapabilityFlags : new type.UInt32Le(null, { optional : true })
304 };
305
306 return new type.Component(self, opt);
307}
308
309/**
310 * @see http://msdn.microsoft.com/en-us/library/cc240511.aspx
311 * @param opt {object} Classic type options
312 * @returns {type.Component}
313 */
314function clientSecurityData(opt) {
315 var self = {
316 __TYPE__ : MessageType.CS_SECURITY,
317 encryptionMethods : new type.UInt32Le(EncryptionMethod.ENCRYPTION_FLAG_40BIT | EncryptionMethod.ENCRYPTION_FLAG_56BIT | EncryptionMethod.ENCRYPTION_FLAG_128BIT),
318 extEncryptionMethods : new type.UInt32Le()
319 };
320
321 return new type.Component(self, opt);
322}
323
324/**
325 * Only use for SSL (RDP security layer TODO)
326 * @see http://msdn.microsoft.com/en-us/library/cc240518.aspx
327 * @param opt {object} Classic type options
328 * @returns {type.Component}
329 */
330function serverSecurityData(opt) {
331 var self = {
332 __TYPE__ : MessageType.SC_SECURITY,
333 encryptionMethod : new type.UInt32Le(),
334 encryptionLevel : new type.UInt32Le()
335 };
336
337 return new type.Component(self, opt);
338}
339
340/**
341 * Channel definition
342 * @param opt {object} Classic type options
343 * @returns {type.Component}
344 */
345function channelDef (opt) {
346 var self = {
347 name : new type.BinaryString(null, { readLength : new type.CallableValue(8) }),
348 options : new type.UInt32Le()
349 };
350
351 return new type.Component(self, opt);
352}
353
354/**
355 * Optional channel requests (sound, clipboard ...)
356 * @param opt {object} Classic type options
357 * @returns {type.Component}
358 */
359function clientNetworkData(channelDefArray, opt) {
360 var self = {
361 __TYPE__ : MessageType.CS_NET,
362 channelCount : new type.UInt32Le( function () {
363 return self.channelDefArray.obj.length;
364 }),
365 channelDefArray : channelDefArray || new type.Factory( function (s) {
366 self.channelDefArray = new type.Component([]);
367
368 for (var i = 0; i < self.channelCount.value; i++) {
369 self.channelDefArray.obj.push(channelDef().read(s));
370 }
371 })
372 };
373
374 return new type.Component(self, opt);
375}
376
377/**
378 * @param channelIds {type.Component} list of available channels
379 * @param opt {object} Classic type options
380 * @returns {type.Component}
381 */
382function serverNetworkData (channelIds, opt) {
383 var self = {
384 __TYPE__ : MessageType.SC_NET,
385 MCSChannelId : new type.UInt16Le(1003, { constant : true }),
386 channelCount : new type.UInt16Le(function () {
387 return self.channelIdArray.obj.length;
388 }),
389 channelIdArray : channelIds || new type.Factory( function (s) {
390 self.channelIdArray = new type.Component([]);
391 for (var i = 0; i < self.channelCount.value; i++) {
392 self.channelIdArray.obj.push(new type.UInt16Le().read(s));
393 }
394 }),
395 pad : new type.UInt16Le(null, { conditional : function () {
396 return (self.channelCount.value % 2) === 1;
397 }})
398 };
399
400 return new type.Component(self, opt);
401}
402
403/**
404 * Client or server GCC settings block
405 * @param blocks {type.Component} array of gcc blocks
406 * @param opt {object} options to component type
407 * @returns {type.Component}
408 */
409function settings(blocks, opt) {
410 var self = {
411 blocks : blocks || new type.Factory(function(s) {
412 self.blocks = new type.Component([]);
413 // read until end of stream
414 while(s.availableLength() > 0) {
415 self.blocks.obj.push(block().read(s));
416 }
417 }),
418 };
419
420 return new type.Component(self, opt);
421}
422
423/**
424 * Read GCC response from server
425 * @param s {type.Stream} current stream
426 * @returns {Array(type.Component)} list of server block
427 */
428function readConferenceCreateResponse(s) {
429 per.readChoice(s);
430
431 if(!per.readObjectIdentifier(s, t124_02_98_oid)) {
432 throw new error.ProtocolError('NODE_RDP_PROTOCOL_T125_GCC_BAD_OBJECT_IDENTIFIER_T124');
433 }
434
435 per.readLength(s);
436 per.readChoice(s);
437 per.readInteger16(s, 1001);
438 per.readInteger(s);
439 per.readEnumerates(s);
440 per.readNumberOfSet(s);
441 per.readChoice(s);
442
443 if (!per.readOctetStream(s, h221_sc_key, 4)) {
444 throw new error.ProtocolError('NODE_RDP_PROTOCOL_T125_GCC_BAD_H221_SC_KEY');
445 }
446
447 length = per.readLength(s);
448 serverSettings = settings(null, { readLength : new type.CallableValue(length) });
449
450 // Object magic
451 return serverSettings.read(s).obj.blocks.obj.map(function(e) {
452 return e.obj.data;
453 });
454}
455
456/**
457 * Read GCC request
458 * @param s {type.Stream}
459 * @returns {Array(type.Component)} list of client block
460 */
461function readConferenceCreateRequest (s) {
462 per.readChoice(s);
463 if (!per.readObjectIdentifier(s, t124_02_98_oid)) {
464 throw new error.ProtocolError('NODE_RDP_PROTOCOL_T125_GCC_BAD_H221_SC_KEY');
465 }
466 per.readLength(s);
467 per.readChoice(s);
468 per.readSelection(s);
469 per.readNumericString(s, 1);
470 per.readPadding(s, 1);
471
472 if (per.readNumberOfSet(s) !== 1) {
473 throw new error.ProtocolError('NODE_RDP_PROTOCOL_T125_GCC_BAD_SET');
474 }
475
476 if (per.readChoice(s) !== 0xc0) {
477 throw new error.ProtocolError('NODE_RDP_PROTOCOL_T125_GCC_BAD_CHOICE');
478 }
479
480 per.readOctetStream(s, h221_cs_key, 4);
481
482 length = per.readLength(s);
483 var clientSettings = settings(null, { readLength : new type.CallableValue(length) });
484
485 // Object magic
486 return clientSettings.read(s).obj.blocks.obj.map(function(e) {
487 return e.obj.data;
488 });
489}
490
491/**
492 * Built {type.Componen} from gcc user data
493 * @param userData {type.Component} GCC data from client
494 * @returns {type.Component} GCC encoded client user data
495 */
496function writeConferenceCreateRequest (userData) {
497 var userDataStream = new type.Stream(userData.size());
498 userData.write(userDataStream);
499
500 return new type.Component([
501 per.writeChoice(0), per.writeObjectIdentifier(t124_02_98_oid),
502 per.writeLength(userData.size() + 14), per.writeChoice(0),
503 per.writeSelection(0x08), per.writeNumericString("1", 1), per.writePadding(1),
504 per.writeNumberOfSet(1), per.writeChoice(0xc0),
505 per.writeOctetStream(Buffer.from(h221_cs_key), 4), per.writeOctetStream(userDataStream.getValue())
506 ]);
507}
508
509function writeConferenceCreateResponse (userData) {
510 var userDataStream = new type.Stream(userData.size());
511 userData.write(userDataStream);
512
513 return new type.Component([
514 per.writeChoice(0), per.writeObjectIdentifier(t124_02_98_oid),
515 per.writeLength(userData.size() + 14), per.writeChoice(0x14),
516 per.writeInteger16(0x79F3, 1001), per.writeInteger(1), per.writeEnumerates(0),
517 per.writeNumberOfSet(1), per.writeChoice(0xc0),
518 per.writeOctetStream(Buffer.from(h221_sc_key), 4), per.writeOctetStream(userDataStream.getValue())
519 ]);
520}
521
522/**
523 * Module exports
524 */
525module.exports = {
526 MessageType : MessageType,
527 VERSION : VERSION,
528 KeyboardLayout : KeyboardLayout,
529 block : block,
530 clientCoreData : clientCoreData,
531 clientNetworkData : clientNetworkData,
532 clientSecurityData : clientSecurityData,
533 serverCoreData : serverCoreData,
534 serverSecurityData : serverSecurityData,
535 serverNetworkData : serverNetworkData,
536 readConferenceCreateResponse : readConferenceCreateResponse,
537 readConferenceCreateRequest : readConferenceCreateRequest,
538 writeConferenceCreateRequest : writeConferenceCreateRequest,
539 writeConferenceCreateResponse : writeConferenceCreateResponse
540};