Handshake.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. var Sequence = require('./Sequence');
  2. var Util = require('util');
  3. var Packets = require('../packets');
  4. var Auth = require('../Auth');
  5. var ClientConstants = require('../constants/client');
  6. module.exports = Handshake;
  7. Util.inherits(Handshake, Sequence);
  8. function Handshake(options, callback) {
  9. Sequence.call(this, options, callback);
  10. options = options || {};
  11. this._config = options.config;
  12. this._handshakeInitializationPacket = null;
  13. }
  14. Handshake.prototype.determinePacket = function determinePacket(firstByte, parser) {
  15. if (firstByte === 0xff) {
  16. return Packets.ErrorPacket;
  17. }
  18. if (!this._handshakeInitializationPacket) {
  19. return Packets.HandshakeInitializationPacket;
  20. }
  21. if (firstByte === 0xfe) {
  22. return (parser.packetLength() === 1)
  23. ? Packets.UseOldPasswordPacket
  24. : Packets.AuthSwitchRequestPacket;
  25. }
  26. return undefined;
  27. };
  28. Handshake.prototype['AuthSwitchRequestPacket'] = function (packet) {
  29. var name = packet.authMethodName;
  30. var data = Auth.auth(name, packet.authMethodData, {
  31. password: this._config.password
  32. });
  33. if (data !== undefined) {
  34. this.emit('packet', new Packets.AuthSwitchResponsePacket({
  35. data: data
  36. }));
  37. } else {
  38. var err = new Error('MySQL is requesting the ' + name + ' authentication method, which is not supported.');
  39. err.code = 'UNSUPPORTED_AUTH_METHOD';
  40. err.fatal = true;
  41. this.end(err);
  42. }
  43. };
  44. Handshake.prototype['HandshakeInitializationPacket'] = function(packet) {
  45. this._handshakeInitializationPacket = packet;
  46. this._config.protocol41 = packet.protocol41;
  47. var serverSSLSupport = packet.serverCapabilities1 & ClientConstants.CLIENT_SSL;
  48. if (this._config.ssl) {
  49. if (!serverSSLSupport) {
  50. var err = new Error('Server does not support secure connection');
  51. err.code = 'HANDSHAKE_NO_SSL_SUPPORT';
  52. err.fatal = true;
  53. this.end(err);
  54. return;
  55. }
  56. this._config.clientFlags |= ClientConstants.CLIENT_SSL;
  57. this.emit('packet', new Packets.SSLRequestPacket({
  58. clientFlags : this._config.clientFlags,
  59. maxPacketSize : this._config.maxPacketSize,
  60. charsetNumber : this._config.charsetNumber
  61. }));
  62. this.emit('start-tls');
  63. } else {
  64. this._sendCredentials();
  65. }
  66. };
  67. Handshake.prototype._tlsUpgradeCompleteHandler = function() {
  68. this._sendCredentials();
  69. };
  70. Handshake.prototype._sendCredentials = function() {
  71. var packet = this._handshakeInitializationPacket;
  72. this.emit('packet', new Packets.ClientAuthenticationPacket({
  73. clientFlags : this._config.clientFlags,
  74. maxPacketSize : this._config.maxPacketSize,
  75. charsetNumber : this._config.charsetNumber,
  76. user : this._config.user,
  77. database : this._config.database,
  78. protocol41 : packet.protocol41,
  79. scrambleBuff : (packet.protocol41)
  80. ? Auth.token(this._config.password, packet.scrambleBuff())
  81. : Auth.scramble323(packet.scrambleBuff(), this._config.password)
  82. }));
  83. };
  84. Handshake.prototype['UseOldPasswordPacket'] = function() {
  85. if (!this._config.insecureAuth) {
  86. var err = new Error(
  87. 'MySQL server is requesting the old and insecure pre-4.1 auth mechanism. ' +
  88. 'Upgrade the user password or use the {insecureAuth: true} option.'
  89. );
  90. err.code = 'HANDSHAKE_INSECURE_AUTH';
  91. err.fatal = true;
  92. this.end(err);
  93. return;
  94. }
  95. this.emit('packet', new Packets.OldPasswordPacket({
  96. scrambleBuff: Auth.scramble323(this._handshakeInitializationPacket.scrambleBuff(), this._config.password)
  97. }));
  98. };
  99. Handshake.prototype['ErrorPacket'] = function(packet) {
  100. var err = this._packetToError(packet, true);
  101. err.fatal = true;
  102. this.end(err);
  103. };