+
    THi|@                        R t ^ RIt^ RIHt ^ RIHu Ht ^ RIH	t	 ^ RI
Ht ^ RIHtHt . ROtR
tR tR tR tR t ! R R]P*                  ]P,                  ]P.                  ]P0                  4      t ! R R]P,                  ]P4                  ]P.                  ]P0                  4      t ! R R]P.                  ]P0                  4      t ! R R	]P*                  ]P.                  ]P0                  4      tR# )z)traditional unix (DES) crypt and variantsN)warn)des_encrypt_int_block
to_unicode)h64h64big	des_crypt
bsdi_cryptbigcryptcrypt16    c                F    \        R \        V R,          4       4       4      # )zconvert secret to 64-bit DES key.

this only uses the first 8 bytes of the secret,
and discards the high 8th bit of each byte at that.
a null parity bit is inserted after every 7th bit of the output.
c              3   b   "   T F%  w  rV^,          ^9V^,          ,
          ,          x  K'  	  R# 5i)   N ).0ics   &  </usr/lib/python3/dist-packages/passlib/handlers/des_crypt.py	<genexpr>'_crypt_secret_to_key.<locals>.<genexpr>!   s(     L6KdaDb1q5j))6Ks   -/:N   N)sum	enumerate)secrets   &r   _crypt_secret_to_keyr      s     Lir
6KLLL    c                   \        V4      ^8X  g   Q h\        P                  ! V4      p\        V \        4      '       d   V P                  R4      p \        V \        4      '       g   Q h\        V 9   d$   \        P                  P                  \        4      h\        V 4      p\        V^ V^4      p\        P                  ! V4      # )z pure-python backed for des_cryptutf-8)lenr   decode_int12
isinstancestrencodebytes_BNULLuhexcNullPasswordErrorr   r   r   r   encode_int64)r   salt
salt_value	key_valueresults   &&   r   _raw_des_cryptr.   $   s    t9>> !!$'J &#w'fe$$$$ ff&&y11 %V,I #9aR@F v&&r   c                    \        V 4      p^p\        V 4      pW#8  d-   V^,           p\        WV 4      p\        W4      V,          pTpK2  V# )z,convert secret to DES key used by bsdi_crypt)r   r   r   )r   r,   idxendnext	tmp_values   &     r   _bsdi_secret_to_keyr4   C   sQ    $V,I
C
f+C
)Qw(D)9:	))?)K	r   c                d   \         P                  ! V4      p\        V \        4      '       d   V P	                  R4      p \        V \
        4      '       g   Q h\        V 9   d$   \        P                  P                  \        4      h\        V 4      p\        V^ W14      p\        P                  ! V4      # )z"pure-python backend for bsdi_cryptr   )r   decode_int24r!   r"   r#   r$   r%   r&   r'   r(   r	   r4   r   r   r)   )r   roundsr*   r+   r,   r-   s   &&&   r   _raw_bsdi_cryptr8   P   s     !!$'J &#w'fe$$$$ ff&&z22 $F+I #9aDF v&&r   c                      a  ] tR t^it o RtR tR
t]P                  t	^t
^;tt]P                  t^t]P                   ! R]P"                  ]P$                  ,          4      t]R 4       tR tR tRt]R 4       tR tRtV tR	# )r   aG  This class implements the des-crypt password hash, and follows the :ref:`password-hash-api`.

It supports a fixed-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 2 characters, drawn from the regexp range ``[./0-9A-Za-z]``.

:param bool truncate_error:
    By default, 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

: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
zU
        ^
        (?P<salt>[./a-z0-9]{2})
        (?P<chk>[./a-z0-9]{11})?
        $c                d    \        VR R4      pVR,          VR,          r2T ! Y#;'       g    RR7      # )asciihash:N   N:r=   NNNr*   checksumr   )clsr<   r*   chks   &&  r   from_stringdes_crypt.from_string   s0    $0Hd2hc{{d33r   c                6    V P                    V P                   2# Nr>   selfs   &r   	to_stringdes_crypt.to_string       ))T]]O,,r   c                j    V P                   '       d   V P                  V4       V P                  V4      # rE   )use_defaults_check_truncate_policy_calc_checksum_backendrG   r   s   &&r   _calc_checksumdes_crypt._calc_checksum   s-    ''/**622r   c                <    V P                  V P                  4       R # T_set_calc_checksum_backend_calc_checksum_builtinr@   s   &r   _load_backend_builtindes_crypt._load_backend_builtin       &&s'A'ABr   c                h    \        WP                  P                  R 4      4      P                  R 4      # r;   )r.   r*   r#   decoderO   s   &&r   rV    des_crypt._calc_checksum_builtin   s'    fii&6&6w&?@GGPPr   r   Nr*   truncate_errorbuiltin)__name__
__module____qualname____firstlineno____doc__namesetting_kwdsr&   HASH64_CHARSchecksum_charschecksum_sizemin_salt_sizemax_salt_size
salt_charstruncate_sizerecompileVERBOSE
IGNORECASE_hash_regexclassmethodrB   rH   rP   backendsrX   rV   __static_attributes____classdictcell____classdict__s   @r   r   r   i   s     B D-L
 __NM
 %&%MMJ
 M **	
 	

R]]"K 4 4
-3 H
  Q Qr   c                   F  a a ] tR t^t oRtR tRt^t]P                  t
^;tt]P                  tRt^tRtRt]P&                  ! R]P(                  ]P*                  ,          4      t]R 4       tR tRt]V 3R	 l4       t]V 3R
 l4       tV 3R ltRt]R 4       tR t Rt!Vt"V ;t## )r	   a  This class implements the BSDi-Crypt password hash, and follows the :ref:`password-hash-api`.

It supports a fixed-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, one will be autogenerated (this is recommended).
    If specified, it must be 4 characters, drawn from the regexp range ``[./0-9A-Za-z]``.

:type rounds: int
:param rounds:
    Optional number of rounds to use.
    Defaults to 5001, must be between 1 and 16777215, 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

.. versionchanged:: 1.6
    :meth:`hash` will now issue a warning if an even number of rounds is used
    (see :ref:`bsdi-crypt-security-issues` regarding weak DES keys).
i  i linearz
        ^
        _
        (?P<rounds>[./a-z0-9]{4})
        (?P<salt>[./a-z0-9]{4})
        (?P<chk>[./a-z0-9]{11})?
        $c                (   \        VR R4      pV P                  P                  V4      pV'       g    \        P                  P                  V 4      hVP                  RRR4      w  r4pV ! \        P                  ! VP                  R 4      4      VVR7      # )r;   r<   r7   r*   rA   )r7   r*   r?   )
r   ru   matchr&   r'   InvalidHashErrorgroupr   r6   r#   )r@   r<   mr7   r*   rA   s   &&    r   rB   bsdi_crypt.from_string  s}    $0OO!!$'&&))#..GGHfe<c##FMM'$:;
 	
r   c                    R P                  \        P                  ! V P                  4      P	                  R4      V P
                  V P                  4      # )z_{}{}{}r;   )formatr   encode_int24r7   r]   r*   r?   rF   s   &r   rH   bsdi_crypt.to_string  s@    T[[)009IIMM
 	
r   Tc                   < \         SV `  ! R/ VB pVP                  ^,          '       g%   \        R\        P
                  P                  4       V# )   zHbsdi_crypt rounds should be odd, as even rounds may reveal weak DES keysr   )superusingdefault_roundsr   r&   r'   PasslibSecurityWarning)r@   kwdssubcls	__class__s   &, r   r   bsdi_crypt.using  sD    &&$$q((Z-- r   c                2   < \         SV `  4       pV^,          # )r   )r   _generate_rounds)r@   r7   r   s   & r   r   bsdi_crypt._generate_rounds(  s    )+ zr   c                Z   < V P                   ^,          '       g   R# \        SV `  ! R/ VB # )r   Tr   )r7   r   _calc_needs_update)rG   r   r   s   &,r   r   bsdi_crypt._calc_needs_update2  s&    {{Qw)1D11r   c                <    V P                  V P                  4       R # rS   rT   rW   s   &r   rX    bsdi_crypt._load_backend_builtin>  rZ   r   c                ~    \        WP                  V P                  P                  R 4      4      P	                  R 4      # r\   )r8   r7   r*   r#   r]   rO   s   &&r   rV   !bsdi_crypt._calc_checksum_builtinC  s2    v{{DII4D4DW4MNUU
 	
r   r   )r*   r7   ra   )$rc   rd   re   rf   rg   rh   ri   rl   r&   rj   rk   rm   rn   ro   r   
min_rounds
max_roundsrounds_costrq   rr   rs   rt   ru   rv   rB   rH   _avoid_even_roundsr   r   r   rw   rX   rV   rx   ry   __classcell__r   r{   s   @@r   r	   r	      s     B D%LM__N %&%MMJ NJJK **	 	

R]]"	K 

 


    2 H
  
 
r   c                      a a ] tR tRt oRtR tR	t]P                  t	^;t
t]P                  t]P                  ! R]P                  ]P                   ,          4      t]R 4       tR tR
V 3R lltR tRtVtV ;t# )r
   iI  a'  This class implements the BigCrypt password hash, and follows the :ref:`password-hash-api`.

It supports a fixed-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 22 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
zX
        ^
        (?P<salt>[./a-z0-9]{2})
        (?P<chk>([./a-z0-9]{11})+)?
        $c                    \        VR R4      pV P                  P                  V4      pV'       g    \        P                  P                  V 4      hVP                  RR4      w  r4V ! W4R7      # r;   r<   r*   rA   r>   r   ru   r   r&   r'   r   r   r@   r<   r   r*   rA   s   &&   r   rB   bigcrypt.from_strings  Y    $0OO!!$'&&))#..GGFE*	++r   c                6    V P                    V P                   2# rE   r>   rF   s   &r   rH   bigcrypt.to_string|  rJ   r   c                   < \         SV `  WR 7      p\        V4      ^,          '       d    \        P                  P                  V 4      hV# ))relaxed)r   _norm_checksumr   r&   r'   r   )rG   r?   r   r   s   &&&r   r   bigcrypt._norm_checksum  s>    7)()Dx=2&&))$//r   c                *   \        V\        4      '       d   VP                  R 4      p\        WP                  P                  R4      4      p^p\        V4      pW48  d&   V^,           pV\        WV VRR 4      ,          pTpK+  VP                  R4      # )r   r;   ii)r!   r"   r#   r.   r*   r   r]   )rG   r   rA   r0   r1   r2   s   &&    r   rP   bigcrypt._calc_checksum  s    fc""]]7+FVYY%5%5g%>?&ki7D>&T"2CBK@@CCzz'""r   r   )r*   )F)rc   rd   re   rf   rg   rh   ri   r&   rj   rk   rm   rn   ro   rq   rr   rs   rt   ru   rv   rB   rH   r   rP   rx   ry   r   r   s   @@r   r
   r
   I  s     0 DL__N %&%MMJ**	
 	

R]]"K , ,-
# 
#r   c                      a  ] tR tRt o RtR tR	t^t]P                  t
^;tt]P                  t^t]P                   ! R]P"                  ]P$                  ,          4      t]R 4       tR tR tRtV tR# )
r   i  aD  This class implements the crypt16 password hash, and follows the :ref:`password-hash-api`.

It supports a fixed-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 2 characters, drawn from the regexp range ``[./0-9A-Za-z]``.

:param bool truncate_error:
    By default, crypt16 will silently truncate passwords larger than 16 bytes.
    Setting ``truncate_error=True`` will cause :meth:`~passlib.ifc.PasswordHash.hash`
    to raise a :exc:`~passlib.exc.PasswordTruncateError` instead.

    .. versionadded:: 1.7

: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
zU
        ^
        (?P<salt>[./a-z0-9]{2})
        (?P<chk>[./a-z0-9]{22})?
        $c                    \        VR R4      pV P                  P                  V4      pV'       g    \        P                  P                  V 4      hVP                  RR4      w  r4V ! W4R7      # r   r   r   s   &&   r   rB   crypt16.from_string  r   r   c                6    V P                    V P                   2# rE   r>   rF   s   &r   rH   crypt16.to_string  rJ   r   c                "   \        V\        4      '       d   VP                  R 4      pV P                  '       d   V P	                  V4        \
        P                  ! V P                  P                  R4      4      p\        T4      p\        T^ T^4      p\        TR,          4      p\        T^ T^4      p\        P                  ! T4      \        P                  ! T4      ,           pTP                  R4      #   \         d    \        R4      Rhi ; i)r   r;   zinvalid chars in saltN:r      N)r!   r"   r#   rL   rM   r   r    r*   
ValueErrorr   r   r   r)   r]   )rG   r   r+   key1result1key2result2rA   s   &&      r   rP   crypt16._calc_checksum  s    fc""]]7+F ''/	@))$))*:*:7*CDJ
 $F+ (aR@ $F4L1 (aQ? !!'*V-@-@-IIzz'""#  	@454?	@s   /C6 6Dr   Nr_   )rc   rd   re   rf   rg   rh   ri   rl   r&   rj   rk   rm   rn   ro   rp   rq   rr   rs   rt   ru   rv   rB   rH   rP   rx   ry   rz   s   @r   r   r     s     B D-L
 M__N
 %&%MMJ
 M**	
 	

R]]"K , ,-# #r   )r   r	   r
   r   )rg   rq   warningsr   passlib.utils.handlersutilshandlersr&   passlib.crypto.desr   passlib.utilsr   passlib.utils.binaryr   r   __all__r%   r   r.   r4   r8   TruncateMixinHasManyBackendsHasSaltGenericHandlerr   	HasRoundsr	   r
   r   r   r   r   <module>r      s    / 	  # # 4 $ , 
M'>
'2[Q  ""4"4bjj"BSBS [Q|
##R\\2::r?P?P 
DF#rzz2,, F#Rf#b

B,=,= f#r   