diff --git a/lib/hashes.js b/lib/hashes.js index 9780e098..21ea5993 100644 --- a/lib/hashes.js +++ b/lib/hashes.js @@ -29,22 +29,19 @@ module.exports.compare = async (password, hash) => { password = (password || '').toString(); hash = (hash || '').toString(); - let algo = [].concat(hash.match(/^\$([^$]+)\$/) || [])[1]; - algo = (algo || '').toString().toLowerCase(); + let algo = checkHashSupport(hash); + if (!algo.result) { + throw new Error('Invalid algo: ' + JSON.stringify(algo.algo)); + } - switch (algo) { - case 'pbkdf2-sha512': - case 'pbkdf2-sha256': - case 'pbkdf2-sha1': + switch (algo.algo) { + case 'pbkdf2': return await pbkdf2.verify(hash, password); - - case '2a': - case '2b': - case '2y': + case 'bcrypt': return await bcrypt.compare(password, hash); - case '6': + case 'unixcrypt': return await unixcryptCompareAsync(password, hash); - case '1': { + case 'md5': { let result; let salt = hash.split('$')[2] || ''; @@ -57,6 +54,33 @@ module.exports.compare = async (password, hash) => { } }; +function checkHashSupport(hash) { + hash = (hash || '').toString(); + + let algo = [].concat(hash.match(/^\$([^$]+)\$/) || [])[1]; + algo = (algo || '').toString().toLowerCase(); + + switch (algo) { + case 'pbkdf2-sha512': + case 'pbkdf2-sha256': + case 'pbkdf2-sha1': + return { result: true, algo: 'pbkdf2' }; + case '2a': + case '2b': + case '2y': + return { result: true, algo: 'bcrypt' }; + case '6': + return { result: true, algo: 'unixcrypt' }; + case '1': { + return { result: true, algo: 'md5' }; + } + default: + return { result: false, algo }; + } +}; + +module.exports.checkHashSupport = checkHashSupport; + module.exports.shouldRehash = hash => { hash = (hash || '').toString(); let algo = [].concat(hash.match(/^\$([^$]+)\$/) || [])[1]; diff --git a/lib/user-handler.js b/lib/user-handler.js index 398026dc..3aabe89d 100644 --- a/lib/user-handler.js +++ b/lib/user-handler.js @@ -1266,9 +1266,13 @@ class UserHandler { try { if (data.hashedPassword) { // try if the hashing library can handle it? - await hashes.compare('whatever', data.password); - // did not throw, so probably OK - hash = data.password; + let algo = hashes.checkHashSupport(data.password); + if (algo.result) { + hash = data.password; + } else { + throw new Error('Invalid algo: ' + JSON.stringify(algo.algo)); + } + } else { hash = await hashes.hash(data.password); }