132 lines
4.0 KiB
JavaScript
132 lines
4.0 KiB
JavaScript
var util = require('util');
|
|
|
|
var ClientConstants = require('../constants/client.js');
|
|
var CommandCode = require('../constants/commands.js');
|
|
|
|
var Command = require('./command.js');
|
|
var Packets = require('../packets/index.js');
|
|
var auth41 = require('../auth_41.js');
|
|
|
|
function ServerHandshake(args)
|
|
{
|
|
Command.call(this);
|
|
this.args = args;
|
|
/*
|
|
this.protocolVersion = args.protocolVersion || 10;
|
|
this.serverVersion = args.serverVersion;
|
|
this.connectionId = args.connectionId,
|
|
this.statusFlags = args.statusFlags,
|
|
this.characterSet = args.characterSet,
|
|
this.capabilityFlags = args.capabilityFlags || 512;
|
|
*/
|
|
}
|
|
util.inherits(ServerHandshake, Command);
|
|
|
|
ServerHandshake.prototype.start = function(packet, connection) {
|
|
var serverHelloPacket = new Packets.Handshake(this.args);
|
|
this.serverHello = serverHelloPacket;
|
|
serverHelloPacket.setScrambleData(function(err) {
|
|
if (err)
|
|
return connection.emit('error', new Error('Error generating random bytes'));
|
|
connection.writePacket(serverHelloPacket.toPacket(0));
|
|
});
|
|
return ServerHandshake.prototype.readClientReply;
|
|
};
|
|
|
|
ServerHandshake.prototype.readClientReply = function(packet, connection) {
|
|
// check auth here
|
|
var clientHelloReply = new Packets.HandshakeResponse.fromPacket(packet);
|
|
if (this.args.authCallback) {
|
|
try {
|
|
this.args.authCallback({
|
|
user: clientHelloReply.user,
|
|
database: clientHelloReply.database,
|
|
address: connection.stream.remoteAddress,
|
|
authPluginData1: this.serverHello.authPluginData1,
|
|
authPluginData2: this.serverHello.authPluginData2,
|
|
authToken: clientHelloReply.authToken,
|
|
}, function(err, mysqlError) {
|
|
//if (err)
|
|
if (!mysqlError)
|
|
connection.writeOk();
|
|
else {
|
|
// TODO create constants / errorToCode
|
|
// 1045 = ER_ACCESS_DENIED_ERROR
|
|
connection.writeError({ message: mysqlError.message || '', code: mysqlError.code || 1045 });
|
|
connection.close();
|
|
}
|
|
});
|
|
} catch(err) {
|
|
throw err;
|
|
// TODO
|
|
// connection.writeError(err)
|
|
}
|
|
} else {
|
|
connection.writeOk();
|
|
}
|
|
return ServerHandshake.prototype.dispatchCommands;
|
|
};
|
|
|
|
ServerHandshake.prototype.dispatchCommands = function(packet, connection) {
|
|
// command from client to server
|
|
var commandCode = packet.readInt8();
|
|
switch (commandCode) {
|
|
case CommandCode.QUIT:
|
|
connection.stream.end();
|
|
break;
|
|
case CommandCode.INIT_DB:
|
|
var schemaName = packet.readString();
|
|
connection.emit('init_db', schemaName);
|
|
connection.writeOk();
|
|
break;
|
|
case CommandCode.PING:
|
|
// allow custom ping response (delayed/incorrect/etc)
|
|
// if no listeners, respond with OK
|
|
if (connection.listeners('ping').length === 0) {
|
|
connection.writeOk();
|
|
} else {
|
|
connection.emit('ping');
|
|
}
|
|
break;
|
|
case CommandCode.QUERY:
|
|
var query = packet.readString();
|
|
connection.emit('query', query);
|
|
break;
|
|
case CommandCode.FIELD_LIST:
|
|
var table = packet.readNullTerminatedString();
|
|
var fields = packet.readString();
|
|
connection.emit('field_list', table, fields);
|
|
break;
|
|
default:
|
|
console.log('Unknown command:', commandCode);
|
|
}
|
|
return ServerHandshake.prototype.dispatchCommands;
|
|
};
|
|
|
|
module.exports = ServerHandshake;
|
|
|
|
// TODO: implement server-side 4.1 authentication
|
|
/*
|
|
4.1 authentication: (http://bazaar.launchpad.net/~mysql/mysql-server/5.5/view/head:/sql/password.c)
|
|
|
|
SERVER: public_seed=create_random_string()
|
|
send(public_seed)
|
|
|
|
CLIENT: recv(public_seed)
|
|
hash_stage1=sha1("password")
|
|
hash_stage2=sha1(hash_stage1)
|
|
reply=xor(hash_stage1, sha1(public_seed,hash_stage2)
|
|
|
|
// this three steps are done in scramble()
|
|
|
|
send(reply)
|
|
|
|
|
|
SERVER: recv(reply)
|
|
hash_stage1=xor(reply, sha1(public_seed,hash_stage2))
|
|
candidate_hash2=sha1(hash_stage1)
|
|
check(candidate_hash2==hash_stage2)
|
|
|
|
server stores sha1(sha1(password)) ( hash_stag2)
|
|
*/
|