Commit fbb2c597 authored by Charlie Jacomme's avatar Charlie Jacomme

Support old hashes, md5/crypt

parent cf3edcef
......@@ -33,8 +33,10 @@ import binascii
import os
from base64 import encodestring
from base64 import decodestring
from base64 import b64encode
from base64 import b64decode
from collections import OrderedDict
import crypt
from django.contrib.auth import hashers
......@@ -72,6 +74,117 @@ def checkPassword(challenge_password, password):
return valid_password
def hash_password_salt(hashed_password):
""" Extract the salt from a given hashed password """
if hashed_password.upper().startswith('{CRYPT}'):
hashed_password = hashed_password[7:]
if hashed_password.startswith('$'):
return '$'.join(hashed_password.split('$')[:-1])
else:
return hashed_password[:2]
elif hashed_password.upper().startswith('{SSHA}'):
try:
digest = b64decode(hashed_password[6:])
except TypeError as error:
raise ValueError("b64 error for `hashed_password` : %s" % error)
if len(digest) < 20:
raise ValueError("`hashed_password` too short")
return digest[20:]
elif hashed_password.upper().startswith('{SMD5}'):
try:
digest = b64decode(hashed_password[7:])
except TypeError as error:
raise ValueError("b64 error for `hashed_password` : %s" % error)
if len(digest) < 16:
raise ValueError("`hashed_password` too short")
return digest[16:]
else:
raise ValueError("`hashed_password` should start with '{SSHA}' or '{CRYPT}' or '{SMD5}'")
class CryptPasswordHasher(hashers.BasePasswordHasher):
"""
Crypt password hashing to allow for LDAP auth compatibility
We do not encode, this should bot be used !
"""
algorithm = "{crypt}"
def encode(self, password, salt):
pass
def verify(self, password, encoded):
"""
Check password against encoded using SSHA algorithm
"""
assert encoded.startswith(self.algorithm)
salt = hash_password_salt(challenge_password)
return crypt.crypt(password.encode(), salt) == challenge.encode()
def safe_summary(self, encoded):
"""
Provides a safe summary of the password
"""
assert encoded.startswith(self.algorithm)
hash_str = encoded[7:]
hash_str = binascii.hexlify(decodestring(hash_str.encode())).decode()
return OrderedDict([
('algorithm', self.algorithm),
('iterations', 0),
('salt', hashers.mask_hash(hash_str[2*DIGEST_LEN:], show=2)),
('hash', hashers.mask_hash(hash_str[:2*DIGEST_LEN])),
])
def harden_runtime(self, password, encoded):
"""
Method implemented to shut up BasePasswordHasher warning
As we are not using multiple iterations the method is pretty useless
"""
pass
class MD5PasswordHasher(hashers.BasePasswordHasher):
"""
MD5 password hashing to allow for LDAP auth compatibility
We do not encode, this should bot be used !
"""
algorithm = "{SMD5}"
def encode(self, password, salt):
pass
def verify(self, password, encoded):
"""
Check password against encoded using SSHA algorithm
"""
assert encoded.startswith(self.algorithm)
salt = hash_password_salt(encoded)
return b64encode(hashlib.md5(password.encode() + salt).digest() + salt) == encoded.encode()
def safe_summary(self, encoded):
"""
Provides a safe summary of the password
"""
assert encoded.startswith(self.algorithm)
hash_str = encoded[7:]
hash_str = binascii.hexlify(decodestring(hash_str.encode())).decode()
return OrderedDict([
('algorithm', self.algorithm),
('iterations', 0),
('salt', hashers.mask_hash(hash_str[2*DIGEST_LEN:], show=2)),
('hash', hashers.mask_hash(hash_str[:2*DIGEST_LEN])),
])
def harden_runtime(self, password, encoded):
"""
Method implemented to shut up BasePasswordHasher warning
As we are not using multiple iterations the method is pretty useless
"""
pass
class SSHAPasswordHasher(hashers.BasePasswordHasher):
"""
SSHA password hashing to allow for LDAP auth compatibility
......
......@@ -46,6 +46,8 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Auth definition
PASSWORD_HASHERS = (
're2o.login.SSHAPasswordHasher',
're2o.login.MD5PasswordHasher',
're2o.login.CryptPasswordHasher',
'django.contrib.auth.hashers.PBKDF2PasswordHasher',
)
AUTH_USER_MODEL = 'users.User' # The class to use for authentication
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment