Switch to crypt from passlib
Next step in getting rid of `passlib` is sha512_crypt. This one is tricky since the `crypt` lib is deprecated in py311 and dropped in py313 with the only replacement by `passlib`. But since passlib itself is abandoned it literally means there is nothing we could use. On the other hand `sha512_crypt` was "deprecated" already in pike and it is not possible to enable it in Keystone while old passwords are still supported. In this unlucky situation still get rid of passlib and support for this algorightm is going to be completely dropped in next Keystone release. Change-Id: If791c953bc2953f2c78ff91e4fc4a342b89d6d1b
This commit is contained in:
parent
364e8bb712
commit
02583542c0
39
keystone/common/password_hashers/sha512_crypt.py
Normal file
39
keystone/common/password_hashers/sha512_crypt.py
Normal file
@ -0,0 +1,39 @@
|
||||
# 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 crypt
|
||||
|
||||
from keystone.common import password_hashers
|
||||
|
||||
|
||||
class Sha512_crypt(password_hashers.PasswordHasher):
|
||||
"""passlib transition class for sha512_crypt password hashing"""
|
||||
|
||||
name: str = "sha512_crypt"
|
||||
ident: str = "$6$"
|
||||
|
||||
@staticmethod
|
||||
def verify(password: bytes, hashed: str) -> bool:
|
||||
"""Verify hashing password would be equal to the `hashed` value
|
||||
|
||||
:param bytes password: Password to verify
|
||||
:param string hashed: Hashed password. Used to extract hashing
|
||||
parameters
|
||||
|
||||
:returns: boolean whether hashing password with the same parameters
|
||||
would match hashed value
|
||||
"""
|
||||
|
||||
return (
|
||||
crypt.crypt(password.decode("utf8"), hashed[0 : hashed.rfind("$")])
|
||||
== hashed
|
||||
)
|
@ -20,6 +20,7 @@ import passlib.hash
|
||||
|
||||
from keystone.common.password_hashers import bcrypt
|
||||
from keystone.common.password_hashers import scrypt
|
||||
from keystone.common.password_hashers import sha512_crypt
|
||||
import keystone.conf
|
||||
from keystone import exception
|
||||
from keystone.i18n import _
|
||||
@ -30,10 +31,10 @@ LOG = log.getLogger(__name__)
|
||||
SUPPORTED_HASHERS = frozenset(
|
||||
[
|
||||
passlib.hash.pbkdf2_sha512,
|
||||
passlib.hash.sha512_crypt,
|
||||
scrypt.Scrypt,
|
||||
bcrypt.Bcrypt,
|
||||
bcrypt.Bcrypt_sha256,
|
||||
sha512_crypt.Sha512_crypt,
|
||||
]
|
||||
)
|
||||
|
||||
|
@ -134,3 +134,23 @@ class TestPasswordHashing(unit.BaseTestCase):
|
||||
self.assertTrue(
|
||||
password_hashing.check_password(password, hashed_passlib)
|
||||
)
|
||||
|
||||
def test_sha512_crypt_passlib_compat(self):
|
||||
self.config_fixture.config(strict_password_check=True)
|
||||
# sha512_crypt is deprecated and is not supported to be set.
|
||||
# We want to ensure that user is still able to login, thus
|
||||
# set algo to whatever and go verify pwd
|
||||
self.config_fixture.config(
|
||||
group="identity", password_hash_algorithm="bcrypt"
|
||||
)
|
||||
self.config_fixture.config(group="identity", max_password_length="72")
|
||||
# few iterations to test multiple random values
|
||||
for _ in range(self.ITERATIONS):
|
||||
password: str = "".join( # type: ignore
|
||||
secrets.choice(string.printable)
|
||||
for i in range(random.randint(1, 72))
|
||||
)
|
||||
hashed_passlib = passlib.hash.sha512_crypt.hash(password)
|
||||
self.assertTrue(
|
||||
password_hashing.check_password(password, hashed_passlib)
|
||||
)
|
||||
|
@ -0,0 +1,7 @@
|
||||
---
|
||||
deprecations:
|
||||
- |
|
||||
This is the last release where passwords hashed using sha512_crypt
|
||||
algorithm are supported. Since even support of that is being dropped in
|
||||
python 3.13 it would be physically dropped from Keystone in the next
|
||||
release (`Epoxy`).
|
Loading…
Reference in New Issue
Block a user