o
    _6d_W                     @   s$  d Z ddlZddlZe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  mZ g dZd	Zd
d Zdd Zdd Zdd Z G dd dej!ej"ej#ej$Z%G dd dej"ej&ej#ej$Z'G dd dej#ej$Z(G d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                 C   s   t d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                 s   s,    | ]\}}t |d @ d|d  > V  qdS )   9      N)r   ).0ic r   qC:\Users\jesus\OneDrive\Desktop\erpjis_fastapi\backend\jisbackend\Lib\site-packages\passlib/handlers/des_crypt.py	<genexpr>(   s     z'_crypt_secret_to_key.<locals>.<genexpr>Nr   )sum	enumerate)secretr   r   r   _crypt_secret_to_key   s   r   c                 C   sp   t |dksJ t|}t| tr| d} t| tsJ t| v r(tj	
tt| }t|d|d}t|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resultr   r   r   _raw_des_crypt+   s   



r1   c                 C   sR   t | }d}t| }||k r'|d }t | || }t|||A }|}||k s|S )z,convert secret to DES key used by bsdi_cryptr   )r   r#   r   )r   r/   idxendnext	tmp_valuer   r   r   _bsdi_secret_to_keyI   s   r6   c                 C   s`   t |}t| tr| d} t| tsJ t| v r tj	t
t| }t|d||}t|S )z"pure-python backend for bsdi_cryptr!   r   )r   decode_int24r%   r   r&   r'   r(   r)   r*   r+   r   r6   r   r   r,   )r   roundsr-   r.   r/   r0   r   r   r   _raw_bsdi_cryptU   s   



r9   c                   @   s   e Zd ZdZd ZdZejZdZ	d Z
ZejZdZeedejejB Zedd Zd	d
 Zdd ZdZedd Zdd Zedd Zd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
    r-   Ztruncate_error   r    r   zU
        ^
        (?P<salt>[./a-z0-9]{2})
        (?P<chk>[./a-z0-9]{11})?
        $c                 C   s6   t |dd}|d d |dd  }}| ||pd dS )Nasciihashr    r-   checksum)r   )clsr=   r-   chkr   r   r   from_string   s   zdes_crypt.from_stringc                 C      t d| j| jf }t|S Nz%s%sr	   r-   r?   r
   selfr=   r   r   r   	to_string      zdes_crypt.to_stringc                 C   s   | j r| | | |S )N)use_defaults_check_truncate_policyZ_calc_checksum_backendrG   r   r   r   r   _calc_checksum   s   

zdes_crypt._calc_checksumZos_cryptbuiltinc                 C      t ddr| | j dS dS )NtestZabgOeLfPimXQoTFr   _set_calc_checksum_backend_calc_checksum_os_cryptr@   r   r   r   _load_backend_os_crypt      
z des_crypt._load_backend_os_cryptc                 C   sT   t || j}|d u r| |S || jrt|dkr$tj| | j||dd  S )N   r    )r   r-   _calc_checksum_builtin
startswithr#   r)   r*   CryptBackendError)rG   r   r=   r   r   r   rT      s   
z!des_crypt._calc_checksum_os_cryptc                 C      |  | j dS NTrS   rY   rU   r   r   r   _load_backend_builtin      zdes_crypt._load_backend_builtinc                 C   s   t || jddS Nr<   )r1   r-   r&   decoderL   r   r   r   rY      s   z des_crypt._calc_checksum_builtinN)__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classmethodrB   rH   rM   backendsrV   rT   r_   rY   r   r   r   r   r   p   s.    $





r   c                       s   e Zd ZdZd ZdZdZejZ	d Z
ZejZdZdZdZdZeed	ejejB Zed
d Zdd ZdZe fddZe fddZ fddZdZedd Zdd Z edd Z!dd Z"  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).
    )r-   r8   r;      i     i Zlinearz
        ^
        _
        (?P<rounds>[./a-z0-9]{4})
        (?P<salt>[./a-z0-9]{4})
        (?P<chk>[./a-z0-9]{11})?
        $c                 C   sV   t |dd}| j|}|stj| |ddd\}}}| t|	d||dS )Nr<   r=   r8   r-   rA   )r8   r-   r?   )
r   rt   matchr)   r*   InvalidHashErrorgroupr   r7   r&   )r@   r=   mr8   r-   rA   r   r   r   rB   4  s   zbsdi_crypt.from_stringc                 C   s,   t dt| jd| j| jf }t|S )Nz_%s%s%sr<   )r	   r   Zencode_int24r8   rb   r-   r?   r
   rF   r   r   r   rH   A  s   zbsdi_crypt.to_stringTc                    s2   t t| jdi |}|jd@ stdtjj |S )Nrx   zHbsdi_crypt rounds should be odd, as even rounds may reveal weak DES keysr   )superr   usingdefault_roundsr   r)   r*   ZPasslibSecurityWarning)r@   kwdssubcls	__class__r   r   r~   N  s   
zbsdi_crypt.usingc                    s   t t|  }|dB S )Nrx   )r}   r   _generate_rounds)r@   r8   r   r   r   r   W  s   zbsdi_crypt._generate_roundsc                    s$   | j d@ sdS tt| jdi |S )Nrx   Tr   )r8   r}   r   _calc_needs_update)rG   r   r   r   r   r   e  s   
zbsdi_crypt._calc_needs_updaterN   c                 C   rP   )NrQ   z_/...lLDAxARksGCHin.TFrR   rU   r   r   r   rV   t  rW   z!bsdi_crypt._load_backend_os_cryptc                 C   s^   |   }t||}|d u r| |S ||d d r!t|dkr)tj| |||dd  S )N	      )rH   r   rY   rZ   r#   r)   r*   r[   )rG   r   configr=   r   r   r   rT   |  s   

z"bsdi_crypt._calc_checksum_os_cryptc                 C   r\   r]   r^   rU   r   r   r   r_     r`   z bsdi_crypt._load_backend_builtinc                 C   s   t || j| jddS ra   )r9   r8   r-   r&   rb   rL   r   r   r   rY     s   z!bsdi_crypt._calc_checksum_builtin)$rc   rd   re   rf   rg   rh   rk   r)   ri   rj   rl   rm   rn   r   Z
min_rounds
max_roundsZrounds_costrp   rq   r	   rr   rs   rt   ru   rB   rH   Z_avoid_even_roundsr~   r   r   rv   rV   rT   r_   rY   __classcell__r   r   r   r   r      s>    #





r   c                       sr   e Zd ZdZd ZdZejZd Z	Z
ejZeedejejB Zedd Zdd Zd fd
d	Zdd Z  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
    )r-   r    zX
        ^
        (?P<salt>[./a-z0-9]{2})
        (?P<chk>([./a-z0-9]{11})+)?
        $c                 C   D   t |dd}| j|}|stj| |dd\}}| ||dS Nr<   r=   r-   rA   r>   r   rt   ry   r)   r*   rz   r{   r@   r=   r|   r-   rA   r   r   r   rB        zbigcrypt.from_stringc                 C   rC   rD   rE   rF   r   r   r   rH     rI   zbigcrypt.to_stringFc                    s0   t t| j||d}t|d rtj| |S )N)relaxedr;   )r}   r   _norm_checksumr#   r)   r*   rz   )rG   r?   r   r   r   r   r     s   zbigcrypt._norm_checksumc                 C   sv   t |tr
|d}t|| jd}d}t|}||k r6|d }|t||| |dd 7 }|}||k s|dS )Nr!   r<   r   r   i)r%   r   r&   r1   r-   r#   rb   )rG   r   rA   r2   r3   r4   r   r   r   rM     s   


zbigcrypt._calc_checksum)F)rc   rd   re   rf   rg   rh   r)   ri   rj   rl   rm   rn   rp   rq   r	   rr   rs   rt   ru   rB   rH   r   rM   r   r   r   r   r   r     s    


	r   c                   @   sh   e Zd ZdZd ZdZdZejZ	d Z
ZejZdZeedejejB Zedd Zd	d
 Zd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
    r:      r       zU
        ^
        (?P<salt>[./a-z0-9]{2})
        (?P<chk>[./a-z0-9]{22})?
        $c                 C   r   r   r   r   r   r   r   rB   +  r   zcrypt16.from_stringc                 C   rC   rD   rE   rF   r   r   r   rH   4  rI   zcrypt16.to_stringc                 C   s   t |tr
|d}| jr| | zt| jd}W n ty*   t	tdw t
|}t|d|d}t
|dd }t|d|d}t|t| }|dS )	Nr!   r<   zinvalid chars in saltr   r   r   r      )r%   r   r&   rJ   rK   r   r$   r-   
ValueErrorr   r   r   r   r,   rb   )rG   r   r.   key1Zresult1key2Zresult2rA   r   r   r   rM   ;  s   



zcrypt16._calc_checksumN)rc   rd   re   rf   rg   rh   rk   r)   ri   rj   rl   rm   rn   ro   rp   rq   r	   rr   rs   rt   ru   rB   rH   rM   r   r   r   r   r     s     $


r   )*rf   rp   logging	getLoggerrc   logwarningsr   Zpasslib.utilsr   r   r   Zpasslib.utils.binaryr   r   Zpasslib.utils.compatr   r	   r
   r   r   Zpasslib.crypto.desr   Zpasslib.utils.handlersutilshandlersr)   __all__r(   r   r1   r6   r9   ZTruncateMixinZHasManyBackendsZHasSaltZGenericHandlerr   Z	HasRoundsr   r   r   r   r   r   r   <module>   s*    
  $S