gcc.js 16 KB

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