You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

149 lines
3.8 KiB

  1. // Copyright 2015 Joyent, Inc.
  2. module.exports = SSHBuffer;
  3. var assert = require('assert-plus');
  4. var Buffer = require('safer-buffer').Buffer;
  5. function SSHBuffer(opts) {
  6. assert.object(opts, 'options');
  7. if (opts.buffer !== undefined)
  8. assert.buffer(opts.buffer, 'options.buffer');
  9. this._size = opts.buffer ? opts.buffer.length : 1024;
  10. this._buffer = opts.buffer || Buffer.alloc(this._size);
  11. this._offset = 0;
  12. }
  13. SSHBuffer.prototype.toBuffer = function () {
  14. return (this._buffer.slice(0, this._offset));
  15. };
  16. SSHBuffer.prototype.atEnd = function () {
  17. return (this._offset >= this._buffer.length);
  18. };
  19. SSHBuffer.prototype.remainder = function () {
  20. return (this._buffer.slice(this._offset));
  21. };
  22. SSHBuffer.prototype.skip = function (n) {
  23. this._offset += n;
  24. };
  25. SSHBuffer.prototype.expand = function () {
  26. this._size *= 2;
  27. var buf = Buffer.alloc(this._size);
  28. this._buffer.copy(buf, 0);
  29. this._buffer = buf;
  30. };
  31. SSHBuffer.prototype.readPart = function () {
  32. return ({data: this.readBuffer()});
  33. };
  34. SSHBuffer.prototype.readBuffer = function () {
  35. var len = this._buffer.readUInt32BE(this._offset);
  36. this._offset += 4;
  37. assert.ok(this._offset + len <= this._buffer.length,
  38. 'length out of bounds at +0x' + this._offset.toString(16) +
  39. ' (data truncated?)');
  40. var buf = this._buffer.slice(this._offset, this._offset + len);
  41. this._offset += len;
  42. return (buf);
  43. };
  44. SSHBuffer.prototype.readString = function () {
  45. return (this.readBuffer().toString());
  46. };
  47. SSHBuffer.prototype.readCString = function () {
  48. var offset = this._offset;
  49. while (offset < this._buffer.length &&
  50. this._buffer[offset] !== 0x00)
  51. offset++;
  52. assert.ok(offset < this._buffer.length, 'c string does not terminate');
  53. var str = this._buffer.slice(this._offset, offset).toString();
  54. this._offset = offset + 1;
  55. return (str);
  56. };
  57. SSHBuffer.prototype.readInt = function () {
  58. var v = this._buffer.readUInt32BE(this._offset);
  59. this._offset += 4;
  60. return (v);
  61. };
  62. SSHBuffer.prototype.readInt64 = function () {
  63. assert.ok(this._offset + 8 < this._buffer.length,
  64. 'buffer not long enough to read Int64');
  65. var v = this._buffer.slice(this._offset, this._offset + 8);
  66. this._offset += 8;
  67. return (v);
  68. };
  69. SSHBuffer.prototype.readChar = function () {
  70. var v = this._buffer[this._offset++];
  71. return (v);
  72. };
  73. SSHBuffer.prototype.writeBuffer = function (buf) {
  74. while (this._offset + 4 + buf.length > this._size)
  75. this.expand();
  76. this._buffer.writeUInt32BE(buf.length, this._offset);
  77. this._offset += 4;
  78. buf.copy(this._buffer, this._offset);
  79. this._offset += buf.length;
  80. };
  81. SSHBuffer.prototype.writeString = function (str) {
  82. this.writeBuffer(Buffer.from(str, 'utf8'));
  83. };
  84. SSHBuffer.prototype.writeCString = function (str) {
  85. while (this._offset + 1 + str.length > this._size)
  86. this.expand();
  87. this._buffer.write(str, this._offset);
  88. this._offset += str.length;
  89. this._buffer[this._offset++] = 0;
  90. };
  91. SSHBuffer.prototype.writeInt = function (v) {
  92. while (this._offset + 4 > this._size)
  93. this.expand();
  94. this._buffer.writeUInt32BE(v, this._offset);
  95. this._offset += 4;
  96. };
  97. SSHBuffer.prototype.writeInt64 = function (v) {
  98. assert.buffer(v, 'value');
  99. if (v.length > 8) {
  100. var lead = v.slice(0, v.length - 8);
  101. for (var i = 0; i < lead.length; ++i) {
  102. assert.strictEqual(lead[i], 0,
  103. 'must fit in 64 bits of precision');
  104. }
  105. v = v.slice(v.length - 8, v.length);
  106. }
  107. while (this._offset + 8 > this._size)
  108. this.expand();
  109. v.copy(this._buffer, this._offset);
  110. this._offset += 8;
  111. };
  112. SSHBuffer.prototype.writeChar = function (v) {
  113. while (this._offset + 1 > this._size)
  114. this.expand();
  115. this._buffer[this._offset++] = v;
  116. };
  117. SSHBuffer.prototype.writePart = function (p) {
  118. this.writeBuffer(p.data);
  119. };
  120. SSHBuffer.prototype.write = function (buf) {
  121. while (this._offset + buf.length > this._size)
  122. this.expand();
  123. buf.copy(this._buffer, this._offset);
  124. this._offset += buf.length;
  125. };