| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540 |
- /*
- * Copyright (c) 2014-2015 Sylvain Peyrefitte
- *
- * This file is part of node-rdpjs.
- *
- * node-rdpjs is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- var type = require('../../core').type;
- var log = require('../../core').log;
- var error = require('../../core').error;
- var per = require('./per');
- var t124_02_98_oid = [ 0, 0, 20, 124, 0, 1 ];
- var h221_cs_key = "Duca";
- var h221_sc_key = "McDn";
- /**
- * @see http://msdn.microsoft.com/en-us/library/cc240509.aspx
- */
- var MessageType = {
- //server -> client
- SC_CORE : 0x0C01,
- SC_SECURITY : 0x0C02,
- SC_NET : 0x0C03,
- //client -> server
- CS_CORE : 0xC001,
- CS_SECURITY : 0xC002,
- CS_NET : 0xC003,
- CS_CLUSTER : 0xC004,
- CS_MONITOR : 0xC005
- };
-
- /**
- * @see http://msdn.microsoft.com/en-us/library/cc240510.aspx
- */
- var ColorDepth = {
- RNS_UD_COLOR_8BPP : 0xCA01,
- RNS_UD_COLOR_16BPP_555 : 0xCA02,
- RNS_UD_COLOR_16BPP_565 : 0xCA03,
- RNS_UD_COLOR_24BPP : 0xCA04
- };
-
- /**
- * @see http://msdn.microsoft.com/en-us/library/cc240510.aspx
- */
- var HighColor = {
- HIGH_COLOR_4BPP : 0x0004,
- HIGH_COLOR_8BPP : 0x0008,
- HIGH_COLOR_15BPP : 0x000f,
- HIGH_COLOR_16BPP : 0x0010,
- HIGH_COLOR_24BPP : 0x0018
- };
- /**
- * @see http://msdn.microsoft.com/en-us/library/cc240510.aspx
- */
- var Support = {
- RNS_UD_24BPP_SUPPORT : 0x0001,
- RNS_UD_16BPP_SUPPORT : 0x0002,
- RNS_UD_15BPP_SUPPORT : 0x0004,
- RNS_UD_32BPP_SUPPORT : 0x0008
- };
- /**
- * @see http://msdn.microsoft.com/en-us/library/cc240510.aspx
- */
- var CapabilityFlag = {
- RNS_UD_CS_SUPPORT_ERRINFO_PDU : 0x0001,
- RNS_UD_CS_WANT_32BPP_SESSION : 0x0002,
- RNS_UD_CS_SUPPORT_STATUSINFO_PDU : 0x0004,
- RNS_UD_CS_STRONG_ASYMMETRIC_KEYS : 0x0008,
- RNS_UD_CS_UNUSED : 0x0010,
- RNS_UD_CS_VALID_CONNECTION_TYPE : 0x0020,
- RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU : 0x0040,
- RNS_UD_CS_SUPPORT_NETCHAR_AUTODETECT : 0x0080,
- RNS_UD_CS_SUPPORT_DYNVC_GFX_PROTOCOL : 0x0100,
- RNS_UD_CS_SUPPORT_DYNAMIC_TIME_ZONE : 0x0200,
- RNS_UD_CS_SUPPORT_HEARTBEAT_PDU : 0x0400
- };
- /**
- * @see http://msdn.microsoft.com/en-us/library/cc240510.aspx
- */
- var ConnectionType = {
- CONNECTION_TYPE_MODEM : 0x01,
- CONNECTION_TYPE_BROADBAND_LOW : 0x02,
- CONNECTION_TYPE_SATELLITE : 0x03,
- CONNECTION_TYPE_BROADBAND_HIGH : 0x04,
- CONNECTION_TYPE_WAN : 0x05,
- CONNECTION_TYPE_LAN : 0x06,
- CONNECTION_TYPE_AUTODETECT : 0x07
- };
- /**
- * @see http://msdn.microsoft.com/en-us/library/cc240510.aspx
- */
- var VERSION = {
- RDP_VERSION_4 : 0x00080001,
- RDP_VERSION_5_PLUS : 0x00080004
- };
- var Sequence = {
- RNS_UD_SAS_DEL : 0xAA03
- };
- /**
- * @see http://msdn.microsoft.com/en-us/library/cc240511.aspx
- */
- var EncryptionMethod = {
- ENCRYPTION_FLAG_40BIT : 0x00000001,
- ENCRYPTION_FLAG_128BIT : 0x00000002,
- ENCRYPTION_FLAG_56BIT : 0x00000008,
- FIPS_ENCRYPTION_FLAG : 0x00000010
- };
- /**
- * @see http://msdn.microsoft.com/en-us/library/cc240518.aspx
- */
- var EncryptionLevel = {
- ENCRYPTION_LEVEL_NONE : 0x00000000,
- ENCRYPTION_LEVEL_LOW : 0x00000001,
- ENCRYPTION_LEVEL_CLIENT_COMPATIBLE : 0x00000002,
- ENCRYPTION_LEVEL_HIGH : 0x00000003,
- ENCRYPTION_LEVEL_FIPS : 0x00000004
- };
- /**
- * @see http://msdn.microsoft.com/en-us/library/cc240513.aspx
- */
- var ChannelOptions = {
- CHANNEL_OPTION_INITIALIZED : 0x80000000,
- CHANNEL_OPTION_ENCRYPT_RDP : 0x40000000,
- CHANNEL_OPTION_ENCRYPT_SC : 0x20000000,
- CHANNEL_OPTION_ENCRYPT_CS : 0x10000000,
- CHANNEL_OPTION_PRI_HIGH : 0x08000000,
- CHANNEL_OPTION_PRI_MED : 0x04000000,
- CHANNEL_OPTION_PRI_LOW : 0x02000000,
- CHANNEL_OPTION_COMPRESS_RDP : 0x00800000,
- CHANNEL_OPTION_COMPRESS : 0x00400000,
- CHANNEL_OPTION_SHOW_PROTOCOL : 0x00200000,
- REMOTE_CONTROL_PERSISTENT : 0x00100000
- };
- /**
- * IBM_101_102_KEYS is the most common keyboard type
- */
- var KeyboardType = {
- IBM_PC_XT_83_KEY : 0x00000001,
- OLIVETTI : 0x00000002,
- IBM_PC_AT_84_KEY : 0x00000003,
- IBM_101_102_KEYS : 0x00000004,
- NOKIA_1050 : 0x00000005,
- NOKIA_9140 : 0x00000006,
- JAPANESE : 0x00000007
- };
- /**
- * @see http://technet.microsoft.com/en-us/library/cc766503%28WS.10%29.aspx
- */
- var KeyboardLayout = {
- ARABIC : 0x00000401,
- BULGARIAN : 0x00000402,
- CHINESE_US_KEYBOARD : 0x00000404,
- CZECH : 0x00000405,
- DANISH : 0x00000406,
- GERMAN : 0x00000407,
- GREEK : 0x00000408,
- US : 0x00000409,
- SPANISH : 0x0000040a,
- FINNISH : 0x0000040b,
- FRENCH : 0x0000040c,
- HEBREW : 0x0000040d,
- HUNGARIAN : 0x0000040e,
- ICELANDIC : 0x0000040f,
- ITALIAN : 0x00000410,
- JAPANESE : 0x00000411,
- KOREAN : 0x00000412,
- DUTCH : 0x00000413,
- NORWEGIAN : 0x00000414
- };
- /**
- * @see http://msdn.microsoft.com/en-us/library/cc240521.aspx
- */
- var CertificateType = {
- CERT_CHAIN_VERSION_1 : 0x00000001,
- CERT_CHAIN_VERSION_2 : 0x00000002
- };
- /**
- * @param {type.Type} data
- * @returns {type.Component}
- */
- function block(data) {
- var self = {
- // type of data block
- type : new type.UInt16Le(function() {
- return self.data.obj.__TYPE__;
- }),
- // length of entire packet
- length : new type.UInt16Le(function() {
- return new type.Component(self).size();
- }),
- // data block
- data : data || new type.Factory(function(s){
- var options = {
- readLength : new type.CallableValue( function () {
- return self.length.value - 4;
- })
- };
- switch(self.type.value) {
- case MessageType.SC_CORE:
- self.data = serverCoreData(options).read(s);
- break;
- case MessageType.SC_SECURITY:
- self.data = serverSecurityData(options).read(s);
- break;
- case MessageType.SC_NET:
- self.data = serverNetworkData(null, options).read(s);
- break;
- case MessageType.CS_CORE:
- self.data = clientCoreData(options).read(s);
- break;
- case MessageType.CS_SECURITY:
- self.data = clientSecurityData(options).read(s);
- break;
- case MessageType.CS_NET:
- self.data = clientNetworkData(null, options).read(s);
- break;
- default:
- log.debug("unknown gcc block type " + self.type.value);
- self.data = new type.BinaryString(null, options).read(s);
- }
- })
- };
-
- return new type.Component(self);
- }
- /**
- * Main client informations
- * keyboard
- * screen definition
- * color depth
- * @see http://msdn.microsoft.com/en-us/library/cc240510.aspx
- * @param opt {object} Classic type options
- * @returns {type.Component}
- */
- function clientCoreData(opt) {
- var self = {
- __TYPE__ : MessageType.CS_CORE,
- rdpVersion : new type.UInt32Le(VERSION.RDP_VERSION_5_PLUS),
- desktopWidth : new type.UInt16Le(1280),
- desktopHeight : new type.UInt16Le(800),
- colorDepth : new type.UInt16Le(ColorDepth.RNS_UD_COLOR_8BPP),
- sasSequence : new type.UInt16Le(Sequence.RNS_UD_SAS_DEL),
- kbdLayout : new type.UInt32Le(KeyboardLayout.FRENCH),
- clientBuild : new type.UInt32Le(3790),
- clientName : new type.BinaryString(Buffer.from('node-rdpjs\x00\x00\x00\x00\x00\x00', 'ucs2'), { readLength : new type.CallableValue(32) }),
- keyboardType : new type.UInt32Le(KeyboardType.IBM_101_102_KEYS),
- keyboardSubType : new type.UInt32Le(0),
- keyboardFnKeys : new type.UInt32Le(12),
- imeFileName : new type.BinaryString(Buffer.from(Array(64 + 1).join('\x00')), { readLength : new type.CallableValue(64), optional : true }),
- postBeta2ColorDepth : new type.UInt16Le(ColorDepth.RNS_UD_COLOR_8BPP, { optional : true }),
- clientProductId : new type.UInt16Le(1, { optional : true }),
- serialNumber : new type.UInt32Le(0, { optional : true }),
- highColorDepth : new type.UInt16Le(HighColor.HIGH_COLOR_24BPP, { optional : true }),
- 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 }),
- earlyCapabilityFlags : new type.UInt16Le(CapabilityFlag.RNS_UD_CS_SUPPORT_ERRINFO_PDU, { optional : true }),
- clientDigProductId : new type.BinaryString(Buffer.from(Array(64 + 1).join('\x00')), { optional : true, readLength : new type.CallableValue(64) }),
- connectionType : new type.UInt8(0, { optional : true }),
- pad1octet : new type.UInt8(0, { optional : true }),
- serverSelectedProtocol : new type.UInt32Le(0, { optional : true })
- };
-
- return new type.Component(self, opt);
- }
- /**
- * @see http://msdn.microsoft.com/en-us/library/cc240517.aspx
- * @param opt {object} Classic type options
- * @returns {type.Component}
- */
- function serverCoreData(opt) {
- var self = {
- __TYPE__ : MessageType.SC_CORE,
- rdpVersion : new type.UInt32Le(VERSION.RDP_VERSION_5_PLUS),
- clientRequestedProtocol : new type.UInt32Le(null, { optional : true }),
- earlyCapabilityFlags : new type.UInt32Le(null, { optional : true })
- };
-
- return new type.Component(self, opt);
- }
- /**
- * @see http://msdn.microsoft.com/en-us/library/cc240511.aspx
- * @param opt {object} Classic type options
- * @returns {type.Component}
- */
- function clientSecurityData(opt) {
- var self = {
- __TYPE__ : MessageType.CS_SECURITY,
- encryptionMethods : new type.UInt32Le(EncryptionMethod.ENCRYPTION_FLAG_40BIT | EncryptionMethod.ENCRYPTION_FLAG_56BIT | EncryptionMethod.ENCRYPTION_FLAG_128BIT),
- extEncryptionMethods : new type.UInt32Le()
- };
-
- return new type.Component(self, opt);
- }
- /**
- * Only use for SSL (RDP security layer TODO)
- * @see http://msdn.microsoft.com/en-us/library/cc240518.aspx
- * @param opt {object} Classic type options
- * @returns {type.Component}
- */
- function serverSecurityData(opt) {
- var self = {
- __TYPE__ : MessageType.SC_SECURITY,
- encryptionMethod : new type.UInt32Le(),
- encryptionLevel : new type.UInt32Le()
- };
-
- return new type.Component(self, opt);
- }
- /**
- * Channel definition
- * @param opt {object} Classic type options
- * @returns {type.Component}
- */
- function channelDef (opt) {
- var self = {
- name : new type.BinaryString(null, { readLength : new type.CallableValue(8) }),
- options : new type.UInt32Le()
- };
-
- return new type.Component(self, opt);
- }
- /**
- * Optional channel requests (sound, clipboard ...)
- * @param opt {object} Classic type options
- * @returns {type.Component}
- */
- function clientNetworkData(channelDefArray, opt) {
- var self = {
- __TYPE__ : MessageType.CS_NET,
- channelCount : new type.UInt32Le( function () {
- return self.channelDefArray.obj.length;
- }),
- channelDefArray : channelDefArray || new type.Factory( function (s) {
- self.channelDefArray = new type.Component([]);
-
- for (var i = 0; i < self.channelCount.value; i++) {
- self.channelDefArray.obj.push(channelDef().read(s));
- }
- })
- };
-
- return new type.Component(self, opt);
- }
- /**
- * @param channelIds {type.Component} list of available channels
- * @param opt {object} Classic type options
- * @returns {type.Component}
- */
- function serverNetworkData (channelIds, opt) {
- var self = {
- __TYPE__ : MessageType.SC_NET,
- MCSChannelId : new type.UInt16Le(1003, { constant : true }),
- channelCount : new type.UInt16Le(function () {
- return self.channelIdArray.obj.length;
- }),
- channelIdArray : channelIds || new type.Factory( function (s) {
- self.channelIdArray = new type.Component([]);
- for (var i = 0; i < self.channelCount.value; i++) {
- self.channelIdArray.obj.push(new type.UInt16Le().read(s));
- }
- }),
- pad : new type.UInt16Le(null, { conditional : function () {
- return (self.channelCount.value % 2) === 1;
- }})
- };
-
- return new type.Component(self, opt);
- }
- /**
- * Client or server GCC settings block
- * @param blocks {type.Component} array of gcc blocks
- * @param opt {object} options to component type
- * @returns {type.Component}
- */
- function settings(blocks, opt) {
- var self = {
- blocks : blocks || new type.Factory(function(s) {
- self.blocks = new type.Component([]);
- // read until end of stream
- while(s.availableLength() > 0) {
- self.blocks.obj.push(block().read(s));
- }
- }),
- };
-
- return new type.Component(self, opt);
- }
- /**
- * Read GCC response from server
- * @param s {type.Stream} current stream
- * @returns {Array(type.Component)} list of server block
- */
- function readConferenceCreateResponse(s) {
- per.readChoice(s);
-
- if(!per.readObjectIdentifier(s, t124_02_98_oid)) {
- throw new error.ProtocolError('NODE_RDP_PROTOCOL_T125_GCC_BAD_OBJECT_IDENTIFIER_T124');
- }
-
- per.readLength(s);
- per.readChoice(s);
- per.readInteger16(s, 1001);
- per.readInteger(s);
- per.readEnumerates(s);
- per.readNumberOfSet(s);
- per.readChoice(s);
-
- if (!per.readOctetStream(s, h221_sc_key, 4)) {
- throw new error.ProtocolError('NODE_RDP_PROTOCOL_T125_GCC_BAD_H221_SC_KEY');
- }
-
- length = per.readLength(s);
- serverSettings = settings(null, { readLength : new type.CallableValue(length) });
-
- // Object magic
- return serverSettings.read(s).obj.blocks.obj.map(function(e) {
- return e.obj.data;
- });
- }
- /**
- * Read GCC request
- * @param s {type.Stream}
- * @returns {Array(type.Component)} list of client block
- */
- function readConferenceCreateRequest (s) {
- per.readChoice(s);
- if (!per.readObjectIdentifier(s, t124_02_98_oid)) {
- throw new error.ProtocolError('NODE_RDP_PROTOCOL_T125_GCC_BAD_H221_SC_KEY');
- }
- per.readLength(s);
- per.readChoice(s);
- per.readSelection(s);
- per.readNumericString(s, 1);
- per.readPadding(s, 1);
- if (per.readNumberOfSet(s) !== 1) {
- throw new error.ProtocolError('NODE_RDP_PROTOCOL_T125_GCC_BAD_SET');
- }
- if (per.readChoice(s) !== 0xc0) {
- throw new error.ProtocolError('NODE_RDP_PROTOCOL_T125_GCC_BAD_CHOICE');
- }
- per.readOctetStream(s, h221_cs_key, 4);
-
- length = per.readLength(s);
- var clientSettings = settings(null, { readLength : new type.CallableValue(length) });
-
- // Object magic
- return clientSettings.read(s).obj.blocks.obj.map(function(e) {
- return e.obj.data;
- });
- }
- /**
- * Built {type.Componen} from gcc user data
- * @param userData {type.Component} GCC data from client
- * @returns {type.Component} GCC encoded client user data
- */
- function writeConferenceCreateRequest (userData) {
- var userDataStream = new type.Stream(userData.size());
- userData.write(userDataStream);
-
- return new type.Component([
- per.writeChoice(0), per.writeObjectIdentifier(t124_02_98_oid),
- per.writeLength(userData.size() + 14), per.writeChoice(0),
- per.writeSelection(0x08), per.writeNumericString("1", 1), per.writePadding(1),
- per.writeNumberOfSet(1), per.writeChoice(0xc0),
- per.writeOctetStream(Buffer.from(h221_cs_key), 4), per.writeOctetStream(userDataStream.getValue())
- ]);
- }
- function writeConferenceCreateResponse (userData) {
- var userDataStream = new type.Stream(userData.size());
- userData.write(userDataStream);
-
- return new type.Component([
- per.writeChoice(0), per.writeObjectIdentifier(t124_02_98_oid),
- per.writeLength(userData.size() + 14), per.writeChoice(0x14),
- per.writeInteger16(0x79F3, 1001), per.writeInteger(1), per.writeEnumerates(0),
- per.writeNumberOfSet(1), per.writeChoice(0xc0),
- per.writeOctetStream(Buffer.from(h221_sc_key), 4), per.writeOctetStream(userDataStream.getValue())
- ]);
- }
- /**
- * Module exports
- */
- module.exports = {
- MessageType : MessageType,
- VERSION : VERSION,
- KeyboardLayout : KeyboardLayout,
- block : block,
- clientCoreData : clientCoreData,
- clientNetworkData : clientNetworkData,
- clientSecurityData : clientSecurityData,
- serverCoreData : serverCoreData,
- serverSecurityData : serverSecurityData,
- serverNetworkData : serverNetworkData,
- readConferenceCreateResponse : readConferenceCreateResponse,
- readConferenceCreateRequest : readConferenceCreateRequest,
- writeConferenceCreateRequest : writeConferenceCreateRequest,
- writeConferenceCreateResponse : writeConferenceCreateResponse
- };
|