127 lines
3.6 KiB
JavaScript
127 lines
3.6 KiB
JavaScript
|
var Sequence = require('./Sequence');
|
||
|
var Util = require('util');
|
||
|
var Packets = require('../packets');
|
||
|
var Auth = require('../Auth');
|
||
|
var ClientConstants = require('../constants/client');
|
||
|
|
||
|
module.exports = Handshake;
|
||
|
Util.inherits(Handshake, Sequence);
|
||
|
function Handshake(options, callback) {
|
||
|
Sequence.call(this, options, callback);
|
||
|
|
||
|
options = options || {};
|
||
|
|
||
|
this._config = options.config;
|
||
|
this._handshakeInitializationPacket = null;
|
||
|
}
|
||
|
|
||
|
Handshake.prototype.determinePacket = function determinePacket(firstByte, parser) {
|
||
|
if (firstByte === 0xff) {
|
||
|
return Packets.ErrorPacket;
|
||
|
}
|
||
|
|
||
|
if (!this._handshakeInitializationPacket) {
|
||
|
return Packets.HandshakeInitializationPacket;
|
||
|
}
|
||
|
|
||
|
if (firstByte === 0xfe) {
|
||
|
return (parser.packetLength() === 1)
|
||
|
? Packets.UseOldPasswordPacket
|
||
|
: Packets.AuthSwitchRequestPacket;
|
||
|
}
|
||
|
|
||
|
return undefined;
|
||
|
};
|
||
|
|
||
|
Handshake.prototype['AuthSwitchRequestPacket'] = function (packet) {
|
||
|
var name = packet.authMethodName;
|
||
|
var data = Auth.auth(name, packet.authMethodData, {
|
||
|
password: this._config.password
|
||
|
});
|
||
|
|
||
|
if (data !== undefined) {
|
||
|
this.emit('packet', new Packets.AuthSwitchResponsePacket({
|
||
|
data: data
|
||
|
}));
|
||
|
} else {
|
||
|
var err = new Error('MySQL is requesting the ' + name + ' authentication method, which is not supported.');
|
||
|
err.code = 'UNSUPPORTED_AUTH_METHOD';
|
||
|
err.fatal = true;
|
||
|
this.end(err);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
Handshake.prototype['HandshakeInitializationPacket'] = function(packet) {
|
||
|
this._handshakeInitializationPacket = packet;
|
||
|
|
||
|
this._config.protocol41 = packet.protocol41;
|
||
|
|
||
|
var serverSSLSupport = packet.serverCapabilities1 & ClientConstants.CLIENT_SSL;
|
||
|
|
||
|
if (this._config.ssl) {
|
||
|
if (!serverSSLSupport) {
|
||
|
var err = new Error('Server does not support secure connection');
|
||
|
|
||
|
err.code = 'HANDSHAKE_NO_SSL_SUPPORT';
|
||
|
err.fatal = true;
|
||
|
|
||
|
this.end(err);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this._config.clientFlags |= ClientConstants.CLIENT_SSL;
|
||
|
this.emit('packet', new Packets.SSLRequestPacket({
|
||
|
clientFlags : this._config.clientFlags,
|
||
|
maxPacketSize : this._config.maxPacketSize,
|
||
|
charsetNumber : this._config.charsetNumber
|
||
|
}));
|
||
|
this.emit('start-tls');
|
||
|
} else {
|
||
|
this._sendCredentials();
|
||
|
}
|
||
|
};
|
||
|
|
||
|
Handshake.prototype._tlsUpgradeCompleteHandler = function() {
|
||
|
this._sendCredentials();
|
||
|
};
|
||
|
|
||
|
Handshake.prototype._sendCredentials = function() {
|
||
|
var packet = this._handshakeInitializationPacket;
|
||
|
this.emit('packet', new Packets.ClientAuthenticationPacket({
|
||
|
clientFlags : this._config.clientFlags,
|
||
|
maxPacketSize : this._config.maxPacketSize,
|
||
|
charsetNumber : this._config.charsetNumber,
|
||
|
user : this._config.user,
|
||
|
database : this._config.database,
|
||
|
protocol41 : packet.protocol41,
|
||
|
scrambleBuff : (packet.protocol41)
|
||
|
? Auth.token(this._config.password, packet.scrambleBuff())
|
||
|
: Auth.scramble323(packet.scrambleBuff(), this._config.password)
|
||
|
}));
|
||
|
};
|
||
|
|
||
|
Handshake.prototype['UseOldPasswordPacket'] = function() {
|
||
|
if (!this._config.insecureAuth) {
|
||
|
var err = new Error(
|
||
|
'MySQL server is requesting the old and insecure pre-4.1 auth mechanism. ' +
|
||
|
'Upgrade the user password or use the {insecureAuth: true} option.'
|
||
|
);
|
||
|
|
||
|
err.code = 'HANDSHAKE_INSECURE_AUTH';
|
||
|
err.fatal = true;
|
||
|
|
||
|
this.end(err);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
this.emit('packet', new Packets.OldPasswordPacket({
|
||
|
scrambleBuff: Auth.scramble323(this._handshakeInitializationPacket.scrambleBuff(), this._config.password)
|
||
|
}));
|
||
|
};
|
||
|
|
||
|
Handshake.prototype['ErrorPacket'] = function(packet) {
|
||
|
var err = this._packetToError(packet, true);
|
||
|
err.fatal = true;
|
||
|
this.end(err);
|
||
|
};
|