Files
modoboa/modoboa/core/password_hashers/base.py
T

101 lines
2.3 KiB
Python

"""
Base password hashers.
Contains weak hashers (the original ones) available with Modoboa.
"""
import crypt
import hashlib
import base64
import string
from random import Random
from django.utils.crypto import constant_time_compare
class PasswordHasher(object):
"""
Base class of all hashers.
"""
def encrypt(self, clearvalue):
"""Encrypt a password.
The format used to store passwords is the same than dovecot's one::
{SCHEME}<hash>
<hash> may differ according to the used scheme.
:param str clearvalue: clear password
:rtype: str
:return: encrypted password
"""
return '%s%s' % (self.scheme, self._encrypt(clearvalue))
def verify(self, clearvalue, hashed_value):
"""Verify a password against a hashed value.
:param str clearvalue: clear password
:param str hashed_value: password previously hashed
:return: True if passwords match, False otherwise
"""
return constant_time_compare(
self._encrypt(clearvalue, hashed_value),
hashed_value
)
class PLAINHasher(PasswordHasher):
"""
Plain (ie. clear) password hasher.
"""
@property
def scheme(self):
return '{PLAIN}'
def _encrypt(self, clearvalue, salt=None):
return clearvalue
class CRYPTHasher(PasswordHasher):
"""
crypt password hasher.
Uses python `crypt` standard module.
"""
@property
def scheme(self):
return '{CRYPT}'
def _encrypt(self, clearvalue, salt=None):
if salt is None:
salt = "".join(Random().sample(string.letters + string.digits, 2))
return crypt.crypt(clearvalue, salt)
class MD5Hasher(PasswordHasher):
"""
MD5 password hasher.
Uses python `hashlib` standard module.
"""
@property
def scheme(self):
return '{MD5}'
def _encrypt(self, clearvalue, salt=None):
obj = hashlib.md5(clearvalue)
return obj.hexdigest()
class SHA256Hasher(PasswordHasher):
"""
SHA256 password hasher.
Uses python `hashlib` and `base64` standard modules.
"""
@property
def scheme(self):
return '{SHA256}'
def _encrypt(self, clearvalue, salt=None):
return base64.b64encode(hashlib.sha256(clearvalue).digest())