From 34f20f423f821c55b0090421bb2ee551cfe32c16 Mon Sep 17 00:00:00 2001 From: calzoneman Date: Tue, 26 Mar 2013 14:12:02 -0500 Subject: [PATCH] Transition to using bcrypt for password hashing/storage --- README.md | 6 ++++-- auth.js | 37 ++++++++++++++++++++++++++++++------- server.js | 1 + user.js | 18 +++++++++--------- www/assets/js/client.js | 20 +++++++------------- 5 files changed, 51 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index c1ac55d9..00fe85ed 100644 --- a/README.md +++ b/README.md @@ -30,8 +30,10 @@ I'm using v0.10, please feel free to report which versions do/do not work 4. Install connect: `npm install connect` 5. Install your distribution's `libmysqlclient` package 6. Install the libmysql node module: `npm install mysql-libmysqlclient` - 7. Edit `config.js` and input your database details and connection port - 8. Edit `www/assets/js/iourl.js` and change the value of `IO_URL` to `yourhostname:port` where `port` is the port defined in `config.js` + 7. Install bcrypt: `npm install bcrypt` + 8. Install node_hash: `npm install node_hash` + 9. Edit `config.js` and input your database details and connection port + 10. Edit `www/assets/js/iourl.js` and change the value of `IO_URL` to `yourhostname:port` where `port` is the port defined in `config.js` Running ------- diff --git a/auth.js b/auth.js index a3cef709..9e02e873 100644 --- a/auth.js +++ b/auth.js @@ -11,6 +11,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI var mysql = require("mysql-libmysqlclient"); var Config = require("./config.js"); +var bcrypt = require("bcrypt"); +var hashlib = require("node_hash"); // Check if a name is taken exports.isRegistered = function(name) { @@ -39,7 +41,7 @@ exports.validateName = function(name) { } // Try to register a new account -exports.register = function(name, sha256) { +exports.register = function(name, pw) { if(!exports.validateName(name)) return false; if(exports.isRegistered(name)) @@ -51,16 +53,17 @@ exports.register = function(name, sha256) { console.log("MySQL Connection Failed"); return false; } + var hash = bcrypt.hashSync(pw, 10); var query = "INSERT INTO registrations VALUES (NULL, '{1}', '{2}', 0)" .replace(/\{1\}/, name) - .replace(/\{2\}/, sha256); + .replace(/\{2\}/, hash); var results = db.querySync(query); db.closeSync(); return results; } // Try to login -exports.login = function(name, sha256) { +exports.login = function(name, pw) { var db = mysql.createConnectionSync(); db.connectSync(Config.MYSQL_SERVER, Config.MYSQL_USER, Config.MYSQL_PASSWORD, Config.MYSQL_DB); @@ -68,14 +71,34 @@ exports.login = function(name, sha256) { console.log("MySQL Connection Failed"); return false; } - var query = "SELECT * FROM registrations WHERE uname='{1}' AND pw='{2}'" + var query = "SELECT * FROM registrations WHERE uname='{1}'" .replace(/\{1\}/, name) - .replace(/\{2\}/, sha256); var results = db.querySync(query); var rows = results.fetchAllSync(); - db.closeSync(); if(rows.length > 0) { - return rows[0]; + if(bcrypt.compareSync(pw, rows[0].pw)) { + db.closeSync(); + return rows[0]; + } + else { + // Check if the sha256 is in the database + // If so, migrate to bcrypt + var sha256 = hashlib.sha256(pw); + if(sha256 == rows[0].pw) { + var newhash = bcrypt.hashSync(pw, 10); + var query = "UPDATE registrations SET pw='{1}' WHERE uname='{2}'" + .replace(/\{1\}/, newhash) + .replace(/\{2\}/, name); + var results = db.querySync(query); + db.closeSync(); + if(!results) { + console.log("Failed to migrate password! user=", name); + return false; + } + return rows[0]; + } + return false; + } } return false; } diff --git a/server.js b/server.js index 2528b4d8..762d598e 100644 --- a/server.js +++ b/server.js @@ -13,6 +13,7 @@ var Config = require("./config.js"); var connect = require("connect"); var app = connect.createServer(connect.static(__dirname+"/www")).listen(Config.IO_PORT); exports.io = require("socket.io").listen(app); +exports.io.set("log level", 1); var User = require("./user.js").User; var Database = require("./database.js"); Database.init(); diff --git a/user.js b/user.js index 92e9d2f8..2d8c1577 100644 --- a/user.js +++ b/user.js @@ -58,11 +58,11 @@ User.prototype.initCallbacks = function() { this.socket.on("login", function(data) { if(this.name == "") - this.login(data.name, data.sha256); + this.login(data.name, data.pw); }.bind(this)); this.socket.on("register", function(data) { - this.register(data.name, data.sha256); + this.register(data.name, data.pw); }.bind(this)); this.socket.on("assignLeader", function(data) { @@ -272,7 +272,7 @@ User.prototype.handleAdm = function(data) { }; // Attempt to login -User.prototype.login = function(name, sha256) { +User.prototype.login = function(name, pw) { if(this.channel != null && name != "") { for(var i = 0; i < this.channel.users.length; i++) { if(this.channel.users[i].name == name) { @@ -285,7 +285,7 @@ User.prototype.login = function(name, sha256) { } } // No password => try guest login - if(sha256 == "") { + if(pw == "") { // Sorry bud, can"t take that name if(Auth.isRegistered(name)) { this.socket.emit("login", { @@ -321,7 +321,7 @@ User.prototype.login = function(name, sha256) { } else { var row; - if((row = Auth.login(name, sha256))) { + if((row = Auth.login(name, pw))) { this.loggedIn = true; this.socket.emit("login", { success: true @@ -355,8 +355,8 @@ User.prototype.login = function(name, sha256) { } // Attempt to register a user account -User.prototype.register = function(name, sha256) { - if(sha256 == "") { +User.prototype.register = function(name, pw) { + if(pw == "") { // Sorry bud, password required this.socket.emit("register", { success: false, @@ -377,12 +377,12 @@ User.prototype.register = function(name, sha256) { error: "Invalid username. Usernames must be 1-20 characters long and consist only of alphanumeric characters and underscores" }); } - else if(Auth.register(name, sha256)) { + else if(Auth.register(name, pw)) { console.log(this.ip + " registered " + name); this.socket.emit("register", { success: true }); - this.login(name, sha256); + this.login(name, pw); } else { this.socket.emit("register", { diff --git a/www/assets/js/client.js b/www/assets/js/client.js index b9e80d7f..f7c425f7 100644 --- a/www/assets/js/client.js +++ b/www/assets/js/client.js @@ -98,7 +98,7 @@ firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); if(uname != null && pw != null && pw != "false") { socket.emit("login", { name: uname, - sha256: pw + pw: pw }); } @@ -147,23 +147,20 @@ $("#qlockbtn").click(function() { function loginClick() { uname = $("#username").val(); - if($("#password").val() == "") - pw = ""; - else - pw = SHA256($("#password").val()); + pw = $("#password").val(); socket.emit("login", { name: uname, - sha256: pw + pw: pw }); }; $("#login").click(loginClick); $("#username").keydown(function(ev) { - if(ev.key == 13) + if(ev.keyCode == 13) loginClick(); }); $("#password").keydown(function(ev) { - if(ev.key == 13) + if(ev.keyCode == 13) loginClick(); }); @@ -175,13 +172,10 @@ $("#logout").click(function() { $("#register").click(function() { uname = $("#username").val(); - if($("#password").val() == "") - pw = ""; - else - pw = SHA256($("#password").val()); + pw = $("#password").val(); socket.emit("register", { name: uname, - sha256: pw + pw: pw }); });