a
    Oʞhw                     @   s   d Z ddlmZmZ ddlZddlZeeZddl	m
Z
 ddlm  mZ ddlmZmZmZmZ ddlmZ dgZG dd dejejejejZdS )	zpasslib.handlers.fshp
    )	b64encode	b64decodeN)
to_unicode)bascii_to_str	iteritemsuunicode)pbkdf1fshpc                       s   e Zd ZdZd ZdZejZe	dZ
dZdZdZdZdZd	ZdZd
ddddZedd eD dd eeD  Zed# fdd	ZdZd$ fdd	Zedd Zedd Zedd Zee	dej Z!edd Z"dd  Z#d!d" Z$  Z%S )%r
   ap  This class implements the FSHP password hash, and follows the :ref:`password-hash-api`.

    It supports a variable-length salt, and a variable number of rounds.

    The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords:

    :param salt:
        Optional raw salt string.
        If not specified, one will be autogenerated (this is recommended).

    :param salt_size:
        Optional number of bytes to use when autogenerating new salts.
        Defaults to 16 bytes, but can be any non-negative value.

    :param rounds:
        Optional number of rounds to use.
        Defaults to 480000, must be between 1 and 4294967295, inclusive.

    :param variant:
        Optionally specifies variant of FSHP to use.

        * ``0`` - uses SHA-1 digest (deprecated).
        * ``1`` - uses SHA-2/256 digest (default).
        * ``2`` - uses SHA-2/384 digest.
        * ``3`` - uses SHA-2/512 digest.

    :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
    )salt	salt_sizeroundsvariantz{FSHP   Ni S    l    Zlinear)sha1   )sha256    )sha3840   )sha512@   )r   r         c                 C   s   g | ]}t ||fqS  )r   ).0kr   r   P/wd/webapps/venvs/v2025_4um/lib/python3.9/site-packages/passlib/handlers/fshp.py
<listcomp>_       zfshp.<listcomp>c                 C   s   g | ]\}}|d  |fqS )r   r   )r   r   vr   r   r   r   `   r    c                    s.   t t| jf i |}|d ur*| ||_|S )N)superr
   using_norm_variantdefault_variant)clsr   kwdssubcls	__class__r   r   r#   f   s    z
fshp.usingc                    sr   | d| _|d ur | |}n2| jrJ| j}| ||ksRJ d|f ntd|| _tt| jf i | d S )Nuse_defaultszinvalid default variant: %rzno variant specified)	getr+   r$   r%   	TypeErrorr   r"   r
   __init__)selfr   r'   r)   r   r   r.   u   s    zfshp.__init__c                 C   sp   t |tr|d}t |trHz| j| }W n tyF   tdY n0 t |tsZtd|| j	vrltd|S )Nasciizinvalid fshp variantz'fshp variant must be int or known alias)

isinstancebytesdecoder   _variant_aliasesKeyError
ValueErrorintr-   _variant_info)r&   r   r   r   r   r$      s    




zfshp._norm_variantc                 C   s   | j | j d S )Nr   r8   r   r/   r   r   r   checksum_alg   s    zfshp.checksum_algc                 C   s   | j | j d S )Nr   r9   r:   r   r   r   checksum_size   s    zfshp.checksum_sizez
            ^
            \{FSHP
            (\d+)\| # variant
            (\d+)\| # salt size
            (\d+)\} # rounds
            ([a-zA-Z0-9+/]+={0,3}) # digest
            $c           	      C   s   t |dd}| j|}|s(tj| |dddd\}}}}t|}t|}t|}zt|	d}W n t
y   tj| Y n0 |d | }||d  }| ||||dS )Nr0   hashr   r   r      )r   checksumr   r   )r   _hash_regexmatchuhexcZInvalidHashErrorgroupr7   r   encoder-   ZMalformedHashError)	r&   r=   mr   r   r   datar   chkr   r   r   from_string   s    zfshp.from_stringc                 C   s4   | j }| j}tt|| }d| jt|| j|f S )Nz{FSHP%d|%d|%d}%s)r?   r   r   r   r   lenr   )r/   rH   r   rG   r   r   r   	to_string   s    zfshp.to_stringc                 C   s.   t |tr|d}t| j| j|| j| jdS )Nzutf-8)digestsecretr   r   Zkeylen)r1   r   rE   r	   r;   r   r   r<   )r/   rM   r   r   r   _calc_checksum   s    

zfshp._calc_checksum)N)N)&__name__
__module____qualname____doc__nameZsetting_kwdsrB   ZPADDED_BASE64_CHARSZchecksum_charsr   identZdefault_salt_sizeZmax_salt_sizeZdefault_roundsZ
min_rounds
max_roundsZrounds_costr%   r8   dictr   r4   classmethodr#   r   r.   r$   propertyr;   r<   recompileXr@   rI   rK   rN   __classcell__r   r   r)   r   r
      sN   )	



	

)rR   base64r   r   rY   logging	getLoggerrO   logZpasslib.utilsr   Zpasslib.utils.handlersutilshandlersrB   Zpasslib.utils.compatr   r   r   r   Zpasslib.crypto.digestr	   __all__Z	HasRoundsZ
HasRawSaltZHasRawChecksumZGenericHandlerr
   r   r   r   r   <module>   s   