+
    ¢THiH  ã                   ó0  € R t ^ RIHt ^ RIHt ^ RIHtHtHt ^ RI	H
u Ht ^ RIHt ^ RIHt ^ RIHtHtHtHt ^ RIHtHtHt ^ R	IHt . R*OtRsR tRt ! R R]P@                  ]PB                  4      t" ! R R]PF                  ]"4      t$ ! R R
]"4      t% ! R R]"4      t&]PN                  ! R]RRRR7      t(R](n)        ](;PT                  R+,          un*         ! R R]4      t+ ! R  R]$4      t, ! R! R],4      t-]PN                  ! R]P\                  ! R"R#7      R$R%R&R'7      t/R$]/n)        ]/;PT                  R+,          un*         ! R( R]P`                  ]P@                  ]PB                  4      t1 ! R) R]Pd                  Pf                  ]Ph                  4      t5R# ),zDjango password hash support)Ú	b64encode)Úhexlify)Úmd5Úsha1Úsha256N)Úpbkdf2_hmac)Ú_wrapped_bcrypt)Úargon2ÚbcryptÚpbkdf2_sha1Úpbkdf2_sha256)Ú
getrandstrÚrngÚ
to_unicode)ÚBASE64_CHARSÚdjango_salted_sha1Údjango_salted_md5Údjango_bcryptÚdjango_pbkdf2_sha1Údjango_pbkdf2_sha256Údjango_argon2Údjango_des_cryptÚdjango_disabledc                  ó*   € \         f   ^ RIH s  \         # )N)Ú	des_crypt)r   Úpasslib.hash© ó    Ú9/usr/lib/python3/dist-packages/passlib/handlers/django.pyÚ_import_des_cryptr      s   € äÒÝ*ÜÐr   Ú>abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789c                   ón   a € ] tR t^(t o RtRt^tRt]t	]
P                  t]R 4       tR tV 3R ltRtV tR# )ÚDjangoSaltedHashz2base class providing common code for django hashesNc                ó\   € \         P                  ! WP                  V R 7      w  r#V ! W#R7      # )©Úhandler©ÚsaltÚchecksum)ÚuhÚ	parse_mc2Úident©ÚclsÚhashr'   Úchks   &&  r   Úfrom_stringÚDjangoSaltedHash.from_string9   s#   € ä—L’L §y¡y¸#Ô>‰	ˆÙ˜Ô+Ð+r   c                ón   € \         P                  ! V P                  V P                  V P                  4      # ©N)r)   Ú
render_mc2r+   r'   r(   ©Úselfs   &r   Ú	to_stringÚDjangoSaltedHash.to_string>   s!   € Ü�}Š}˜TŸZ™Z¨¯©°D·M±MÓBÐBr   c                ó:   <€ V ^8„  d   Qh/ S[ S[R3,          ;R&   # )é   .Úsetting_kwds)ÚtupleÚstr)ÚformatÚ__classdict__s   "€r   Ú__annotate__ÚDjangoSaltedHash.__annotate__(   s   ø‡ ‚ ñ
 ™˜S˜•/Ñ9ò r   r   )r'   Ú	salt_size)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r;   Údefault_salt_sizeÚmax_salt_sizeÚ
SALT_CHARSÚ
salt_charsr)   ÚLOWER_HEX_CHARSÚchecksum_charsÚclassmethodr0   r7   Ú__annotate_func__Ú__static_attributes__Ú__classdictcell__©r?   s   @r   r"   r"   (   sK   ø‡ € Ù<ð %:€Lð ÐØ€MØ€Jà×'Ñ'€Nàñ,ó ð,òC÷- ƒ r   r"   c                   ód   a € ] tR t^Ct o Rt]P                  R,           t^t]R 4       t	R t
RtV tR# )ÚDjangoVariableHashzEbase class providing common code for django hashes w/ variable roundsc                ó`   € \         P                  ! WP                  V R 7      w  r#pV ! W#VR7      # )r$   )Úroundsr'   r(   )r)   Ú	parse_mc3r+   )r-   r.   rV   r'   r/   s   &&   r   r0   ÚDjangoVariableHash.from_stringM   s(   € äŸLšL¨¯y©yÀ#ÔFÑˆ�cÙ˜&°cÔ:Ð:r   c                ó„   € \         P                  ! V P                  V P                  V P                  V P
                  4      # r3   )r)   Ú
render_mc3r+   rV   r'   r(   r5   s   &r   r7   ÚDjangoVariableHash.to_stringR   s'   € Ü�}Š}˜TŸZ™Z¨¯©°d·i±iÀÇÁÓOÐOr   r   N)rV   )rC   rD   rE   rF   rG   r"   r;   Ú
min_roundsrN   r0   r7   rP   rQ   rR   s   @r   rT   rT   C   s>   ø‡ € ñ Pà#×0Ñ0°;Õ>€Là€Jàñ;ó ð;÷Pð Pr   rT   c                   ó:   a € ] tR t^Vt o RtR tRtRt^(tR t	Rt
V tR# )r   a}  This 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.
r   zsha1$c                óÂ   € \        V\        4      '       d   VP                  R 4      p\        V P                  P                  R4      V,           4      P                  4       # ©úutf-8Úascii)Ú
isinstancer=   Úencoder   r'   Ú	hexdigest©r6   Úsecrets   &&r   Ú_calc_checksumÚ!django_salted_sha1._calc_checksumw   sE   € Ü�fœc×"Ò"Ø—]‘] 7Ó+ˆFÜ�D—I‘I×$Ñ$ WÓ-°Õ6Ó7×AÑAÓCÐCr   r   N©rC   rD   rE   rF   rG   ÚnameÚdjango_namer+   Úchecksum_sizerg   rP   rQ   rR   s   @r   r   r   V   s,   ø‡ € ñð6  €DØ€KØ€EØ€M÷Dð Dr   c                   ó:   a € ] tR t^}t o RtR tRtRt^ tR t	Rt
V tR# )r   a’  This 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.
r   zmd5$c                óÂ   € \        V\        4      '       d   VP                  R 4      p\        V P                  P                  R4      V,           4      P                  4       # r_   )rb   r=   rc   r   r'   rd   re   s   &&r   rg   Ú django_salted_md5._calc_checksumŸ   sE   € Ü�fœc×"Ò"Ø—]‘] 7Ó+ˆFÜ�4—9‘9×#Ñ# GÓ,¨vÕ5Ó6×@Ñ@ÓBÐBr   r   Nri   rR   s   @r   r   r   }   s,   ø‡ € ñð8 €DØ€KØ€EØ€M÷Cð Cr   zbcrypt$aÇ  This 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
   c                   óx   a a€ ] tR t^¾t oRtR tRt]tRt	]
R 4       t]
V 3R l4       tV 3R ltV 3R ltRtVtV ;t# )	Údjango_bcrypt_sha256a‚  This 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 </lib/passlib.hash.bcrypt>` for more details.

.. versionadded:: 1.6.2
Úbcrypt_sha256zbcrypt_sha256$c                óx   € \         P                  ! V4      pV'       g   R # VP                  V P                  4      # ©F)r)   Úto_unicode_for_identifyÚ
startswithÚdjango_prefix©r-   r.   s   &&r   ÚidentifyÚdjango_bcrypt_sha256.identifyÕ   s-   € ä×)Ò)¨$Ó/ˆßÙØ�‰˜s×0Ñ0Ó1Ð1r   c                óX  <€ \        VR R4      pVP                  V P                  4      '       g    \        P                  P                  V 4      hV\        V P                  4      R pVP                  R4      '       g    \        P                  P                  V 4      h\        SV `%  V4      # )ra   r.   Nz$2)
r   rx   ry   r)   ÚexcÚInvalidHashErrorÚlenÚMalformedHashErrorÚsuperr0   )r-   r.   ÚbhashÚ	__class__s   && €r   r0   Ú django_bcrypt_sha256.from_stringÜ   s‰   ø€ ä˜$ ¨Ó0ˆØ�‰˜s×0Ñ0×1Ò1Ü—&‘&×)Ñ)¨#Ó.Ð.Ø”S˜×*Ñ*Ó+Ð-Ð.ˆØ×Ñ ×%Ò%Ü—&‘&×+Ñ+¨CÓ0Ð0Ü‰wÑ" 5Ó)Ð)r   c                óF   <€ \         SV `  4       pV P                  V,           # r3   )r‚   r7   ry   )r6   rƒ   r„   s   & €r   r7   Údjango_bcrypt_sha256.to_stringæ   s!   ø€ Ü‘Ñ!Ó#ˆØ×!Ñ! EÕ)Ð)r   c                óÀ   <€ \        V\        4      '       d   VP                  R 4      p\        V P	                  V4      P                  4       4      p\        SV `  V4      # )r`   )rb   r=   rc   r   Ú_digestÚdigestr‚   rg   )r6   rf   r„   s   &&€r   rg   Ú#django_bcrypt_sha256._calc_checksumê   sJ   ø€ Ü�fœc×"Ò"Ø—]‘] 7Ó+ˆFÜ˜Ÿ™ fÓ-×4Ñ4Ó6Ó7ˆÜ‰wÑ% fÓ-Ð-r   r   )rC   rD   rE   rF   rG   rj   rk   r   r‰   ry   rN   r{   r0   r7   rg   rP   rQ   Ú__classcell__)r„   r?   s   @@r   rs   rs   ¾   sW   ù‡ € ñ	ð "€DØ!€KØ€Gð %€Màñ2ó ð2ð ô*ó ð*õ*÷.õ .r   rs   c                   óv   a € ] tR t^ñt o RtR tRtRt^tRt	]
P                  t^,t]P                  tRtR tRtV tR# )	r   a$  This 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   zpbkdf2_sha256$l   ÿÿ r   c                ó¨   € \        V P                  WP                  V P                  4      p\	        V4      P                  4       P                  R 4      # )ra   )r   r‰   r'   rV   r   ÚrstripÚdecode)r6   rf   r.   s   && r   rg   Ú#django_pbkdf2_sha256._calc_checksum   s:   € ä˜4Ÿ<™<¨·±¸D¿K¹KÓHˆÜ˜‹×%Ñ%Ó'×.Ñ.¨wÓ7Ð7r   r   N)rC   rD   rE   rF   rG   rj   rk   r+   Úmin_salt_sizeÚ
max_roundsr)   ÚPADDED_BASE64_CHARSrM   rl   r   Údefault_roundsr‰   rg   rP   rQ   rR   s   @r   r   r   ñ   sP   ø‡ € ñ"ðH "€DØ!€KØ€EØ€MØ€JØ×+Ñ+€NØ€MØ"×1Ñ1€NØ€G÷8ð 8r   c                   óF   € ] tR tRtRtR tRtRt^t]	P                  t
RtRtR# )r   i&  a'  This 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$r   r   N)rC   rD   rE   rF   rG   rj   rk   r+   rl   r   r•   r‰   rP   r   r   r   r   r   &  s.   † ñ"ðH  €DØ€KØ€EØ€MØ ×/Ñ/€NØ„Gr   ÚI)Útyper	   zargon2$argon2i$aÒ  This 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 </lib/passlib.hash.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
    )rj   Úwrappedrp   r+   rq   c                   ó€   a € ] tR tRt o RtR tRtRtRt]	P                  ;tt^t^;tt^tRt]R 4       tR tR tR	tV tR
# )r   io  a‹  This 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.
Úcryptzcrypt$Tc                ó  € \         P                  ! WP                  V R 7      w  r#V'       dQ   V'       g   VR,          pM5VR,          VR,          8w  d!   \         P                  P	                  V R4      hVR,          pV ! W#R7      # )r$   ºNr:   Nz0first two digits of salt and checksum must match:r:   NNr&   )r)   r*   r+   r~   r�   r,   s   &&  r   r0   Údjango_des_crypt.from_stringª  sn   € ä—L’L §y¡y¸#Ô>‰	ˆßçð ˜2•w‘Ø�b•˜S �WÔ$ô —f‘f×/Ñ/ØÐKóð ð �b•'ˆCÙ˜Ô+Ð+r   c                óø   € V P                   pVR ,          V P                  ,           pV P                  '       d"   \        P                  ! V P
                  W4      # \        P                  ! V P
                  RV4      # )r�   Ú )r'   r(   Úuse_duplicate_saltr)   r4   r+   )r6   r'   r/   s   &  r   r7   Údjango_des_crypt.to_string¾  sU   € Ø�y‰yˆØ�2�h˜Ÿ™Õ&ˆØ×"×"Ð"ä—=’= §¡¨TÓ7Ð7ä�}Š}˜TŸZ™Z¨¨SÓ1Ð1r   c                óÄ   € \         f   \        4        V P                  '       d   V P                  V4       \        V P                  R,          R7      P                  V4      # )Nr�   )r'   )r   r   Úuse_defaultsÚ_check_truncate_policyr'   rg   re   s   &&r   rg   Údjango_des_crypt._calc_checksumÇ  sH   € ô ÒÜÔà××ÐØ×'Ñ'¨Ô/Ü˜dŸi™i¨�mÔ,×;Ñ;¸FÓCÐCr   r   N)r'   rB   Útruncate_error)rC   rD   rE   rF   rG   rj   rk   r;   r+   r)   ÚHASH64_CHARSrM   rK   rl   r’   rH   Útruncate_sizer¡   rN   r0   r7   rg   rP   rQ   rR   s   @r   r   r   o  sn   ø‡ € ñ
ð< €DØ€KØ:€LØ€EØ"$§/¡/Ð1€N�ZØ€MØ()Ð)€MÐ%Ø€Mð Ðàñ,ó ð,ò&2÷	Dð 	Dr   c                   óV   a € ] tR tRt o RtR tRt^(t]R 4       t	R t
]R 4       tRtV tR# )	r   iÓ  a  This 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 `<https://code.djangoproject.com/ticket/20079>`_ for why
    Django appends an alphanumeric string.

.. versionchanged:: 1.6.2 added Django 1.6 support

.. versionchanged:: 1.7 started appending an alphanumeric string.
Ú!c                ód   € \         P                  ! V4      pVP                  V P                  4      # r3   )r)   rw   rx   Ú_hash_prefixrz   s   &&r   r{   Údjango_disabled.identifyð  s'   € ä×)Ò)¨$Ó/ˆØ�‰˜s×/Ñ/Ó0Ð0r   c                óF   € \        \        \        R R V P                  4      # )Néþÿÿÿ)r   r   r   Úsuffix_lengthre   s   &&r   rg   Údjango_disabled._calc_checksumõ  s   € äœ#œ|¨C¨RÐ0°$×2DÑ2DÓEÐEr   c                óž   € \         P                  ! V4       V P                  V4      '       g    \         P                  P	                  V 4      hR # rv   )r)   Úvalidate_secretr{   r~   r   )r-   rf   r.   s   &&&r   ÚverifyÚdjango_disabled.verifyù  s7   € ä
×Ò˜6Ô"Ø�|‰|˜D×!Ò!Ü—&‘&×)Ñ)¨#Ó.Ð.Ùr   r   N)rC   rD   rE   rF   rG   rj   r­   r±   rN   r{   rg   rµ   rP   rQ   rR   s   @r   r   r   Ó  sI   ø‡ € ñð. €DØ€LØ€Mð ñ1ó ð1òFð ñó ör   )r   r   r   r   r   r   r   r   )rk   )6rG   Úbase64r   Úbinasciir   Úhashlibr   r   r   Úpasslib.utils.handlersÚutilsÚhandlersr)   Úpasslib.crypto.digestr   Úpasslib.handlers.bcryptr   r   r	   r
   r   r   Úpasslib.utilsr   r   r   Úpasslib.utils.binaryr   Ú__all__r   r   rJ   ÚHasSaltÚGenericHandlerr"   Ú	HasRoundsrT   r   r   ÚPrefixWrapperr   rk   Ú_using_clone_attrsrs   r   r   Úusingr   ÚTruncateMixinr   ÚifcÚDisabledHashÚStaticHandlerr   r   r   r   Ú<module>rÌ      s�  ðÙ "å Ý ß %Ñ %ç #Ð #Ý -Ý 3ß CÓ Cß 5Ñ 5Ý -ò	€ð €	òð N€
ôC�r—z‘z 2×#4Ñ#4ô Cô6PØ‡L�LØôPô&$DÐ)ô $DôN%CÐ(ô %CðP × Ò ØØ
ØØ
ð	ô€ð* %€Ô Ø ×  Ò  Ð$4Õ 4Õ  ô0.˜?ô 0.ôf28Ð-ô 28ôj*Ð-ô *ð` × Ò Ø	Ø�LŠL˜cÔ"ØØ
ð	ô€ð* %€Ô Ø ×  Ò  Ð$4Õ 4Õ  ôaDØ×ÑØ‡J�JØ×ÑôaDôH+�b—f‘f×)Ñ)¨2×+;Ñ+;ö +r   