Server IP : 85.214.239.14 / Your IP : 3.145.16.251 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 : /srv/modoboa/env/lib64/python3.5/site-packages/passlib/handlers/ |
Upload File : |
"""passlib.handlers.sha1_crypt """ #============================================================================= # imports #============================================================================= # core import logging; log = logging.getLogger(__name__) # site # pkg from passlib.utils import safe_crypt, test_crypt from passlib.utils.binary import h64 from passlib.utils.compat import u, unicode, irange from passlib.crypto.digest import compile_hmac import passlib.utils.handlers as uh # local __all__ = [ ] #============================================================================= # sha1-crypt #============================================================================= _BNULL = b'\x00' class sha1_crypt(uh.HasManyBackends, uh.HasRounds, uh.HasSalt, uh.GenericHandler): """This class implements the SHA1-Crypt password hash, and follows the :ref:`password-hash-api`. It supports a variable-length salt, and a variable number of rounds. The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords: :type salt: str :param salt: Optional salt string. If not specified, an 8 character one will be autogenerated (this is recommended). If specified, it must be 0-64 characters, drawn from the regexp range ``[./0-9A-Za-z]``. :type salt_size: int :param salt_size: Optional number of bytes to use when autogenerating new salts. Defaults to 8 bytes, but can be any value between 0 and 64. :type rounds: int :param rounds: Optional number of rounds to use. Defaults to 480000, must be between 1 and 4294967295, inclusive. :type relaxed: bool :param relaxed: By default, providing an invalid value for one of the other keywords will result in a :exc:`ValueError`. If ``relaxed=True``, and the error can be corrected, a :exc:`~passlib.exc.PasslibHashWarning` will be issued instead. Correctable errors include ``rounds`` that are too small or too large, and ``salt`` strings that are too long. .. versionadded:: 1.6 """ #=================================================================== # class attrs #=================================================================== #--GenericHandler-- name = "sha1_crypt" setting_kwds = ("salt", "salt_size", "rounds") ident = u("$sha1$") checksum_size = 28 checksum_chars = uh.HASH64_CHARS #--HasSalt-- default_salt_size = 8 max_salt_size = 64 salt_chars = uh.HASH64_CHARS #--HasRounds-- default_rounds = 480000 # current passlib default min_rounds = 1 # really, this should be higher. max_rounds = 4294967295 # 32-bit integer limit rounds_cost = "linear" #=================================================================== # formatting #=================================================================== @classmethod def from_string(cls, hash): rounds, salt, chk = uh.parse_mc3(hash, cls.ident, handler=cls) return cls(rounds=rounds, salt=salt, checksum=chk) def to_string(self, config=False): chk = None if config else self.checksum return uh.render_mc3(self.ident, self.rounds, self.salt, chk) #=================================================================== # backend #=================================================================== backends = ("os_crypt", "builtin") #--------------------------------------------------------------- # os_crypt backend #--------------------------------------------------------------- @classmethod def _load_backend_os_crypt(cls): if test_crypt("test", '$sha1$1$Wq3GL2Vp$C8U25GvfHS8qGHim' 'ExLaiSFlGkAe'): cls._set_calc_checksum_backend(cls._calc_checksum_os_crypt) return True else: return False def _calc_checksum_os_crypt(self, secret): config = self.to_string(config=True) hash = safe_crypt(secret, config) if hash: assert hash.startswith(config) and len(hash) == len(config) + 29 return hash[-28:] else: # py3's crypt.crypt() can't handle non-utf8 bytes. # fallback to builtin alg, which is always available. return self._calc_checksum_builtin(secret) #--------------------------------------------------------------- # builtin backend #--------------------------------------------------------------- @classmethod def _load_backend_builtin(cls): cls._set_calc_checksum_backend(cls._calc_checksum_builtin) return True def _calc_checksum_builtin(self, secret): if isinstance(secret, unicode): secret = secret.encode("utf-8") if _BNULL in secret: raise uh.exc.NullPasswordError(self) rounds = self.rounds # NOTE: this seed value is NOT the same as the config string result = (u("%s$sha1$%s") % (self.salt, rounds)).encode("ascii") # NOTE: this algorithm is essentially PBKDF1, modified to use HMAC. keyed_hmac = compile_hmac("sha1", secret) for _ in irange(rounds): result = keyed_hmac(result) return h64.encode_transposed_bytes(result, self._chk_offsets).decode("ascii") _chk_offsets = [ 2,1,0, 5,4,3, 8,7,6, 11,10,9, 14,13,12, 17,16,15, 0,19,18, ] #=================================================================== # eoc #=================================================================== #============================================================================= # eof #=============================================================================