var ClientConstants = require('../constants/client'); var Charsets = require('../constants/charsets'); var crypto = require('crypto'); var Packet = require('../packets/packet'); function sha1(msg, msg1, msg2) { var hash = crypto.createHash('sha1'); hash.update(msg); if (msg1) hash.update(msg1); if (msg2) hash.update(msg2); return hash.digest('binary'); } function xor(a, b) { if (!Buffer.isBuffer(a)) a = new Buffer(a, 'binary'); if (!Buffer.isBuffer(b)) b = new Buffer(b, 'binary'); var result = new Buffer(a.length); for (var i = 0; i < a.length; i++) { result[i] = (a[i] ^ b[i]); } return result; } function token(password, scramble1, scramble2) { var scramble = Buffer(scramble1.toString('binary') + scramble2.toString('binary')); if (!password) { return new Buffer(0); } var stage1 = sha1(Buffer(password, "utf8").toString('binary')); var stage2 = sha1(stage1); var stage3 = sha1(scramble1, scramble2, stage2); return xor(stage3, stage1); } function HandshakeResponse(handshake) { this.user = handshake.user || ''; this.database = handshake.database || ''; this.password = handshake.password || ''; this.authPluginData1 = handshake.authPluginData1; this.authPluginData2 = handshake.authPluginData2; this.compress = handshake.compress; this.clientFlags = handshake.flags; this.authToken = token(this.password, this.authPluginData1, this.authPluginData2); this.charsetNumber = handshake.charsetNumber; } HandshakeResponse.prototype.toPacket = function() { if (typeof this.user != 'string') throw new Error('"user" connection config prperty must be a string'); if (typeof this.database != 'string') throw new Error('"database" connection config prperty must be a string'); var length = 36 + 23 + this.user.length + this.database.length; var buffer = new Buffer(length); var packet = new Packet(0, buffer); buffer.fill(0); packet.offset = 4; packet.writeInt32(this.clientFlags); packet.writeInt32(0); // max packet size. todo: move to config packet.writeInt8(this.charsetNumber); packet.skip(23); packet.writeNullTerminatedString(this.user); packet.writeInt8(this.authToken.length); packet.writeBuffer(this.authToken); packet.writeNullTerminatedString(this.database); return packet; }; module.exports = HandshakeResponse;