+
    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#    LLyy#>	++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!    }}TZZDMM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(    LLyy#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'    }}TZZdii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    fc""]]7+FDII$$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    fc""]]7+F499##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    fc""]]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<<DKK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1N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    LLyy#>	 2wbSW$ ff//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    yy2h&"""==T77}}TZZ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     ''/dii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"$//1NZ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    #|CR0$2D2D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rzz2#4#4 C6PLLP&$D) $DN%C( %CP   

	* %      $4 4  0.? 0.f28- 28j*- *`   	LLc"
	* %      $4 4  aDJJaDH+bff))2+;+; +r   