From 5b1f8aff3b61a6109f92fae0166d0e0585b9cab4 Mon Sep 17 00:00:00 2001 From: brianc Date: Fri, 22 Oct 2010 18:16:40 -0500 Subject: [PATCH] supporting md5 password authentication --- lib/client.js | 19 +++++++++++++++++++ test/unit/authentication-tests.js | 28 +++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/lib/client.js b/lib/client.js index e3eb79a3..2a9a50a3 100644 --- a/lib/client.js +++ b/lib/client.js @@ -2,6 +2,7 @@ var EventEmitter = require('events').EventEmitter; var net = require('net'); var Query = require(__dirname+'/query'); var sys = require('sys'); +var crypto = require('crypto'); var Client = function(config) { EventEmitter.call(this); @@ -52,6 +53,14 @@ p.connect = function() { self.send('p', new Buffer(self.password + '\0', self.encoding)); }); + this.on('authenticationMD5Password', function(msg) { + var enc = function(string) { + return crypto.createHash('md5').update(string).digest('hex'); + } + var md5password = "md5" + enc(enc(self.password + self.user) + msg.salt.toString('binary')) + "\0"; + self.send('p', new Buffer(md5password, self.encoding)); + }); + this.on('readyForQuery', function() { self.readyForQuery = true; self.pulseQueryQueue(); @@ -180,6 +189,16 @@ p.parseR = function(msg) { } return msg; } + if(msg.length == 12) { + code = this.parseInt32(); + if(code == 5) { //md5 required + msg.name = 'authenticationMD5Password'; + msg.salt = new Buffer(4); + this.buffer.copy(msg.salt, 0, this.offset, this.offset + 4); + this.offset += 4; + return msg; + } + } throw new Error("Unknown authenticatinOk message type" + sys.inspect(msg)); }; diff --git a/test/unit/authentication-tests.js b/test/unit/authentication-tests.js index 522126eb..80ba98b4 100644 --- a/test/unit/authentication-tests.js +++ b/test/unit/authentication-tests.js @@ -1,3 +1,4 @@ + require(__dirname+'/test-helper'); test('password authentication', function(){ @@ -28,5 +29,30 @@ test('password authentication', function(){ }); test('md5 authentication', function() { - return false; + var client = createClient(); + client.password = "!"; + + var md5PasswordBuffer = Buffer([0x52, 0, 0, 0, 12, 0, 0, 0, 5, 1, 2, 3, 4]); + + var raised = false; + + client.on('authenticationMD5Password', function(msg) { + raised = true; + assert.equalBuffers(msg.salt, new Buffer([1,2,3,4])); + }); + + client.stream.emit('data', md5PasswordBuffer); + + test('raises event', function() { + assert.ok(raised); + }); + + test('responds', function() { + assert.length(client.stream.packets, 1); + test('should have correct encrypted data', function() { + //how do we want to test this? + return false; + }); + }); + });