
    XR__W                        d Z ddlZddlZ ej        e          ZddlmZ ddlm	Z	m
Z
mZ ddlmZmZ ddlmZmZmZmZmZ ddlmZ ddlmc mZ g dZd	Zd
 Zd Zd Zd Z  G d dej!        ej"        ej#        ej$                  Z% G d dej"        ej&        ej#        ej$                  Z' G d dej#        ej$                  Z( G d dej!        ej#        ej$                  Z)dS )zFpasslib.handlers.des_crypt - traditional unix (DES) crypt and variants    N)warn)
safe_crypt
test_crypt
to_unicode)h64h64big)byte_elem_valueuuascii_to_strunicodesuppress_cause)des_encrypt_int_block)	des_crypt
bsdi_cryptbigcryptcrypt16    c                 ^    t          d t          | dd                   D                       S )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   R   K   | ]"\  }}t          |          d z  d|dz  z
  z  V  #dS )   9      N)r	   ).0ics      </usr/lib/python3/dist-packages/passlib/handlers/des_crypt.py	<genexpr>z'_crypt_secret_to_key.<locals>.<genexpr>(   sT       2 21a  ""T)r!A#v6 2 2 2 2 2 2    Nr   )sum	enumerate)secrets    r   _crypt_secret_to_keyr"      sB      2 2$VBQBZ002 2 2 2 2 2r   c                    t          |          dk    sJ t          j        |          }t          | t                    r|                     d          } t          | t                    sJ t          | v r$t          j	        
                    t                    t          |           }t          |d|d          }t          j        |          S )z pure-python backed for des_crypt   utf-8r      )lenr   decode_int12
isinstancer   encodebytes_BNULLuhexcNullPasswordErrorr   r"   r   r   encode_int64)r!   salt
salt_value	key_valueresults        r   _raw_des_cryptr5   +   s    t99>>>> !$''J &'"" (w''fe$$$$$ f&&y111 %V,,I #9aR@@F v&&&r   c                     t          |           }d}t          |           }||k     r7|dz   }t          | ||                   }t          ||          |z  }|}||k     7|S )z,convert secret to DES key used by bsdi_cryptr   )r"   r'   r   )r!   r3   idxendnext	tmp_values         r   _bsdi_secret_to_keyr;   I   ss    $V,,I
C
f++C
))Qw(D)9::	))Y??)K		 ))
 r   c                 p   t          j        |          }t          | t                    r|                     d          } t          | t
                    sJ t          | v r$t          j        	                    t                    t          |           }t          |d||          }t          j        |          S )z"pure-python backend for bsdi_cryptr%   r   )r   decode_int24r)   r   r*   r+   r,   r-   r.   r/   r   r;   r   r   r0   )r!   roundsr1   r2   r3   r4   s         r   _raw_bsdi_cryptr?   U   s     !$''J &'"" (w''fe$$$$$ f&&z222 $F++I #9aVDDF v&&&r   c                       e Zd ZdZd ZdZej        ZdZ	dxZ
Zej        ZdZ ej         ed          ej        ej        z            Zed             Zd Zd	 Zd
Zed             Zd Zed             Zd ZdS )r   a  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
    r1   truncate_error   r$   r   zU
        ^
        (?P<salt>[./a-z0-9]{2})
        (?P<chk>[./a-z0-9]{11})?
        $c                 j    t          |dd          }|d d         |dd          }} | ||pd           S )Nasciihashr$   r1   checksum)r   )clsrF   r1   chks       r   from_stringzdes_crypt.from_string   sE    $00!Hd122hcss{d3333r   c                 \    t          d          | j        | j        fz  }t          |          S Nz%s%sr
   r1   rH   r   selfrF   s     r   	to_stringzdes_crypt.to_string   )    yyDIt}55T"""r   c                 d    | j         r|                     |           |                     |          S )N)use_defaults_check_truncate_policy_calc_checksum_backendrP   r!   s     r   _calc_checksumzdes_crypt._calc_checksum   s5     	0''///**6222r   os_cryptbuiltinc                 ^    t          dd          r|                     | j                   dS dS )NtestabgOeLfPimXQoTFr   _set_calc_checksum_backend_calc_checksum_os_cryptrI   s    r   _load_backend_os_cryptz des_crypt._load_backend_os_crypt   s5    fo.. 	**3+FGGG45r   c                    t          || j                  }||                     |          S |                    | j                  rt	          |          dk    r&t
          j                            | | j        |          |dd          S )N   r$   )r   r1   _calc_checksum_builtin
startswithr'   r-   r.   CryptBackendError)rP   r!   rF   s      r   ra   z!des_crypt._calc_checksum_os_crypt   s~     &$),,< ..v666ty)) 	BSYY"__&**4DAAAABBxr   c                 :    |                      | j                   dS NTr`   rf   rb   s    r   _load_backend_builtinzdes_crypt._load_backend_builtin       &&s'ABBBtr   c                 x    t          || j                            d                                        d          S NrE   )r5   r1   r*   decoderW   s     r   rf   z des_crypt._calc_checksum_builtin   s0    fdi&6&6w&?&?@@GGPPPr   N)__name__
__module____qualname____doc__namesetting_kwdsr-   HASH64_CHARSchecksum_charschecksum_sizemin_salt_sizemax_salt_size
salt_charstruncate_sizerecompiler
   XI_hash_regexclassmethodrK   rQ   rX   backendsrc   ra   rl   rf    r   r   r   r   p   s!        H D-L
 _NM
 %&%MMJ
 M "*QQ     tBDy	 K 4 4 [4
# # #3 3 3 'H
   [
 
 
   [Q Q Q Q Qr   r   c                   @    e Zd ZdZd ZdZdZej        Z	dxZ
Zej        ZdZdZdZdZ ej         ed	          ej        ej        z            Zed
             Zd ZdZe fd            Ze fd            Z fdZdZed             Zd Z ed             Z!d Z" xZ#S )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).
    )r1   r>   rC      i     i linearz
        ^
        _
        (?P<rounds>[./a-z0-9]{4})
        (?P<salt>[./a-z0-9]{4})
        (?P<chk>[./a-z0-9]{11})?
        $c                 6   t          |dd          }| j                            |          }|st          j                            |           |                    ddd          \  }}} | t          j        |	                    d                    ||          S )NrE   rF   r>   r1   rJ   )r>   r1   rH   )
r   r   matchr-   r.   InvalidHashErrorgroupr   r=   r*   )rI   rF   mr>   r1   rJ   s         r   rK   zbsdi_crypt.from_string4  s    $00O!!$'' 	/&))#...GGHfe<<cs#FMM'$:$:;;
 
 
 	
r   c                     t          d          t          j        | j                                      d          | j        | j        fz  }t          |          S )Nz_%s%s%srE   )r
   r   encode_int24r>   rp   r1   rH   r   rO   s     r   rQ   zbsdi_crypt.to_stringA  sK    ||s/<<CCGLL#y$-9 9T"""r   Tc                      t          t          |           j        di |}|j        dz  st	          dt
          j        j                   |S )Nr   zHbsdi_crypt rounds should be odd, as even rounds may reveal weak DES keysr   )superr   usingdefault_roundsr   r-   r.   PasslibSecurityWarning)rI   kwdssubcls	__class__s      r   r   zbsdi_crypt.usingN  sW    -z3''-5555$q( 	0[.0 0 0r   c                 \    t          t          |                                           }|dz  S )Nr   )r   r   _generate_rounds)rI   r>   r   s     r   r   zbsdi_crypt._generate_roundsW  s)    z3''88:: axr   c                 \    | j         dz  sdS  t          t          |           j        di |S )Nr   Tr   )r>   r   r   _calc_needs_update)rP   r   r   s     r   r   zbsdi_crypt._calc_needs_updatee  s9    {Q 	49uZ&&9AADAAAr   rY   c                 ^    t          dd          r|                     | j                   dS dS )Nr]   z_/...lLDAxARksGCHin.TFr_   rb   s    r   rc   z!bsdi_crypt._load_backend_os_cryptt  s6    f455 	**3+FGGG45r   c                 .   |                                  }t          ||          }||                     |          S |                    |d d                   rt	          |          dk    r!t
          j                            | ||          |dd          S )N	      )rQ   r   rf   rg   r'   r-   r.   rh   )rP   r!   configrF   s       r   ra   z"bsdi_crypt._calc_checksum_os_crypt|  s    !!&&))< ..v666vbqbz** 	?c$ii2oo&**4>>>CDDzr   c                 :    |                      | j                   dS rj   rk   rb   s    r   rl   z bsdi_crypt._load_backend_builtin  rm   r   c                     t          || j        | j                            d                                        d          S ro   )r?   r>   r1   r*   rp   rW   s     r   rf   z!bsdi_crypt._calc_checksum_builtin  s5    vt{DI4D4DW4M4MNNUUV]^^^r   )$rq   rr   rs   rt   ru   rv   ry   r-   rw   rx   rz   r{   r|   r   
min_rounds
max_roundsrounds_costr~   r   r
   r   r   r   r   rK   rQ   _avoid_even_roundsr   r   r   r   rc   ra   rl   rf   __classcell__r   s   @r   r   r      s        F D%LM_N %&%MMJ NJJK "*QQ     tBDy K 

 

 [

# # #     [     [B B B B B 'H
   [	 	 	   [_ _ _ _ _ _ _r   r   c                        e Zd ZdZd ZdZej        ZdxZ	Z
ej        Z ej         ed          ej        ej        z            Zed             Zd Zd
 fd	Zd	 Z xZS )r   ag  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
    )r1   r$   zX
        ^
        (?P<salt>[./a-z0-9]{2})
        (?P<chk>([./a-z0-9]{11})+)?
        $c                     t          |dd          }| j                            |          }|st          j                            |           |                    dd          \  }} | ||          S NrE   rF   r1   rJ   rG   r   r   r   r-   r.   r   r   rI   rF   r   r1   rJ   s        r   rK   zbigcrypt.from_string  r    $00O!!$'' 	/&))#...GGFE**	css++++r   c                 \    t          d          | j        | j        fz  }t          |          S rM   rN   rO   s     r   rQ   zbigcrypt.to_string  rR   r   Fc                     t          t          |                               ||          }t          |          dz  rt          j                            |           |S )N)relaxedrC   )r   r   _norm_checksumr'   r-   r.   r   )rP   rH   r   r   s      r   r   zbigcrypt._norm_checksum  sS    4((77'7RRx==2 	0&))$///r   c                 ^   t          |t                    r|                    d          }t          || j                            d                    }d}t          |          }||k     r0|dz   }|t          |||         |dd                   z  }|}||k     0|                    d          S )Nr%   rE   r   r   i)r)   r   r*   r5   r1   r'   rp   )rP   r!   rJ   r7   r8   r9   s         r   rX   zbigcrypt._calc_checksum  s    fg&& 	,]]7++FVTY%5%5g%>%>??&kkCii7D>&T"2CBK@@@CC Cii zz'"""r   )F)rq   rr   rs   rt   ru   rv   r-   rw   rx   rz   r{   r|   r~   r   r
   r   r   r   r   rK   rQ   r   rX   r   r   s   @r   r   r     s         4 DL_N %&%MMJ
 "*QQ     tBDy	 K , , [,# # #     
# 
# 
# 
# 
# 
# 
#r   r   c                       e Zd ZdZd ZdZdZej        Z	dxZ
Zej        ZdZ ej         ed          ej        ej        z            Zed             Zd Zd	 Zd
S )r   a  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
    rA      r$      zU
        ^
        (?P<salt>[./a-z0-9]{2})
        (?P<chk>[./a-z0-9]{22})?
        $c                     t          |dd          }| j                            |          }|st          j                            |           |                    dd          \  }} | ||          S r   r   r   s        r   rK   zcrypt16.from_string+  r   r   c                 \    t          d          | j        | j        fz  }t          |          S rM   rN   rO   s     r   rQ   zcrypt16.to_string4  rR   r   c                 N   t          |t                    r|                    d          }| j        r|                     |           	 t          j        | j                            d                    }n*# t          $ r t          t          d                    w xY wt          |          }t          |d|d          }t          |dd                   }t          |d|d          }t          j        |          t          j        |          z   }|                    d          S )	Nr%   rE   zinvalid chars in saltr   r   r   r      )r)   r   r*   rT   rU   r   r(   r1   
ValueErrorr   r"   r   r   r0   rp   )rP   r!   r2   key1result1key2result2rJ   s           r   rX   zcrypt16._calc_checksum;  s(   fg&& 	,]]7++F  	0''///	F)$)*:*:7*C*CDDJJ 	F 	F 	F ,C!D!DEEE	F $F++ (aR@@ $F1R4L11 (aQ?? !'**V-@-I-IIzz'"""s   ,A5 5'BN)rq   rr   rs   rt   ru   rv   ry   r-   rw   rx   rz   r{   r|   r}   r~   r   r
   r   r   r   r   rK   rQ   rX   r   r   r   r   r     s         H D-L
 M_N
 %&%MMJ
 M
 "*QQ     tBDy	 K , , [,# # ## # # # #r   r   )*rt   r~   logging	getLoggerrq   logwarningsr   passlib.utilsr   r   r   passlib.utils.binaryr   r   passlib.utils.compatr	   r
   r   r   r   passlib.crypto.desr   passlib.utils.handlersutilshandlersr-   __all__r,   r"   r5   r;   r?   TruncateMixinHasManyBackendsHasSaltGenericHandlerr   	HasRoundsr   r   r   r   r   r   <module>r      sA   L L
 
			 'g'11       = < < < < < < < < < , , , , , , , , [ [ [ [ [ [ [ [ [ [ [ [ [ [ 4 4 4 4 4 4 # # # # # # # # #   
2 2 2' ' '<
 
 
' ' '6}Q }Q }Q }Q }Q ""4bj"BS }Q }Q }QF]_ ]_ ]_ ]_ ]_#R\2:r?P ]_ ]_ ]_FM# M# M# M# M#rz2, M# M# M#fn# n# n# n# n#b
B,= n# n# n# n# n#r   