U
    h5                     @   s   d Z ddlmZ ddlZeeZddlmZm	Z	m
Z
 ddlmZ ddlmZmZ ddlm  mZ ddgZd	Zd
ZdZdZdZdddZG dd dejejZG dd dejeZG dd deZ dS )z0passlib.handlers.md5_crypt - md5-crypt algorithm    )md5N)
safe_crypt
test_cryptrepeat_string)h64)unicodeu	md5_cryptapr_md5_crypt    s   $1$s   $apr1$))r            r   r   )r      r   r   r   r   )   r   r   r   )r   r   r   r   r   )r   r   r   r   )r   r   r   r   r   )      r         r         r      	   r   r   
   r      Fc                    s  t | tr| d} t | ts&tdt| kr:tjt	t
| }t |tsTtd|d}t
|dk srtd|r|t}nt}t| | |   }t| | | }|j}|t|| |}| dd }	|r||d@ rtn|	 |dL }q| }
| |  }| | }| ||||  ||  || g  fd	d
tD }|
}d}|rv|D ]&\}}t|t||    }qB|d8 }q8|dd D ]&\}}t|t||    }qt|tdS )a  perform raw md5-crypt calculation

    this function provides a pure-python implementation of the internals
    for the MD5-Crypt algorithms; it doesn't handle any of the
    parsing/validation of the hash strings themselves.

    :arg pwd: password chars/bytes to hash
    :arg salt: salt chars to use
    :arg use_apr: use apache variant

    :returns:
        encoded checksum chars
    zutf-8zpwd not unicode or byteszsalt not unicodeasciir   zsalt too largeNr   c                    s    g | ]\}} |  | fqS  r   ).0evenoddZpermsr   @./venv/lib/python3.8/site-packages/passlib/handlers/md5_crypt.py
<listcomp>   s     z"_raw_md5_crypt.<locals>.<listcomp>      )
isinstancer   encodebytesAssertionError_BNULLuhexcZNullPasswordErrorr	   len
_APR_MAGIC
_MD5_MAGICr   Zdigestupdater   _c_digest_offsetsr   Zencode_transposed_bytes_transpose_mapdecode)pwdsaltuse_aprZpwd_lenmagicZdbZa_ctxZa_ctx_updateiZevenchardaZpwd_pwdZpwd_saltdataZdcZblocksr!   r"   r   r#   r$   _raw_md5_crypt,   sF    



.  r=   c                   @   s<   e Zd ZdZdZdZejZdZ	ejZ
edd Zdd Zd	S )
_MD5_Commonz+common code for md5_crypt and apr_md5_crypt)r7   Z	salt_size   r   c                 C   s"   t j|| j| d\}}| ||dS )N)Zhandler)r7   checksum)r-   Z	parse_mc2ident)clshashr7   Zchkr   r   r$   from_string   s    z_MD5_Common.from_stringc                 C   s   t | j| j| jS N)r-   Z
render_mc2rA   r7   r@   )selfr   r   r$   	to_string   s    z_MD5_Common.to_stringN)__name__
__module____qualname____doc__Zsetting_kwdsZchecksum_sizer-   ZHASH64_CHARSZchecksum_charsZmax_salt_sizeZ
salt_charsclassmethodrD   rG   r   r   r   r$   r>      s   
r>   c                   @   sH   e Zd ZdZd Ze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 MD5-Crypt password hash, and follows the :ref:`password-hash-api`.

    It supports a variable-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 0-8 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 8, but can be any value between 0 and 8.
        (This is mainly needed when generating Cisco-compatible hashes,
        which require ``salt_size=4``).

    :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
    z$1$)Zos_cryptZbuiltinc                 C   s"   t ddr| | j dS dS d S )NZtestz$1$test$pi/xDtU5WFVRqYS6BMU8X/TF)r   _set_calc_checksum_backend_calc_checksum_os_cryptrB   r   r   r$   _load_backend_os_crypt  s    
z md5_crypt._load_backend_os_cryptc                 C   sb   | j | j }t||}|d kr(| |S ||rFt|t|d krVtj| |||dd  S )Nr&   i)	rA   r7   r   _calc_checksum_builtin
startswithr/   r-   r.   ZCryptBackendError)rF   secretZconfigrC   r   r   r$   rN     s    

z!md5_crypt._calc_checksum_os_cryptc                 C   s   |  | j dS )NT)rM   rQ   rO   r   r   r$   _load_backend_builtin%  s    zmd5_crypt._load_backend_builtinc                 C   s   t || jS rE   r=   r7   rF   rS   r   r   r$   rQ   *  s    z md5_crypt._calc_checksum_builtinN)rH   rI   rJ   rK   namer   rA   ZbackendsrL   rP   rN   rT   rQ   r   r   r   r$   r	      s    

c                   @   s$   e Zd ZdZd ZedZdd ZdS )r
   ap  This class implements the Apr-MD5-Crypt password hash, and follows the :ref:`password-hash-api`.

    It supports a variable-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 0-8 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
    z$apr1$c                 C   s   t || jddS )NT)r8   rU   rV   r   r   r$   _calc_checksumQ  s    zapr_md5_crypt._calc_checksumN)rH   rI   rJ   rK   rW   r   rA   rX   r   r   r   r$   r
   1  s   )F)!rK   Zhashlibr   ZloggingZ	getLoggerrH   logZpasslib.utilsr   r   r   Zpasslib.utils.binaryr   Zpasslib.utils.compatr   r   Zpasslib.utils.handlersZutilsZhandlersr-   __all__r,   r1   r0   r3   r4   r=   ZHasSaltZGenericHandlerr>   ZHasManyBackendsr	   r
   r   r   r   r$   <module>   s(    


  Q