a fWcN@sdZddlmZddlmZddlmZmZmZddl Z e e Z ddl mZddlmZmZmZmZddlmZmZmZdd lmZdd lmZmZmZmZdd lm Z ddl!m"m#Z$gd Z%da&d dZ'dZ(Gddde$j)e$j*Z+Gddde$j,e+Z-Gddde+Z.Gddde+Z/e$j0deededddZ1de1_2e1j3d7_3GdddeZ4Gd d!d!e-Z5Gd"d#d#e5Z6e$j0d$ej7d%d&ed'ed(d)d*Z8d'e8_2e8j3d7_3Gd+d,d,e$j9e$j)e$j*Z:Gd-d.d.e$j;jdS)/z5passlib.handlers.django- Django password hash support) b64encode)hexlify)md5sha1sha256N)_wrapped_bcrypt)argon2bcrypt pbkdf2_sha1 pbkdf2_sha256) to_unicoderng getrandstr) BASE64_CHARS) str_to_uascii uascii_to_strunicodeu) pbkdf2_hmac)django_salted_sha1django_salted_md5 django_bcryptdjango_pbkdf2_sha1django_pbkdf2_sha256 django_argon2django_des_cryptdjango_disabledcCstdurddlmatS)Nr) des_crypt)r passlib.hashrr;/usr/lib/python3.9/site-packages/passlib/handlers/django.py_import_des_crypt&s r!Z>abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789c@s:eZdZdZdZdZdZeZe j Z e ddZ ddZdS) DjangoSaltedHashz2base class providing common code for django hashes)salt salt_size NcCs"tj||j|d\}}|||dS)NZhandlerr#checksum)uh parse_mc2identclshashr#chkrrr from_stringBszDjangoSaltedHash.from_stringcCst|j|j|jSN)r) render_mc2r+r#r(selfrrr to_stringGszDjangoSaltedHash.to_string)__name__ __module__ __qualname____doc__ setting_kwdsdefault_salt_sizeZ max_salt_size SALT_CHARS salt_charsr)ZLOWER_HEX_CHARSchecksum_chars classmethodr0r5rrrr r"2s r"c@s2eZdZdZejdZdZeddZddZ dS) DjangoVariableHashzEbase class providing common code for django hashes w/ variable rounds)roundscCs&tj||j|d\}}}||||dS)Nr&)rAr#r()r)Z parse_mc3r+)r-r.rAr#r/rrr r0QszDjangoVariableHash.from_stringcCst|j|j|j|jSr1)r)Z render_mc3r+rAr#r(r3rrr r5VszDjangoVariableHash.to_stringN) r6r7r8r9r"r:Z min_roundsr?r0r5rrrr r@Ks   r@c@s,eZdZdZdZdZedZdZddZ dS)raThis class implements Django's Salted SHA1 hash, and follows the :ref:`password-hash-api`. It supports a variable-length salt, and uses a single round of SHA1. The :meth:`~passlib.ifc.PasswordHash.hash` and :meth:`~passlib.ifc.PasswordHash.genconfig` methods accept the following optional keywords: :type salt: str :param salt: Optional salt string. If not specified, a 12 character one will be autogenerated (this is recommended). If specified, may be any series of 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 12, but can be any positive value. This should be compatible with Django 1.4's :class:`!SHA1PasswordHasher` class. .. versionchanged: 1.6 This class now generates 12-character salts instead of 5, and generated salts uses the character range ``[0-9a-zA-Z]`` instead of the ``[0-9a-f]``. This is to be compatible with how Django >= 1.4 generates these hashes; but hashes generated in this manner will still be correctly interpreted by earlier versions of Django. rzsha1$(cCs0t|tr|d}tt|jd|SNutf-8ascii) isinstancerencoderrr# hexdigestr4secretrrr _calc_checksumys  z!django_salted_sha1._calc_checksumN r6r7r8r9name django_namerr+ checksum_sizerLrrrr rYs rc@s,eZdZdZdZdZedZdZddZ dS)raThis class implements Django's Salted MD5 hash, and follows the :ref:`password-hash-api`. It supports a variable-length salt, and uses a single round of MD5. The :meth:`~passlib.ifc.PasswordHash.hash` and :meth:`~passlib.ifc.PasswordHash.genconfig` methods accept the following optional keywords: :type salt: str :param salt: Optional salt string. If not specified, a 12 character one will be autogenerated (this is recommended). If specified, may be any series of 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 12, but can be any positive value. This should be compatible with the hashes generated by Django 1.4's :class:`!MD5PasswordHasher` class. .. versionchanged: 1.6 This class now generates 12-character salts instead of 5, and generated salts uses the character range ``[0-9a-zA-Z]`` instead of the ``[0-9a-f]``. This is to be compatible with how Django >= 1.4 generates these hashes; but hashes generated in this manner will still be correctly interpreted by earlier versions of Django. rzmd5$ cCs0t|tr|d}tt|jd|SrD)rGrrHrrr#rIrJrrr rLs  z django_salted_md5._calc_checksumNrMrrrr r~s rrzbcrypt$aThis class implements Django 1.4's BCrypt wrapper, and follows the :ref:`password-hash-api`. This is identical to :class:`!bcrypt` itself, but with the Django-specific prefix ``"bcrypt$"`` prepended. See :doc:`/lib/passlib.hash.bcrypt` for more details, the usage and behavior is identical. This should be compatible with the hashes generated by Django 1.4's :class:`!BCryptPasswordHasher` class. .. versionadded:: 1.6 )prefixr+docr )rOcs\eZdZdZdZdZeZedZ e ddZ e fddZ fdd Z fd d ZZS) django_bcrypt_sha256aThis class implements Django 1.6's Bcrypt+SHA256 hash, and follows the :ref:`password-hash-api`. It supports a variable-length salt, and a variable number of rounds. While the algorithm and format is somewhat different, the api and options for this hash are identical to :class:`!bcrypt` itself, see :doc:`bcrypt ` for more details. .. versionadded:: 1.6.2 Z bcrypt_sha256zbcrypt_sha256$cCst|}|sdS||jSNF)r)to_unicode_for_identify startswith django_prefixr-r.rrr identifys zdjango_bcrypt_sha256.identifycs\t|dd}||js$tj||t|jd}|dsLtj|tt | |S)NrFr.z$2) r rWrXr)excInvalidHashErrorlenMalformedHashErrorsuperrTr0)r-r.bhash __class__rr r0s     z django_bcrypt_sha256.from_stringcstt|}t|j|Sr1)r_rTr5rrX)r4r`rarr r5szdjango_bcrypt_sha256.to_stringcs6t|tr|d}t||}tt||S)NrE) rGrrHr_digestdigestr_rTrLrJrarr rLs  z#django_bcrypt_sha256._calc_checksum)r6r7r8r9rNrOrrcrrXr?rZr0r5rL __classcell__rrrar rTs   rTc@sDeZdZdZdZdZedZdZdZ e j Z dZ ejZdZdd Zd S) raThis class implements Django's PBKDF2-HMAC-SHA256 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, a 12 character one will be autogenerated (this is recommended). If specified, may be any series of 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 12, but can be any positive value. :type rounds: int :param rounds: Optional number of rounds to use. Defaults to 29000, but must be within ``range(1,1<<32)``. :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. This should be compatible with the hashes generated by Django 1.4's :class:`!PBKDF2PasswordHasher` class. .. versionadded:: 1.6 r zpbkdf2_sha256$rBl,rcCs&t|j||j|j}t|dS)NrF)rrcr#rArrstripdecode)r4rKr.rrr rL#sz#django_pbkdf2_sha256._calc_checksumN)r6r7r8r9rNrOrr+ min_salt_sizeZ max_roundsr)ZPADDED_BASE64_CHARSr>rPr default_roundsrcrLrrrr rs#rc@s.eZdZdZdZdZedZdZe j Z dZ dS)raThis class implements Django's PBKDF2-HMAC-SHA1 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, a 12 character one will be autogenerated (this is recommended). If specified, may be any series of 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 12, but can be any positive value. :type rounds: int :param rounds: Optional number of rounds to use. Defaults to 131000, but must be within ``range(1,1<<32)``. :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. This should be compatible with the hashes generated by Django 1.4's :class:`!PBKDF2SHA1PasswordHasher` class. .. versionadded:: 1.6 r z pbkdf2_sha1$rN) r6r7r8r9rNrOrr+rPr rjrcrrrr r(s#rrI)typerzargon2$argon2i$aThis class implements Django 1.10's Argon2 wrapper, and follows the :ref:`password-hash-api`. This is identical to :class:`!argon2` itself, but with the Django-specific prefix ``"argon2$"`` prepended. See :doc:`argon2 ` for more details, the usage and behavior is identical. This should be compatible with the hashes generated by Django 1.10's :class:`!Argon2PasswordHasher` class. .. versionadded:: 1.7 )rNwrappedrRr+rSc@s^eZdZdZdZdZdZedZe j Z Z dZ dZZdZdZed d Zd d Zd dZdS)raThis class implements Django's :class:`des_crypt` wrapper, and follows the :ref:`password-hash-api`. It supports a fixed-length salt. The :meth:`~passlib.ifc.PasswordHash.hash` and :meth:`~passlib.ifc.PasswordHash.genconfig` methods accept 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 2 characters, drawn from the regexp range ``[./0-9A-Za-z]``. :param bool truncate_error: By default, django_des_crypt will silently truncate passwords larger than 8 bytes. Setting ``truncate_error=True`` will cause :meth:`~passlib.ifc.PasswordHash.hash` to raise a :exc:`~passlib.exc.PasswordTruncateError` instead. .. versionadded:: 1.7 This should be compatible with the hashes generated by Django 1.4's :class:`!CryptPasswordHasher` class. Note that Django only supports this hash on Unix systems (though :class:`!django_des_crypt` is available cross-platform under Passlib). .. versionchanged:: 1.6 This class will now accept hashes with empty salt strings, since Django 1.4 generates them this way. Zcrypt)r#r$Ztruncate_errorzcrypt$ TcCsjtj||j|d\}}|r^|s,|dd}n&|dd|ddkrRtj|d|dd}|||dS)Nr&rpz0first two digits of salt and checksum must matchr')r)r*r+r[r^r,rrr r0s zdjango_des_crypt.from_stringcCsB|j}|dd|j}|jr.t|j||St|jd|SdS)Nrp)r#r(use_duplicate_saltr)r2r+)r4r#r/rrr r5s zdjango_des_crypt.to_stringcCs8tdurt|jr||t|jddd|S)Nrp)r#)rr!Z use_defaultsZ_check_truncate_policyr#rLrJrrr rLs  zdjango_des_crypt._calc_checksumN)r6r7r8r9rNrOr:rr+r)Z HASH64_CHARSr>r=rPrir;Z truncate_sizersr?r0r5rLrrrr rts   rc@s@eZdZdZdZedZdZeddZ ddZ edd Z d S) raFThis class provides disabled password behavior for Django, and follows the :ref:`password-hash-api`. This class does not implement a hash, but instead claims the special hash string ``"!"`` which Django uses to indicate an account's password has been disabled. * newly encrypted passwords will hash to ``"!"``. * it rejects all passwords. .. note:: Django 1.6 prepends a randomly generated 40-char alphanumeric string to each unusuable password. This class recognizes such strings, but for backwards compatibility, still returns ``"!"``. See ``_ for why Django appends an alphanumeric string. .. versionchanged:: 1.6.2 added Django 1.6 support .. versionchanged:: 1.7 started appending an alphanumeric string. !rCcCst|}||jSr1)r)rVrW _hash_prefixrYrrr rZs zdjango_disabled.identifycCstttdd|jS)N)rr r suffix_lengthrJrrr rLszdjango_disabled._calc_checksumcCs$t|||s tj|dSrU)r)Zvalidate_secretrZr[r\)r-rKr.rrr verifys   zdjango_disabled.verifyN) r6r7r8r9rNrrurwr?rZrLrxrrrr rs r)?r9base64rZbinasciirZhashlibrrrZloggingZ getLoggerr6logZpasslib.handlers.bcryptrrrr r r Z passlib.utilsr r rZpasslib.utils.binaryrZpasslib.utils.compatrrrrZpasslib.crypto.digestrZpasslib.utils.handlersZutilshandlersr)__all__rr!r<ZHasSaltZGenericHandlerr"Z HasRoundsr@rrZ PrefixWrapperrrOZ_using_clone_attrsrTrrZusingrZ TruncateMixinrZifcZ DisabledHashZ StaticHandlerrrrrr sN     %* 532 ^