Server IP : 85.214.239.14 / Your IP : 18.118.255.238 Web Server : Apache/2.4.62 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Tue Jan 9 19:45:01 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 7.4.18 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare, MySQL : OFF | cURL : OFF | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /proc/2/root/proc/2/root/proc/2/cwd/srv/modoboa/env/lib64/python3.5/site-packages/modoboa/core/password_hashers/ |
Upload File : |
""" Base password hashers. Contains weak hashers (the original ones) available with Modoboa. """ import base64 import crypt import hashlib import string from random import Random from django.utils.crypto import constant_time_compare from django.utils.encoding import force_bytes, force_text class MetaHasher(type): """ PasswordHasher Metaclass Allow classmethod to be properties """ @property def name(cls): """Returns the name of the hasher""" return cls.__name__.rstrip('Hasher').lower() @property def label(cls): """Returns the label of the hasher""" return cls.name if not cls._weak else "{} (weak)".format(cls.name) class PasswordHasher(metaclass=MetaHasher): """ Base class of all hashers. """ _weak = False def __init__(self, target="local"): self._target = target def _encrypt(self, clearvalue, salt=None): raise NotImplementedError def _b64encode(self, pwhash): """Encode :keyword:`pwhash` using base64 if needed. :param str pwhash: password hash :return: base64 encoded hash or original hash """ if self._target == "ldap": return base64.b64encode(pwhash) return pwhash 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 """ pwhash = self._b64encode(self._encrypt(force_text(clearvalue))) return "%s%s" % (self.scheme, force_text(pwhash)) 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._b64encode(self._encrypt(clearvalue, hashed_value)), hashed_value ) def needs_rehash(self, hashed_value): """Check if the provided hash needs rehasing accoring to the current parameters :param str hashed_value: hased password :rtype bool :return: True if the password needs rehash, false otherwise """ return False @classmethod def get_password_hashers(cls): """Return all the PasswordHasher supported by Modoboa""" return cls.__subclasses__() class PLAINHasher(PasswordHasher): """ Plain (ie. clear) password hasher. """ _weak = True @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. """ _weak = True @property def scheme(self): return "{CRYPT}" def _encrypt(self, clearvalue, salt=None): if salt is None: salt = "".join( Random().sample( string.ascii_letters + string.digits, 2 ) ) return crypt.crypt(clearvalue, salt) class MD5Hasher(PasswordHasher): """ MD5 password hasher. Uses python `hashlib` standard module. """ _weak = True @property def scheme(self): return "{MD5}" def _encrypt(self, clearvalue, salt=None): obj = hashlib.md5(force_bytes(clearvalue)) return obj.hexdigest() class SHA256Hasher(PasswordHasher): """ SHA256 password hasher. Uses python `hashlib` and `base64` standard modules. """ _weak = True @property def scheme(self): return "{SHA256}" def _encrypt(self, clearvalue, salt=None): return hashlib.sha256(force_bytes(clearvalue)).digest() def _b64encode(self, pwhash): """Encode :keyword:`pwhash` using base64. :param str pwhash: password hash :return: base64 encoded hash """ return base64.b64encode(pwhash)