diff --git a/node/db/Pad.js b/node/db/Pad.js index f18bc8914..42ae6bdaa 100644 --- a/node/db/Pad.js +++ b/node/db/Pad.js @@ -495,7 +495,7 @@ Class('Pad', { }, getPasswordSalt: function() { - return this.passwordHash.split("$")[1]; + return this.passwordHash == null? null:this.passwordHash.split("$")[1]; }, isCorrectPassword: function(password) { @@ -512,7 +512,7 @@ Class('Pad', { function hash(password, salt) { - var shasum = crypto.createHash('sha512'); + var shasum = crypto.createHash('sha256'); shasum.update(password + salt); return shasum.digest("hex") + "$" + salt; } @@ -524,7 +524,7 @@ function generateSalt() var randomstring = ''; for (var i = 0; i < len; i++) { - randomstring += chars[Math.floor(Math.random() * chars.length)]; + randomstring += charset[Math.floor(Math.random() * charset.length)]; } return randomstring; } diff --git a/node/db/SecurityManager.js b/node/db/SecurityManager.js index dbc6783c2..fa7780dc3 100644 --- a/node/db/SecurityManager.js +++ b/node/db/SecurityManager.js @@ -133,8 +133,8 @@ exports.checkAccess = function (padID, sessionID, token, password, callback) //is it password protected? isPasswordProtected = pad.isPasswordProtected(); - //get the password salt used by the hash function - pwsalt = pad.getPasswordSalt(); + //get the password salt used by the hash function + pwsalt = pad.getPasswordSalt(); //is password correct? if(isPasswordProtected && password && pad.isCorrectPassword(password)) @@ -205,18 +205,19 @@ exports.checkAccess = function (padID, sessionID, token, password, callback) else if(isPublic && isPasswordProtected && passwordStatus == "wrong") { //--> deny access, ask for new password and tell them that the password is wrong - statusObject = {accessStatus: "wrongPassword"}; + statusObject = {accessStatus: "wrongPassword", passwordSalt: pwsalt}; } //- its public and the pad is password protected but no password given else if(isPublic && isPasswordProtected && passwordStatus == "notGiven") { //--> ask for password - statusObject = {accessStatus: "needPassword"}; + statusObject = {accessStatus: "needPassword", passwordSalt: pwsalt}; } //- its not public else if(!isPublic) { //--> deny access + console.log("not public"); statusObject = {accessStatus: "deny"}; } else @@ -228,6 +229,7 @@ exports.checkAccess = function (padID, sessionID, token, password, callback) else { //--> deny access + console.log("imaginary pad"); statusObject = {accessStatus: "deny"}; } diff --git a/node/handler/PadMessageHandler.js b/node/handler/PadMessageHandler.js index 0fdece233..56e6de873 100644 --- a/node/handler/PadMessageHandler.js +++ b/node/handler/PadMessageHandler.js @@ -644,7 +644,7 @@ function handleClientReady(client, message) //no access, send the client a message that tell him why else { - client.json.send({accessStatus: statusObject.accessStatus}) + client.json.send({accessStatus: statusObject.accessStatus, passwordSalt: statusObject.passwordSalt}) } }); }, diff --git a/node/handler/SocketIORouter.js b/node/handler/SocketIORouter.js index 2d8f4f44d..d1e858cf1 100644 --- a/node/handler/SocketIORouter.js +++ b/node/handler/SocketIORouter.js @@ -92,7 +92,7 @@ exports.setSocketIO = function(_socket) { if(message.protocolVersion && message.protocolVersion != 2) { - messageLogger.warn("Protocolversion header is not correct:" + stringifyWithoutPassword(message)); + messageLogger.warn("Protocol version header is not correct:" + stringifyWithoutPassword(message)); return; } @@ -121,14 +121,14 @@ exports.setSocketIO = function(_socket) else { messageLogger.warn("Authentication try failed:" + stringifyWithoutPassword(message)); - client.json.send({accessStatus: statusObject.accessStatus}); + client.json.send({accessStatus: statusObject.accessStatus, passwordSalt: statusObject.passwordSalt}); } }); } //drop message else { - messageLogger.warn("Droped message cause of bad permissions:" + stringifyWithoutPassword(message)); + messageLogger.warn("Dropped message cause of insufficient permissions:" + stringifyWithoutPassword(message)); } } }); diff --git a/static/index.html b/static/index.html index a24a45e92..1c35e3852 100644 --- a/static/index.html +++ b/static/index.html @@ -119,7 +119,9 @@ } else { - window.location = "p/" + padname; + $.get("api/1/createPad", {apikey: "o8PJ496RtbcwoMQGgDyjoOmyq5wJ8dON", padID: padname}, function(data){ + window.location = "p/" + padname; + }); } } else diff --git a/static/js/jquery.sha256.js b/static/js/jquery.sha256.js new file mode 100644 index 000000000..385015801 --- /dev/null +++ b/static/js/jquery.sha256.js @@ -0,0 +1,159 @@ +/** + * SHA256 Hash Algorithm Plugin + * + * @version 1.0 (06/09/2009) + * @requires jQuery v1.2.6+ + * @author Alex Weber + * @copyright Copyright (c) 2008-2009, Alex Weber + * @see http://anmar.eu.org/projects/jssha2/ + * @see http://pajhome.org.uk/crypt/md5 + * + * Distributed under the terms of the new BSD License + * http://www.opensource.org/licenses/bsd-license.php + */ + +/** + * This plugin is based on the following work: + * + * A JavaScript implementation of the Secure Hash Algorithm, SHA-256, as defined + * in FIPS 180-2 + * Version 2.2-beta Copyright Angel Marin, Paul Johnston 2000 - 2009. + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * + */ + +(function($) { + var chrsz = 8; // bits per input character. 8 - ASCII; 16 - Unicode + + var safe_add = function(x, y) { + var lsw = (x & 0xFFFF) + (y & 0xFFFF); + var msw = (x >> 16) + (y >> 16) + (lsw >> 16); + return (msw << 16) | (lsw & 0xFFFF); + } + + var S = function(X, n) { + return ( X >>> n ) | (X << (32 - n)); + } + + var R = function(X, n) { + return ( X >>> n ); + } + + var Ch = function(x, y, z) { + return ((x & y) ^ ((~x) & z)); + } + + var Maj = function(x, y, z) { + return ((x & y) ^ (x & z) ^ (y & z)); + } + + var Sigma0256 = function(x) { + return (S(x, 2) ^ S(x, 13) ^ S(x, 22)); + } + + var Sigma1256 = function(x) { + return (S(x, 6) ^ S(x, 11) ^ S(x, 25)); + } + + var Gamma0256 = function(x) { + return (S(x, 7) ^ S(x, 18) ^ R(x, 3)); + } + + var Gamma1256 = function (x) { + return (S(x, 17) ^ S(x, 19) ^ R(x, 10)); + } + + + var core_sha256 = function(m, l) { + var K = new Array(0x428A2F98,0x71374491,0xB5C0FBCF,0xE9B5DBA5,0x3956C25B,0x59F111F1,0x923F82A4,0xAB1C5ED5,0xD807AA98,0x12835B01,0x243185BE,0x550C7DC3,0x72BE5D74,0x80DEB1FE,0x9BDC06A7,0xC19BF174,0xE49B69C1,0xEFBE4786,0xFC19DC6,0x240CA1CC,0x2DE92C6F,0x4A7484AA,0x5CB0A9DC,0x76F988DA,0x983E5152,0xA831C66D,0xB00327C8,0xBF597FC7,0xC6E00BF3,0xD5A79147,0x6CA6351,0x14292967,0x27B70A85,0x2E1B2138,0x4D2C6DFC,0x53380D13,0x650A7354,0x766A0ABB,0x81C2C92E,0x92722C85,0xA2BFE8A1,0xA81A664B,0xC24B8B70,0xC76C51A3,0xD192E819,0xD6990624,0xF40E3585,0x106AA070,0x19A4C116,0x1E376C08,0x2748774C,0x34B0BCB5,0x391C0CB3,0x4ED8AA4A,0x5B9CCA4F,0x682E6FF3,0x748F82EE,0x78A5636F,0x84C87814,0x8CC70208,0x90BEFFFA,0xA4506CEB,0xBEF9A3F7,0xC67178F2); + var HASH = new Array(0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19); + var W = new Array(64); + var a, b, c, d, e, f, g, h, i, j; + var T1, T2; + /* append padding */ + m[l >> 5] |= 0x80 << (24 - l % 32); + m[((l + 64 >> 9) << 4) + 15] = l; + for ( var i = 0; i>5] |= (str.charCodeAt(i / chrsz) & mask) << (24 - i%32); + } + return bin; + } + + var binb2hex = function(binarray) { + //var hexcase = 0; /* hex output format. 0 - lowercase; 1 - uppercase */ + //var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef"; + var hex_tab = "0123456789abcdef"; + var str = ""; + for (var i = 0; i < binarray.length * 4; i++) { + str += hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF) + hex_tab.charAt((binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF); + } + return str; + } + + var core_hmac_sha256 = function(key, data) { + var bkey = str2binb(key); + if(bkey.length > 16) { + bkey = core_sha1(bkey, key.length * chrsz); + } + var ipad = Array(16), opad = Array(16); + for(var i = 0; i < 16; i++) { + ipad[i] = bkey[i] ^ 0x36363636; + opad[i] = bkey[i] ^ 0x5C5C5C5C; + } + var hash = core_sha256(ipad.concat(str2binb(data)), 512 + data.length * chrsz); + return core_sha256(opad.concat(hash), 512 + 256); + } + + var prep = function(string){ + string = typeof string == 'object' ? $(string).val() : string.toString(); + return string; + } + + // standard sha256 implementation: var x = $.sha256(value); + // standard sha266hmac implementation: varx = $.sha256hmac(value1, value2); + $.extend({ + sha256 : function(string){ + string = prep(string); + return binb2hex(core_sha256(str2binb(string),string.length * chrsz)); + }, + sha256hmac : function(key, data){ + key = prep(key); + data = prep(data); + return binb2hex(core_hmac_sha256(key, data)); + }, + sha256config : function(bits){ + chrsz = parseInt(bits) || 8; + } + }); + // alternative sha256 implementation: var x = value.sha256(); + $.fn.sha256 = function (bits) { + // change bits + $.sha256config(bits); + var string = prep($(this).val()); + var val = $.sha256(string); + // reset bits, this was a one-time operation + $.sha256config(8); + return val; + }; +})(jQuery); diff --git a/static/js/pad2.js b/static/js/pad2.js index d21c43748..568b34568 100644 --- a/static/js/pad2.js +++ b/static/js/pad2.js @@ -71,8 +71,7 @@ function randomString() var randomstring = ''; for (var i = 0; i < string_length; i++) { - var rnum = Math.floor(Math.random() * chars.length); - randomstring += chars[rnum]; + randomstring += chars[Math.floor(Math.random() * chars.length)]; } return "t." + randomstring; } @@ -149,7 +148,7 @@ function getUrlVars() function hash(password, salt) { - return sha512(password + salt) + "$" + salt; + return $.sha256(password + salt) + "$" + salt; } /* Generate the "timed hash" used to get access. @@ -226,13 +225,15 @@ function handshake() { $("#editorloadingbox").html("You need a password to access this pad
" + ""+ - ""); + ""); + console.log("passwordSalt: "+obj.passwordSalt); } else if(obj.accessStatus == "wrongPassword") { $("#editorloadingbox").html("Your password was wrong
" + ""+ - ""); + ""); + console.log("passwordSalt: "+obj.passwordSalt); } } diff --git a/static/pad.html b/static/pad.html index 980905e99..86da0f8c8 100644 --- a/static/pad.html +++ b/static/pad.html @@ -15,6 +15,7 @@ +