HandshakeInitializationPacket.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. var Buffer = require('safe-buffer').Buffer;
  2. var Client = require('../constants/client');
  3. module.exports = HandshakeInitializationPacket;
  4. function HandshakeInitializationPacket(options) {
  5. options = options || {};
  6. this.protocolVersion = options.protocolVersion;
  7. this.serverVersion = options.serverVersion;
  8. this.threadId = options.threadId;
  9. this.scrambleBuff1 = options.scrambleBuff1;
  10. this.filler1 = options.filler1;
  11. this.serverCapabilities1 = options.serverCapabilities1;
  12. this.serverLanguage = options.serverLanguage;
  13. this.serverStatus = options.serverStatus;
  14. this.serverCapabilities2 = options.serverCapabilities2;
  15. this.scrambleLength = options.scrambleLength;
  16. this.filler2 = options.filler2;
  17. this.scrambleBuff2 = options.scrambleBuff2;
  18. this.filler3 = options.filler3;
  19. this.pluginData = options.pluginData;
  20. this.protocol41 = options.protocol41;
  21. if (this.protocol41) {
  22. // force set the bit in serverCapabilities1
  23. this.serverCapabilities1 |= Client.CLIENT_PROTOCOL_41;
  24. }
  25. }
  26. HandshakeInitializationPacket.prototype.parse = function(parser) {
  27. this.protocolVersion = parser.parseUnsignedNumber(1);
  28. this.serverVersion = parser.parseNullTerminatedString();
  29. this.threadId = parser.parseUnsignedNumber(4);
  30. this.scrambleBuff1 = parser.parseBuffer(8);
  31. this.filler1 = parser.parseFiller(1);
  32. this.serverCapabilities1 = parser.parseUnsignedNumber(2);
  33. this.serverLanguage = parser.parseUnsignedNumber(1);
  34. this.serverStatus = parser.parseUnsignedNumber(2);
  35. this.protocol41 = (this.serverCapabilities1 & (1 << 9)) > 0;
  36. if (this.protocol41) {
  37. this.serverCapabilities2 = parser.parseUnsignedNumber(2);
  38. this.scrambleLength = parser.parseUnsignedNumber(1);
  39. this.filler2 = parser.parseFiller(10);
  40. // scrambleBuff2 should be 0x00 terminated, but sphinx does not do this
  41. // so we assume scrambleBuff2 to be 12 byte and treat the next byte as a
  42. // filler byte.
  43. this.scrambleBuff2 = parser.parseBuffer(12);
  44. this.filler3 = parser.parseFiller(1);
  45. } else {
  46. this.filler2 = parser.parseFiller(13);
  47. }
  48. if (parser.reachedPacketEnd()) {
  49. return;
  50. }
  51. // According to the docs this should be 0x00 terminated, but MariaDB does
  52. // not do this, so we assume this string to be packet terminated.
  53. this.pluginData = parser.parsePacketTerminatedString();
  54. // However, if there is a trailing '\0', strip it
  55. var lastChar = this.pluginData.length - 1;
  56. if (this.pluginData[lastChar] === '\0') {
  57. this.pluginData = this.pluginData.substr(0, lastChar);
  58. }
  59. };
  60. HandshakeInitializationPacket.prototype.write = function(writer) {
  61. writer.writeUnsignedNumber(1, this.protocolVersion);
  62. writer.writeNullTerminatedString(this.serverVersion);
  63. writer.writeUnsignedNumber(4, this.threadId);
  64. writer.writeBuffer(this.scrambleBuff1);
  65. writer.writeFiller(1);
  66. writer.writeUnsignedNumber(2, this.serverCapabilities1);
  67. writer.writeUnsignedNumber(1, this.serverLanguage);
  68. writer.writeUnsignedNumber(2, this.serverStatus);
  69. if (this.protocol41) {
  70. writer.writeUnsignedNumber(2, this.serverCapabilities2);
  71. writer.writeUnsignedNumber(1, this.scrambleLength);
  72. writer.writeFiller(10);
  73. }
  74. writer.writeNullTerminatedBuffer(this.scrambleBuff2);
  75. if (this.pluginData !== undefined) {
  76. writer.writeNullTerminatedString(this.pluginData);
  77. }
  78. };
  79. HandshakeInitializationPacket.prototype.scrambleBuff = function() {
  80. var buffer = null;
  81. if (typeof this.scrambleBuff2 === 'undefined') {
  82. buffer = Buffer.from(this.scrambleBuff1);
  83. } else {
  84. buffer = Buffer.allocUnsafe(this.scrambleBuff1.length + this.scrambleBuff2.length);
  85. this.scrambleBuff1.copy(buffer, 0);
  86. this.scrambleBuff2.copy(buffer, this.scrambleBuff1.length);
  87. }
  88. return buffer;
  89. };