From e492bbc68ef41b276a0a18c6dbeda242d46b66f4 Mon Sep 17 00:00:00 2001 From: David Stanek Date: Wed, 19 Feb 2014 18:26:58 +0000 Subject: [PATCH] Always hash passwords on their way into the DB Way back in ed793ad5 a feature was added to detect if a password was already hashed. If it looked like it was already hashed the password was put into the database as is. It appears that this was added to support a migration that was using the identity API to store users instead of direct database inserts. Change-Id: I37b575e4db2fa7090c5171b8bc32cf2c57ad6e03 Fixes-bug: #1279849 --- keystone/common/utils.py | 7 ++-- keystone/tests/unit/__init__.py | 0 keystone/tests/unit/common/__init__.py | 0 keystone/tests/unit/common/test_utils.py | 44 ++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 5 deletions(-) create mode 100644 keystone/tests/unit/__init__.py create mode 100644 keystone/tests/unit/common/__init__.py create mode 100644 keystone/tests/unit/common/test_utils.py diff --git a/keystone/common/utils.py b/keystone/common/utils.py index a36e45303f..e03f68df0d 100644 --- a/keystone/common/utils.py +++ b/keystone/common/utils.py @@ -106,11 +106,8 @@ def hash_ldap_user_password(user): def hash_password(password): """Hash a password. Hard.""" password_utf8 = trunc_password(password).encode('utf-8') - if passlib.hash.sha512_crypt.identify(password_utf8): - return password_utf8 - h = passlib.hash.sha512_crypt.encrypt(password_utf8, - rounds=CONF.crypt_strength) - return h + return passlib.hash.sha512_crypt.encrypt( + password_utf8, rounds=CONF.crypt_strength) def ldap_hash_password(password): diff --git a/keystone/tests/unit/__init__.py b/keystone/tests/unit/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/keystone/tests/unit/common/__init__.py b/keystone/tests/unit/common/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/keystone/tests/unit/common/test_utils.py b/keystone/tests/unit/common/test_utils.py new file mode 100644 index 0000000000..0b7243e097 --- /dev/null +++ b/keystone/tests/unit/common/test_utils.py @@ -0,0 +1,44 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import uuid + +import testtools + +from keystone.common import utils + + +class TestPasswordHashing(testtools.TestCase): + + def setUp(self): + super(TestPasswordHashing, self).setUp() + self.password = uuid.uuid4().hex + self.hashed_password = utils.hash_password(self.password) + + def test_that_we_can_verify_a_password_against_a_hash(self): + self.assertTrue(utils.check_password(self.password, + self.hashed_password)) + + def test_that_an_incorrect_password_fails_to_validate(self): + bad_password = uuid.uuid4().hex + self.assertFalse(utils.check_password(bad_password, + self.hashed_password)) + + def test_that_a_hash_can_not_be_validated_against_a_hash(self): + # NOTE(dstanek): Bug 1279849 reported a problem where passwords + # were not being hashed if they already looked like a hash. This + # would allow someone to hash their password ahead of time + # (potentially getting around password requirements, like + # length) and then they could auth with their original password. + new_hashed_password = utils.hash_password(self.hashed_password) + self.assertFalse(utils.check_password(self.password, + new_hashed_password))