o
    5h_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   n/var/www/html/construction_image-detection-poc/venv/lib/python3.10/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-   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_policy_calc_checksum_backendrH   r   r   r   r   _calc_checksum   s   

zdes_crypt._calc_checksumos_cryptbuiltinc                 C      t ddr| | j dS dS )NtestabgOeLfPimXQoTFr   _set_calc_checksum_backend_calc_checksum_os_cryptrA   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)rH   r   r>   r   r   r   rX      s   
z!des_crypt._calc_checksum_os_cryptc                 C      |  | j dS NTrW   r]   rY   r   r   r   _load_backend_builtin      zdes_crypt._load_backend_builtinc                 C   s   t || jddS Nr=   )r1   r-   r&   decoderN   r   r   r   r]      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classmethodrC   rI   rO   backendsrZ   rX   rc   r]   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 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-   rB   )r8   r-   r@   )
r   rx   matchr)   r*   InvalidHashErrorgroupr   r7   r&   )rA   r>   mr8   r-   rB   r   r   r   rC   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   encode_int24r8   rf   r-   r@   r
   rG   r   r   r   rI   A  s   zbsdi_crypt.to_stringTc                    s2   t t| jdi |}|jd@ 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)rA   kwdssubcls	__class__r   r   r   N  s   
zbsdi_crypt.usingc                    s   t t|  }|dB S )Nr|   )r   r   _generate_rounds)rA   r8   r   r   r   r   W  s   zbsdi_crypt._generate_roundsc                    s$   | j d@ sdS tt| jdi |S )Nr|   Tr   )r8   r   r   _calc_needs_update)rH   r   r   r   r   r   e  s   
zbsdi_crypt._calc_needs_updaterP   c                 C   rS   )NrT   z_/...lLDAxARksGCHin.TFrV   rY   r   r   r   rZ   t  r[   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	      )rI   r   r]   r^   r#   r)   r*   r_   )rH   r   configr>   r   r   r   rX   |  s   

z"bsdi_crypt._calc_checksum_os_cryptc                 C   r`   ra   rb   rY   r   r   r   rc     rd   z bsdi_crypt._load_backend_builtinc                 C   s   t || j| jddS re   )r9   r8   r-   r&   rf   rN   r   r   r   r]     s   z!bsdi_crypt._calc_checksum_builtin)$rg   rh   ri   rj   rk   rl   ro   r)   rm   rn   rp   rq   rr   r   
min_rounds
max_roundsrounds_costrt   ru   r	   rv   rw   rx   ry   rC   rI   _avoid_even_roundsr   r   r   rz   rZ   rX   rc   r]   __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-   rB   r?   r   rx   r~   r)   r*   r   r   rA   r>   r   r-   rB   r   r   r   rC        zbigcrypt.from_stringc                 C   rD   rE   rF   rG   r   r   r   rI     rJ   zbigcrypt.to_stringFc                    s0   t t| j||d}t|d rtj| |S )N)relaxedr<   )r   r   _norm_checksumr#   r)   r*   r   )rH   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#   rf   )rH   r   rB   r2   r3   r4   r   r   r   rO     s   


zbigcrypt._calc_checksum)F)rg   rh   ri   rj   rk   rl   r)   rm   rn   rp   rq   rr   rt   ru   r	   rv   rw   rx   ry   rC   rI   r   rO   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   rC   +  r   zcrypt16.from_stringc                 C   rD   rE   rF   rG   r   r   r   rI   4  rJ   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&   rK   rL   r   r$   r-   
ValueErrorr   r   r   r   r,   rf   )rH   r   r.   key1result1key2result2rB   r   r   r   rO   ;  s   



zcrypt16._calc_checksumN)rg   rh   ri   rj   rk   rl   ro   r)   rm   rn   rp   rq   rr   rs   rt   ru   r	   rv   rw   rx   ry   rC   rI   rO   r   r   r   r   r     s     $


r   )*rj   rt   logging	getLoggerrg   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   r1   r6   r9   TruncateMixinHasManyBackendsHasSaltGenericHandlerr   	HasRoundsr   r   r   r   r   r   r   <module>   s*    
  $S