per.js 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  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 error = require('../../core').error;
  21. /**
  22. * @param s {type.Stream} read value from stream
  23. * @returns read length from per format
  24. */
  25. function readLength(s) {
  26. var byte = new type.UInt8().read(s).value;
  27. var size = 0;
  28. if(byte & 0x80) {
  29. byte &= ~0x80;
  30. size = byte << 8;
  31. size += new type.UInt8().read(s).value;
  32. }
  33. else {
  34. size = byte;
  35. }
  36. return size;
  37. }
  38. /**
  39. * @param value {raw} value to convert to per format
  40. * @returns type objects per encoding value
  41. */
  42. function writeLength(value) {
  43. if(value > 0x7f) {
  44. return new type.UInt16Be(value | 0x8000);
  45. }
  46. else {
  47. return new type.UInt8(value);
  48. }
  49. }
  50. /**
  51. * @param s {type.Stream}
  52. * @returns {integer} choice decoding from per encoding
  53. */
  54. function readChoice(s) {
  55. return new type.UInt8().read(s).value;
  56. }
  57. /**
  58. * @param choice {integer}
  59. * @returns {type.UInt8} choice per encoded
  60. */
  61. function writeChoice(choice) {
  62. return new type.UInt8(choice);
  63. }
  64. /**
  65. * @param s {type.Stream}
  66. * @returns {integer} number represent selection
  67. */
  68. function readSelection(s) {
  69. return new type.UInt8().read(s).value;
  70. }
  71. /**
  72. * @param selection {integer}
  73. * @returns {type.UInt8} per encoded selection
  74. */
  75. function writeSelection(selection) {
  76. return new type.UInt8(selection);
  77. }
  78. /**
  79. * @param s {type.Stream}
  80. * @returns {integer} number of sets
  81. */
  82. function readNumberOfSet(s) {
  83. return new type.UInt8().read(s).value;
  84. }
  85. /**
  86. * @param numberOfSet {integer}
  87. * @returns {type.UInt8} per encoded nuimber of sets
  88. */
  89. function writeNumberOfSet(numberOfSet) {
  90. return new type.UInt8(numberOfSet);
  91. }
  92. /**
  93. * @param s {type.Stream}
  94. * @returns {integer} enumerates number
  95. */
  96. function readEnumerates(s) {
  97. return new type.UInt8().read(s).value;
  98. }
  99. /**
  100. * @param enumerate {integer}
  101. * @returns {type.UInt8} per encoded enumerate
  102. */
  103. function writeEnumerates(enumerate) {
  104. return new type.UInt8(enumerate);
  105. }
  106. /**
  107. * @param s {type.Stream}
  108. * @returns {integer} integer per decoded
  109. */
  110. function readInteger(s) {
  111. var result;
  112. var size = readLength(s);
  113. switch(size) {
  114. case 1:
  115. result = new type.UInt8();
  116. break;
  117. case 2:
  118. result = new type.UInt16Be();
  119. break;
  120. case 4:
  121. result = new type.UInt32Be();
  122. break;
  123. default:
  124. throw new error.UnexpectedFatalError('NODE_RDP_PROTOCOL_T125_PER_BAD_INTEGER_LENGTH');
  125. }
  126. return result.read(s).value;
  127. }
  128. /**
  129. * @param value {integer}
  130. * @returns {type.Component} per encoded integer
  131. */
  132. function writeInteger(value) {
  133. if(value <= 0xff) {
  134. return new type.Component([writeLength(1), new type.UInt8(value)]);
  135. }
  136. else if(value < 0xffff) {
  137. return new type.Component([writeLength(2), new type.UInt16Be(value)]);
  138. }
  139. else {
  140. return new type.Component([writeLength(4), new type.UInt32Be(value)]);
  141. }
  142. }
  143. /**
  144. * @param s {type.Stream}
  145. * @param minimum {integer} increment (default 0)
  146. * @returns {integer} per decoded integer 16 bits
  147. */
  148. function readInteger16(s, minimum) {
  149. return new type.UInt16Be().read(s).value + (minimum || 0);
  150. }
  151. /**
  152. * @param value {integer}
  153. * @param minimum {integer} decrement (default 0)
  154. * @returns {type.UInt16Be} per encoded integer 16 bits
  155. */
  156. function writeInteger16(value, minimum) {
  157. return new type.UInt16Be(value - (minimum || 0));
  158. }
  159. /**
  160. * Check object identifier
  161. * @param s {type.Stream}
  162. * @param oid {array} object identifier to check
  163. */
  164. function readObjectIdentifier(s, oid) {
  165. var size = readLength(s);
  166. if(size !== 5) {
  167. return false;
  168. }
  169. var a_oid = [0, 0, 0, 0, 0, 0];
  170. var t12 = new type.UInt8().read(s).value;
  171. a_oid[0] = t12 >> 4;
  172. a_oid[1] = t12 & 0x0f;
  173. a_oid[2] = new type.UInt8().read(s).value;
  174. a_oid[3] = new type.UInt8().read(s).value;
  175. a_oid[4] = new type.UInt8().read(s).value;
  176. a_oid[5] = new type.UInt8().read(s).value;
  177. for(var i in oid) {
  178. if(oid[i] !== a_oid[i]) return false;
  179. }
  180. return true;
  181. }
  182. /**
  183. * @param oid {array} oid to write
  184. * @returns {type.Component} per encoded object identifier
  185. */
  186. function writeObjectIdentifier(oid) {
  187. return new type.Component([new type.UInt8(5), new type.UInt8((oid[0] << 4) & (oid[1] & 0x0f)), new type.UInt8(oid[2]), new type.UInt8(oid[3]), new type.UInt8(oid[4]), new type.UInt8(oid[5])]);
  188. }
  189. /**
  190. * Read as padding...
  191. * @param s {type.Stream}
  192. * @param minValue
  193. */
  194. function readNumericString(s, minValue) {
  195. var length = readLength(s);
  196. length = (length + minValue + 1) / 2;
  197. s.readPadding(length);
  198. }
  199. /**
  200. * @param nStr {String}
  201. * @param minValue {integer}
  202. * @returns {type.Component} per encoded numeric string
  203. */
  204. function writeNumericString(nStr, minValue) {
  205. var length = nStr.length;
  206. var mlength = minValue;
  207. if(length - minValue >= 0) {
  208. mlength = length - minValue;
  209. }
  210. var result = [];
  211. for(var i = 0; i < length; i += 2) {
  212. var c1 = nStr.charCodeAt(i);
  213. var c2 = 0;
  214. if(i + 1 < length) {
  215. c2 = nStr.charCodeAt(i + 1);
  216. }
  217. else {
  218. c2 = 0x30;
  219. }
  220. c1 = (c1 - 0x30) % 10;
  221. c2 = (c2 - 0x30) % 10;
  222. result[result.length] = new type.UInt8((c1 << 4) | c2);
  223. }
  224. return new type.Component([writeLength(mlength), new type.Component(result)]);
  225. }
  226. /**
  227. * @param s {type.Stream}
  228. * @param length {integer} length of padding
  229. */
  230. function readPadding(s, length) {
  231. s.readPadding(length);
  232. }
  233. /**
  234. * @param length {integer} length of padding
  235. * @returns {type.BinaryString} per encoded padding
  236. */
  237. function writePadding(length) {
  238. return new type.BinaryString(Buffer.from(Array(length + 1).join("\x00")));
  239. }
  240. /**
  241. * @param s {type.Stream}
  242. * @param octetStream {String}
  243. * @param minValue {integer} default 0
  244. * @returns {Boolean} true if read octectStream is equal to octetStream
  245. */
  246. function readOctetStream(s, octetStream, minValue) {
  247. var size = readLength(s) + (minValue || 0);
  248. if(size !== octetStream.length) {
  249. return false;
  250. }
  251. for(var i = 0; i < size; i++) {
  252. var c = new type.UInt8().read(s);
  253. if(octetStream.charCodeAt(i) !== c.value) {
  254. return false;
  255. }
  256. }
  257. return true;
  258. }
  259. /**
  260. * @param oStr {String}
  261. * @param minValue {integer} default 0
  262. * @returns {type.Component} per encoded octet stream
  263. */
  264. function writeOctetStream(oStr, minValue) {
  265. minValue = minValue || 0;
  266. var length = oStr.length;
  267. var mlength = minValue;
  268. if(length - minValue >= 0) {
  269. mlength = length - minValue;
  270. }
  271. result = [];
  272. for(var i = 0; i < length; i++) {
  273. result[result.length] = new type.UInt8(oStr[i]);
  274. }
  275. return new type.Component([writeLength(mlength), new type.Component(result)]);
  276. }
  277. /**
  278. * Module exports
  279. */
  280. module.exports = {
  281. readLength : readLength,
  282. writeLength : writeLength,
  283. readChoice : readChoice,
  284. writeChoice : writeChoice,
  285. readSelection : readSelection,
  286. writeSelection : writeSelection,
  287. readNumberOfSet : readNumberOfSet,
  288. writeNumberOfSet : writeNumberOfSet,
  289. readEnumerates : readEnumerates,
  290. writeEnumerates : writeEnumerates,
  291. readInteger : readInteger,
  292. writeInteger : writeInteger,
  293. readInteger16 : readInteger16,
  294. writeInteger16 : writeInteger16,
  295. readObjectIdentifier : readObjectIdentifier,
  296. writeObjectIdentifier : writeObjectIdentifier,
  297. readNumericString : readNumericString,
  298. writeNumericString : writeNumericString,
  299. readPadding : readPadding,
  300. writePadding : writePadding,
  301. readOctetStream : readOctetStream,
  302. writeOctetStream : writeOctetStream
  303. };