SshEncoder.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.SshEncoder = void 0;
  4. const JsonPackMpint_1 = require("../JsonPackMpint");
  5. class SshEncoder {
  6. constructor(writer) {
  7. this.writer = writer;
  8. }
  9. encode(value) {
  10. const writer = this.writer;
  11. writer.reset();
  12. this.writeAny(value);
  13. return writer.flush();
  14. }
  15. writeUnknown(value) {
  16. throw new Error('SSH encoder does not support unknown types');
  17. }
  18. writeAny(value) {
  19. switch (typeof value) {
  20. case 'boolean':
  21. return this.writeBoolean(value);
  22. case 'number':
  23. return this.writeNumber(value);
  24. case 'string':
  25. return this.writeStr(value);
  26. case 'object': {
  27. if (value === null)
  28. return this.writeNull();
  29. const constructor = value.constructor;
  30. switch (constructor) {
  31. case Uint8Array:
  32. return this.writeBin(value);
  33. case Array:
  34. return this.writeNameList(value);
  35. case JsonPackMpint_1.JsonPackMpint:
  36. return this.writeMpint(value);
  37. default:
  38. return this.writeUnknown(value);
  39. }
  40. }
  41. case 'bigint':
  42. return this.writeUint64(value);
  43. case 'undefined':
  44. return this.writeNull();
  45. default:
  46. return this.writeUnknown(value);
  47. }
  48. }
  49. writeNull() {
  50. throw new Error('SSH protocol does not have a null type');
  51. }
  52. writeBoolean(bool) {
  53. this.writer.u8(bool ? 1 : 0);
  54. }
  55. writeByte(byte) {
  56. this.writer.u8(byte & 0xff);
  57. }
  58. writeUint32(uint) {
  59. const writer = this.writer;
  60. writer.ensureCapacity(4);
  61. writer.view.setUint32(writer.x, Math.trunc(uint) >>> 0, false);
  62. writer.move(4);
  63. }
  64. writeUint64(uint) {
  65. const writer = this.writer;
  66. writer.ensureCapacity(8);
  67. if (typeof uint === 'bigint') {
  68. writer.view.setBigUint64(writer.x, uint, false);
  69. }
  70. else {
  71. const truncated = Math.trunc(Math.abs(uint));
  72. const high = Math.floor(truncated / 0x100000000);
  73. const low = truncated >>> 0;
  74. writer.view.setUint32(writer.x, high, false);
  75. writer.view.setUint32(writer.x + 4, low, false);
  76. }
  77. writer.move(8);
  78. }
  79. writeBinStr(data) {
  80. this.writeUint32(data.length);
  81. this.writer.buf(data, data.length);
  82. }
  83. writeStr(str) {
  84. const writer = this.writer;
  85. const maxSize = str.length * 4;
  86. writer.ensureCapacity(4 + maxSize);
  87. const lengthOffset = writer.x;
  88. writer.x += 4;
  89. const bytesWritten = writer.utf8(str);
  90. const endPos = writer.x;
  91. writer.x = lengthOffset;
  92. this.writeUint32(bytesWritten);
  93. writer.x = endPos;
  94. }
  95. writeAsciiStr(str) {
  96. const writer = this.writer;
  97. writer.ensureCapacity(4 + str.length);
  98. this.writeUint32(str.length);
  99. for (let i = 0; i < str.length; i++) {
  100. writer.u8(str.charCodeAt(i) & 0x7f);
  101. }
  102. }
  103. writeMpint(mpint) {
  104. this.writeUint32(mpint.data.length);
  105. this.writer.buf(mpint.data, mpint.data.length);
  106. }
  107. writeNameList(names) {
  108. const nameListStr = names.join(',');
  109. this.writeAsciiStr(nameListStr);
  110. }
  111. writeNumber(num) {
  112. if (Number.isInteger(num)) {
  113. if (num >= 0 && num <= 0xffffffff) {
  114. this.writeUint32(num);
  115. }
  116. else {
  117. this.writeUint64(num);
  118. }
  119. }
  120. else {
  121. throw new Error('SSH protocol does not support floating point numbers');
  122. }
  123. }
  124. writeInteger(int) {
  125. this.writeUint32(int);
  126. }
  127. writeUInteger(uint) {
  128. this.writeUint32(uint);
  129. }
  130. writeFloat(float) {
  131. throw new Error('SSH protocol does not support floating point numbers');
  132. }
  133. writeBin(buf) {
  134. this.writeBinStr(buf);
  135. }
  136. writeArr(arr) {
  137. throw new Error('SSH protocol does not have a generic array type. Use writeNameList for name-list type.');
  138. }
  139. writeObj(obj) {
  140. throw new Error('SSH protocol does not have an object type');
  141. }
  142. }
  143. exports.SshEncoder = SshEncoder;
  144. //# sourceMappingURL=SshEncoder.js.map