__  __    __   __  _____      _            _          _____ _          _ _ 
 |  \/  |   \ \ / / |  __ \    (_)          | |        / ____| |        | | |
 | \  / |_ __\ V /  | |__) | __ ___   ____ _| |_ ___  | (___ | |__   ___| | |
 | |\/| | '__|> <   |  ___/ '__| \ \ / / _` | __/ _ \  \___ \| '_ \ / _ \ | |
 | |  | | |_ / . \  | |   | |  | |\ V / (_| | ||  __/  ____) | | | |  __/ | |
 |_|  |_|_(_)_/ \_\ |_|   |_|  |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1
 if you need WebShell for Seo everyday contact me on Telegram
 Telegram Address : @jackleet
        
        
For_More_Tools: Telegram: @jackleet | Bulk Smtp support mail sender | Business Mail Collector | Mail Bouncer All Mail | Bulk Office Mail Validator | Html Letter private



Upload:

Command:

[email protected]: ~ $
"""passlib.handlers.md5_crypt - md5-crypt algorithm"""
#=============================================================================
# imports
#=============================================================================
# core
from hashlib import md5
import logging; log = logging.getLogger(__name__)
# site
# pkg
from passlib.utils import safe_crypt, test_crypt, repeat_string
from passlib.utils.binary import h64
from passlib.utils.compat import unicode, u
import passlib.utils.handlers as uh
# local
__all__ = [
    "md5_crypt",
    "apr_md5_crypt",
]

#=============================================================================
# pure-python backend
#=============================================================================
_BNULL = b"\x00"
_MD5_MAGIC = b"$1$"
_APR_MAGIC = b"$apr1$"

# pre-calculated offsets used to speed up C digest stage (see notes below).
# sequence generated using the following:
    ##perms_order = "p,pp,ps,psp,sp,spp".split(",")
    ##def offset(i):
    ##    key = (("p" if i % 2 else "") + ("s" if i % 3 else "") +
    ##        ("p" if i % 7 else "") + ("" if i % 2 else "p"))
    ##    return perms_order.index(key)
    ##_c_digest_offsets = [(offset(i), offset(i+1)) for i in range(0,42,2)]
_c_digest_offsets = (
    (0, 3), (5, 1), (5, 3), (1, 2), (5, 1), (5, 3), (1, 3),
    (4, 1), (5, 3), (1, 3), (5, 0), (5, 3), (1, 3), (5, 1),
    (4, 3), (1, 3), (5, 1), (5, 2), (1, 3), (5, 1), (5, 3),
    )

# map used to transpose bytes when encoding final digest
_transpose_map = (12, 6, 0, 13, 7, 1, 14, 8, 2, 15, 9, 3, 5, 10, 4, 11)

def _raw_md5_crypt(pwd, salt, use_apr=False):
    """perform raw md5-crypt calculation

    this function provides a pure-python implementation of the internals
    for the MD5-Crypt algorithms; it doesn't handle any of the
    parsing/validation of the hash strings themselves.

    :arg pwd: password chars/bytes to hash
    :arg salt: salt chars to use
    :arg use_apr: use apache variant

    :returns:
        encoded checksum chars
    """
    # NOTE: regarding 'apr' format:
    # really, apache? you had to invent a whole new "$apr1$" format,
    # when all you did was change the ident incorporated into the hash?
    # would love to find webpage explaining why just using a portable
    # implementation of $1$ wasn't sufficient. *nothing else* was changed.

    #===================================================================
    # init & validate inputs
    #===================================================================

    # validate secret
    # XXX: not sure what official unicode policy is, using this as default
    if isinstance(pwd, unicode):
        pwd = pwd.encode("utf-8")
    assert isinstance(pwd, bytes), "pwd not unicode or bytes"
    if _BNULL in pwd:
        raise uh.exc.NullPasswordError(md5_crypt)
    pwd_len = len(pwd)

    # validate salt - should have been taken care of by caller
    assert isinstance(salt, unicode), "salt not unicode"
    salt = salt.encode("ascii")
    assert len(salt) < 9, "salt too large"
        # NOTE: spec says salts larger than 8 bytes should be truncated,
        # instead of causing an error. this function assumes that's been
        # taken care of by the handler class.

    # load APR specific constants
    if use_apr:
        magic = _APR_MAGIC
    else:
        magic = _MD5_MAGIC

    #===================================================================
    # digest B - used as subinput to digest A
    #===================================================================
    db = md5(pwd + salt + pwd).digest()

    #===================================================================
    # digest A - used to initialize first round of digest C
    #===================================================================
    # start out with pwd + magic + salt
    a_ctx = md5(pwd + magic + salt)
    a_ctx_update = a_ctx.update

    # add pwd_len bytes of b, repeating b as many times as needed.
    a_ctx_update(repeat_string(db, pwd_len))

    # add null chars & first char of password
        # NOTE: this may have historically been a bug,
        # where they meant to use db[0] instead of B_NULL,
        # but the original code memclear'ed db,
        # and now all implementations have to use this.
    i = pwd_len
    evenchar = pwd[:1]
    while i:
        a_ctx_update(_BNULL if i & 1 else evenchar)
        i >>= 1

    # finish A
    da = a_ctx.digest()

    #===================================================================
    # digest C - for a 1000 rounds, combine A, S, and P
    #            digests in various ways; in order to burn CPU time.
    #===================================================================

    # NOTE: the original MD5-Crypt implementation performs the C digest
    # calculation using the following loop:
    #
    ##dc = da
    ##i = 0
    ##while i < rounds:
    ##    tmp_ctx = md5(pwd if i & 1 else dc)
    ##    if i % 3:
    ##        tmp_ctx.update(salt)
    ##    if i % 7:
    ##        tmp_ctx.update(pwd)
    ##    tmp_ctx.update(dc if i & 1 else pwd)
    ##    dc = tmp_ctx.digest()
    ##    i += 1
    #
    # The code Passlib uses (below) implements an equivalent algorithm,
    # it's just been heavily optimized to pre-calculate a large number
    # of things beforehand. It works off of a couple of observations
    # about the original algorithm:
    #
    # 1. each round is a combination of 'dc', 'salt', and 'pwd'; and the exact
    #    combination is determined by whether 'i' a multiple of 2,3, and/or 7.
    # 2. since lcm(2,3,7)==42, the series of combinations will repeat
    #    every 42 rounds.
    # 3. even rounds 0-40 consist of 'hash(dc + round-specific-constant)';
    #    while odd rounds 1-41 consist of hash(round-specific-constant + dc)
    #
    # Using these observations, the following code...
    # * calculates the round-specific combination of salt & pwd for each round 0-41
    # * runs through as many 42-round blocks as possible (23)
    # * runs through as many pairs of rounds as needed for remaining rounds (17)
    # * this results in the required 42*23+2*17=1000 rounds required by md5_crypt.
    #
    # this cuts out a lot of the control overhead incurred when running the
    # original loop 1000 times in python, resulting in ~20% increase in
    # speed under CPython (though still 2x slower than glibc crypt)

    # prepare the 6 combinations of pwd & salt which are needed
    # (order of 'perms' must match how _c_digest_offsets was generated)
    pwd_pwd = pwd+pwd
    pwd_salt = pwd+salt
    perms = [pwd, pwd_pwd, pwd_salt, pwd_salt+pwd, salt+pwd, salt+pwd_pwd]

    # build up list of even-round & odd-round constants,
    # and store in 21-element list as (even,odd) pairs.
    data = [ (perms[even], perms[odd]) for even, odd in _c_digest_offsets]

    # perform 23 blocks of 42 rounds each (for a total of 966 rounds)
    dc = da
    blocks = 23
    while blocks:
        for even, odd in data:
            dc = md5(odd + md5(dc + even).digest()).digest()
        blocks -= 1

    # perform 17 more pairs of rounds (34 more rounds, for a total of 1000)
    for even, odd in data[:17]:
        dc = md5(odd + md5(dc + even).digest()).digest()

    #===================================================================
    # encode digest using appropriate transpose map
    #===================================================================
    return h64.encode_transposed_bytes(dc, _transpose_map).decode("ascii")

#=============================================================================
# handler
#=============================================================================
class _MD5_Common(uh.HasSalt, uh.GenericHandler):
    """common code for md5_crypt and apr_md5_crypt"""
    #===================================================================
    # class attrs
    #===================================================================
    # name - set in subclass
    setting_kwds = ("salt", "salt_size")
    # ident - set in subclass
    checksum_size = 22
    checksum_chars = uh.HASH64_CHARS

    max_salt_size = 8
    salt_chars = uh.HASH64_CHARS

    #===================================================================
    # methods
    #===================================================================

    @classmethod
    def from_string(cls, hash):
        salt, chk = uh.parse_mc2(hash, cls.ident, handler=cls)
        return cls(salt=salt, checksum=chk)

    def to_string(self):
        return uh.render_mc2(self.ident, self.salt, self.checksum)

    # _calc_checksum() - provided by subclass

    #===================================================================
    # eoc
    #===================================================================

class md5_crypt(uh.HasManyBackends, _MD5_Common):
    """This class implements the MD5-Crypt password hash, and follows the :ref:`password-hash-api`.

    It supports a variable-length salt.

    The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords:

    :type salt: str
    :param salt:
        Optional salt string.
        If not specified, one will be autogenerated (this is recommended).
        If specified, it must be 0-8 characters, drawn from the regexp range ``[./0-9A-Za-z]``.

    :type salt_size: int
    :param salt_size:
        Optional number of characters to use when autogenerating new salts.
        Defaults to 8, but can be any value between 0 and 8.
        (This is mainly needed when generating Cisco-compatible hashes,
        which require ``salt_size=4``).

    :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
        ``salt`` strings that are too long.

        .. versionadded:: 1.6
    """
    #===================================================================
    # class attrs
    #===================================================================
    name = "md5_crypt"
    ident = u("$1$")

    #===================================================================
    # methods
    #===================================================================
    # FIXME: can't find definitive policy on how md5-crypt handles non-ascii.
    #        all backends currently coerce -> utf-8

    backends = ("os_crypt", "builtin")

    #---------------------------------------------------------------
    # os_crypt backend
    #---------------------------------------------------------------
    @classmethod
    def _load_backend_os_crypt(cls):
        if test_crypt("test", '$1$test$pi/xDtU5WFVRqYS6BMU8X/'):
            cls._set_calc_checksum_backend(cls._calc_checksum_os_crypt)
            return True
        else:
            return False

    def _calc_checksum_os_crypt(self, secret):
        config = self.ident + self.salt
        hash = safe_crypt(secret, config)
        if hash is None:
            # py3's crypt.crypt() can't handle non-utf8 bytes.
            # fallback to builtin alg, which is always available.
            return self._calc_checksum_builtin(secret)
        if not hash.startswith(config) or len(hash) != len(config) + 23:
            raise uh.exc.CryptBackendError(self, config, hash)
        return hash[-22:]

    #---------------------------------------------------------------
    # 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):
        return _raw_md5_crypt(secret, self.salt)

    #===================================================================
    # eoc
    #===================================================================

class apr_md5_crypt(_MD5_Common):
    """This class implements the Apr-MD5-Crypt password hash, and follows the :ref:`password-hash-api`.

    It supports a variable-length salt.

    The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords:

    :type salt: str
    :param salt:
        Optional salt string.
        If not specified, one will be autogenerated (this is recommended).
        If specified, it must be 0-8 characters, drawn from the regexp range ``[./0-9A-Za-z]``.

    :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
        ``salt`` strings that are too long.

        .. versionadded:: 1.6
    """
    #===================================================================
    # class attrs
    #===================================================================
    name = "apr_md5_crypt"
    ident = u("$apr1$")

    #===================================================================
    # methods
    #===================================================================
    def _calc_checksum(self, secret):
        return _raw_md5_crypt(secret, self.salt, use_apr=True)

    #===================================================================
    # eoc
    #===================================================================

#=============================================================================
# eof
#=============================================================================

Filemanager

Name Type Size Permission Actions
__pycache__ Folder 0755
__init__.py File 86 B 0644
argon2.py File 38.06 KB 0644
bcrypt.py File 52.35 KB 0644
cisco.py File 15.9 KB 0644
des_crypt.py File 21.84 KB 0644
digests.py File 6.18 KB 0644
django.py File 19.71 KB 0644
fshp.py File 7.62 KB 0644
ldap_digests.py File 12.74 KB 0644
md5_crypt.py File 13.42 KB 0644
misc.py File 9.87 KB 0644
mssql.py File 8.28 KB 0644
mysql.py File 4.68 KB 0644
oracle.py File 6.53 KB 0644
pbkdf2.py File 18.56 KB 0644
phpass.py File 4.67 KB 0644
postgres.py File 2.22 KB 0644
roundup.py File 1.15 KB 0644
scram.py File 22.01 KB 0644
scrypt.py File 13.81 KB 0644
sha1_crypt.py File 5.74 KB 0644
sha2_crypt.py File 21.29 KB 0644
sun_md5_crypt.py File 13.61 KB 0644
windows.py File 12.09 KB 0644
Filemanager