o
    5h                  	   @   s  d Z ddlmZmZ ddlZeeZddlZddl	Z	ddl
mZ dZdaddlm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   m!Z" d
gZ#edZ$edZ%edZ&e&e$e%fZ'e(e'Z)dZ*zddl+ZW n e,y   dZY nw e-edsdZ*dZn	e-edsdZ*dZe-edre. Z/ej0j1Z2nG dd dZ3e3 Z/dZ2G dd de"j4e"j5e"j6e"j7e"j8e"j9Z:G dd de:Z;G dd de:Z<G dd de:Z=G dd
 d
e;e:Z+dS )a  passlib.handlers.argon2 -- argon2 password hash wrapper

References
==========
* argon2
    - home: https://github.com/P-H-C/phc-winner-argon2
    - whitepaper: https://github.com/P-H-C/phc-winner-argon2/blob/master/argon2-specs.pdf
* argon2 cffi wrapper
    - pypi: https://pypi.python.org/pypi/argon2_cffi
    - home: https://github.com/hynek/argon2_cffi
* argon2 pure python
    - pypi: https://pypi.python.org/pypi/argon2pure
    - home: https://github.com/bwesterb/argon2pure
    )with_statementabsolute_importN)warn)exc)
MAX_UINT32)classpropertyto_bytesrender_bytes)b64s_encodeb64s_decode)uunicodebascii_to_struascii_to_strPY2argon2ididTypezb'argon2' module points to unsupported 'argon2' pypi package; please install 'argon2-cffi' instead.	low_levelz@'argon2-cffi' is too old, please update to argon2_cffi >= 18.2.0PasswordHasherc                   @   s$   e Zd ZdZdZdZdZdZdZdS )_DummyCffiHashera  
        dummy object to use as source of defaults when argon2_cffi isn't present.
        this tries to mimic the attributes of ``argon2.PasswordHasher()`` which the rest of
        this module reads.

        .. note:: values last synced w/ argon2 19.2 as of 2019-11-09
           i      N)	__name__
__module____qualname____doc__	time_costmemory_costparallelismsalt_lenhash_len r$   r$   k/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/passlib/handlers/argon2.pyr   ]   s    r      c                       sj  e Zd ZdZdZdZejZe	j
jd Ze	j
jd ZejZdZeZejZdZeZdZd	ZeZd
ZdZdZdZi Zedd Z e!Z"ej#Z#eZ$ej%Z%e&dd Z'd
Z(e)	
	
d. fdd	Z*e)dd Z+e,-dZ.e)dd Z/e,-de,j0Z1e)dd Z2dd Z3d/ fdd	Z4e)dd  Z5e)d!d" Z6e)d0d#d$Z7e)d%d& Z8 fd'd(Z9d)Z:e)d*d+ Z;e)d1d,d-Z<  Z=S )2_Argon2Commona&  
    Base class which implements brunt of Argon2 code.
    This is then subclassed by the various backends,
    to override w/ backend-specific methods.

    When a backend is loaded, the bases of the 'argon2' class proper
    are modified to prepend the correct backend-specific subclass.
    r   )
salt	salt_sizer"   roundsr   r    r!   digest_sizer#   type)r,   )r"   r   r#   r+         lineari NFc                 C   s   |    t| jS )zj
        return tuple of types supported by this backend
        
        .. versionadded:: 1.7.2
        )get_backendtuple_backend_type_map)clsr$   r$   r%   type_values   s   
z_Argon2Common.type_valuesc                 C   s
   | j tkS )zn
        flag indicating a Type D hash

        .. deprecated:: 1.7.2; will be removed in passlib 2.0
        )r,   TYPE_Dselfr$   r$   r%   type_d   s   
z_Argon2Common.type_dc	                    s`  |d urd|	v rt d||	d< |d ur d|	v rt d||	d< |d ur.|d ur,t d|}|d ur<|d ur:t d|}tt| jdi |	}
|d urQ|
||
_|	d}|d urpt|tj	rdt
|}tj|
|dtd	|d
|
_|d urt|tj	r~t
|}|
j||d|
_|
|
j|
j |d urt|tj	rt
|}|dk r|dkrtd|f ||
_|
S )Nr*   z/'time_cost' and 'rounds' are mutually exclusiver)   z1'salt_len' and 'salt_size' are mutually exclusivez3'hash_len' and 'digest_size' are mutually exclusivez8'checksum_size' and 'digest_size' are mutually exclusiverelaxedr   r+   )minmaxparamr:   )r:   r.   r0   z7max_threads (%d) must be -1 (unlimited), or at least 1.r$   )	TypeErrorsuperr'   using
_norm_typer,   get
isinstanceuhnative_string_typesintnorm_integerr   checksum_size_norm_memory_costr    _validate_constraintsr!   
ValueErrormax_threads)r4   r,   r    r"   r   r+   rH   r#   rL   kwdssubclsr:   	__class__r$   r%   r@     sP   
z_Argon2Common.usingc                 C   s*   d| }||k rt d| j|||f d S )Nr-   zO%s: memory_cost (%d) is too low, must be at least 8 * parallelism (8 * %d = %d))rK   name)r4   r    r!   min_memory_costr$   r$   r%   rJ   B  s   z#_Argon2Common._validate_constraintsz^\$argon2[a-z]+\$c                 C   s   t |}| j|d uS N)rD   to_unicode_for_identify_ident_regexmatch)r4   hashr$   r$   r%   identifyT  s   
z_Argon2Common.identifys  
        ^
        \$argon2(?P<type>[a-z]+)\$
        (?:
            v=(?P<version>\d+)
            \$
        )?
        m=(?P<memory_cost>\d+)
        ,
        t=(?P<time_cost>\d+)
        ,
        p=(?P<parallelism>\d+)
        (?:
            ,keyid=(?P<keyid>[^,$]+)
        )?
        (?:
            ,data=(?P<data>[^,$]+)
        )?
        (?:
            \$
            (?P<salt>[^$]+)
            (?:
                \$
                (?P<digest>.+)
            )?
        )?
        $
    c                 C   s   t |tr
|d}t |tst|d| j|}|s"t| |	ddddddd	d
d	\	}}}}}}}	}
}|r>t
d| |d|rIt|ndt|t|t||
rYt|
nd |	r`t|	nd |rit|dS d dS )Nutf-8rW   r,   versionr    r   r!   keyiddatar(   digestz&argon2 'keyid' parameter not supportedasciir   )r,   rZ   r    r*   r!   r(   r\   checksum)rC   r   encodebytesr   ExpectedStringError_hash_regexrV   MalformedHashErrorgroupNotImplementedErrordecoderF   r   )r4   rW   mr,   rZ   r    r   r!   r[   r\   r(   r]   r$   r$   r%   from_string  s2   




z_Argon2Common.from_stringc                 C   sv   | j }|dkr
d}nd| }| j}|rdtt| j }nd}dt| j|| j| j| j|tt| j	tt| j
f S )Nr    zv=%d$z,data=z"$argon2%s$%sm=%d,t=%d,p=%d%s$%s$%s)rZ   r\   r   r
   r   r,   r    r*   r!   r(   r_   )r8   rZ   vstrr\   kdstrr$   r$   r%   	to_string  s$   z_Argon2Common.to_stringc                    s  |rt d |d u sJ t}|d}|d urt|| _tt| jd	i | |d u r9tj	| | j
| jdds8J n| || _
|d u rQtj	| | j| jddsPJ n| || _|d u ritj	| | j| jddshJ n| || _|d u r|| jd u szJ d S t|tstj|dd|| _d S )
Nzoargon2 `type_d=True` keyword is deprecated, and will be removed in passlib 2.0; please use ``type="d"`` insteadr_   r,   )r=   rZ   r    ra   r\   r$   )r   r6   rB   lenrH   r?   r'   __init__rD   validate_default_valuer,   rA   rZ   _norm_versionr    rI   r\   rC   ra   r   ExpectedTypeError)r8   r,   r9   rZ   r    r\   rM   r_   rO   r$   r%   ro     s4   



z_Argon2Common.__init__c                 C   sb   t |tstrt |tr|d}ntj|dd|tv r |S |	 }|tv r*|S t
d|f )Nr^   strr,   zunknown argon2 hash type: %r)rC   r   r   ra   rg   rD   r   rr   ALL_TYPES_SETlowerrK   )r4   valuetempr$   r$   r%   rA     s   
z_Argon2Common._norm_typec                 C   sh   t |tjstj|dd|dk r|dkrtd|f |  }|| jkr2td| j||| jf |S )NintegerrZ   r&   r   zinvalid argon2 hash version: %dzk%s: hash version 0x%X not supported by %r backend (max version is 0x%X); try updating or switching backends)	rC   rD   	int_typesr   rr   rK   r1   max_versionrQ   )r4   rZ   backendr$   r$   r%   rq   	  s   
z_Argon2Common._norm_versionc                 C   s   t j| || jd|dS )Nr    )r;   r=   r:   )rD   rG   rR   )r4   r    r:   r$   r$   r%   rI     s   z_Argon2Common._norm_memory_costc                 C   s8   z| j | W S  ty   Y nw d||  f }t|)z>
        helper to resolve backend constant from type
        z=unsupported argon2 hash (type %r not supported by %s backend))r3   KeyErrorr1   rK   )r4   rv   msgr$   r$   r%   _get_backend_type%  s   
z_Argon2Common._get_backend_typec                    sz   t | }| j |j krdS |j}|d u s||jkr|j}| j|k r"dS | j|jkr*dS | j|jkr2dS tt| jdi |S )NTr$   )	r,   min_desired_versionrz   rZ   r    rH   r?   r'   _calc_needs_update)r8   rM   r4   minverrO   r$   r%   r   7  s   
z _Argon2Common._calc_needs_updatez> -- recommend you install one (e.g. 'pip install argon2_cffi')c                 C   sr   | j }t|tr|dksJ |dk rtd| tjj tD ]}|| jv r*|| _	 dS qtd| tjj
 t| _	dS )z
        helper called by from backend mixin classes' _load_backend_mixin() --
        invoked after backend imports have been loaded, and performs
        feature detection & testing common to all backends.
        r   r&   z6%r doesn't support argon2 v1.3, and should be upgradedz)%r lacks support for all known hash typesT)rz   rC   rF   r   rD   r   PasslibSecurityWarning	ALL_TYPESr3   r,   PasslibRuntimeWarningTYPE_ID)	mixin_clsrQ   dryrunrz   r,   r$   r$   r%   _finalize_backend_mixinM  s   
z%_Argon2Common._finalize_backend_mixinc                 C   s   |   }|du r|dur| |}|dur*||j|j |dkr*|jdur*tdt|}|dvr:d|||f }nt|}t	j
| |d)z}
        internal helper invoked when backend has hash/verification error;
        used to adapt to passlib message.
        Nargon2_cffiz8argon2_cffi backend doesn't support the 'data' parameter)zDecoding failedz%s reported: %s: hash=%r)reason)r1   ri   rJ   r    r!   r\   rf   rs   reprr   rd   )r4   errrW   r8   r{   textr   r$   r$   r%   _adapt_backend_errorg  s   
z"_Argon2Common._adapt_backend_error)NNNNNNNN)NFNNN)F)NN)>r   r   r   r   rQ   setting_kwds_default_settingsr#   rH   rD   GenericHandler_always_parse_settings_unparsed_settingsr"   default_salt_sizemin_salt_sizer   max_salt_sizer   default_rounds
min_rounds
max_roundsrounds_costmax_parallelism_default_versionrz   r   rR   rL   pure_use_threadsr3   r   r5   r   r,   r!   rZ   r    propertyr9   r\   classmethodr@   rJ   recompilerU   rX   Xrc   ri   rm   ro   rA   rq   rI   r~   r   _no_backend_suggestionr   r   __classcell__r$   r$   rO   r%   r'   s   s    

	;



2




r'   c                       sR   e Zd ZdZedd Zedd Zejddded	d
 Z	 fddZ
  ZS )
_NoBackendz
    mixin used before any backend has been loaded.
    contains stubs that force loading of one of the available backends.
    c                 C   s   |    | |S rS   )_stub_requires_backendrW   )r4   secretr$   r$   r%   rW     s   
z_NoBackend.hashc                 C      |    | ||S rS   )r   verify)r4   r   rW   r$   r$   r%   r     s   z_NoBackend.verifyz1.7z2.0)
deprecatedremovedc                 C   r   rS   )r   genhash)r4   r   configr$   r$   r%   r     s   z_NoBackend.genhashc                    s   |    tt| |S rS   )r   r?   r   _calc_checksumr8   r   rO   r$   r%   r     s   z_NoBackend._calc_checksum)r   r   r   r   r   rW   r   rD   deprecated_methodr   r   r   r$   r$   rO   r%   r     s    

r   c                   @   sZ   e Zd ZdZedd Zedd Zedd eD Z	edd	 Z
ed
d Zdd ZdS )_CffiBackendz
    argon2_cffi backend
    c              	   C   s   | t u sJ td u rtrttdS tjj}tdtj	| tj
}i }tD ]"}zt|| ||< W q& tyH   |ttfvsFJ d| Y q&w || _| | _| _| ||S )NFzOdetected 'argon2_cffi' backend, version %r, with support for 0x%x argon2 hashesunexpected missing type: %r)r   _argon2_cffi_argon2_cffi_errorr   PasslibSecurityErrorr   ARGON2_VERSIONlogdebug__version__r   r   getattrupperAttributeErrorTYPE_Ir6   r3   rZ   rz   r   )r   rQ   r   rz   TypeEnumtype_mapr,   r$   r$   r%   _load_backend_mixin  s(   
z _CffiBackend._load_backend_mixinc              
   C   st   t | t|d}zttjj| | j| j	| j
| jt|  | j|dW S  tjjy9 } z| |d }~ww )NrY   )r,   r    r   r!   r(   r#   r   )rD   validate_secretr   r   r   r   hash_secretr~   r,   r    r   r!   _generate_saltrH   
exceptionsHashingErrorr   )r4   r   r   r$   r$   r%   rW     s    




	
z_CffiBackend.hashc                 c   s$    | ]}t d |d|fV  qdS )s
   $argon2%s$r^   N)r	   r`   ).0r,   r$   r$   r%   	<genexpr>  s    z_CffiBackend.<genexpr>c              
   C   s   t | t|d}t|d}| j|d d|dd  t}| |}ztj	
|||}|du s4J W dS  tjjyB   Y dS  tjjyV } z| j||dd }~ww )NrY   r^   r.      $TFrW   )rD   r   r   _byte_ident_maprB   findr   r~   r   r   verify_secretr   VerifyMismatchErrorVerificationErrorr   )r4   r   rW   r,   	type_coderesultr   r$   r$   r%   r     s   


"
z_CffiBackend.verifyc                 C   s   t | t|d}| |}zttjj| |j	|j
|j|jt|j|j||jd}W n tjjyB } z| j||dd }~ww |jdkrN|dd}|S )NrY   )r,   r    r   r!   r(   r#   r   rZ   r   r   z$v=16$$)rD   r   r   ri   r   r   r   r   r~   r,   r    r*   r!   r(   rH   rZ   r   r   r   replace)r4   r   r   r8   r   r   r$   r$   r%   r     s*   





z_CffiBackend.genhashc                 C   s   t d)Nz-shouldn't be called under argon2_cffi backend)AssertionErrorr   r$   r$   r%   r   *  s   z_CffiBackend._calc_checksumN)r   r   r   r   r   r   rW   dictr   r   r   r   r   r$   r$   r$   r%   r     s    



r   c                   @   s$   e Zd ZdZedd Zdd ZdS )_PureBackendz
    argon2pure backend
    c              	   C   s   | t u sJ zdd laW n
 ty   Y dS w zddlm} W n ty.   td Y dS w td| |s=tdt	j
 i }tD ]$}zttd|  ||< W qA tye   |ttfvscJ d| Y qAw || _| | _| _| ||S )	Nr   F)ARGON2_DEFAULT_VERSIONz\detected 'argon2pure' backend, but package is too old (passlib requires argon2pure >= 1.2.3)zBdetected 'argon2pure' backend, with support for 0x%x argon2 hasheszUsing argon2pure backend, which is 100x+ slower than is required for adequate security. Installing argon2_cffi (via 'pip install argon2_cffi') is strongly recommendedARGON2r   )r   
argon2pure_argon2pureImportErrorr   r   warningr   r   r   r   r   r   r   r   r   r6   r3   rZ   rz   r   )r   rQ   r   rz   r   r,   r$   r$   r%   r   <  s:   
z _PureBackend._load_backend_mixinc              
   C   s   t | t|d}t|| j| j| j| j| j| 	| j
| jd}| jdkr*| j|d< | jr1d|d< | jr9| j|d< z	tjd	i |W S  tjyV } z| j|| dd }~ww )
NrY   )passwordr(   r   r    r!   
tag_lengthr   rZ   r   threadsTuse_threadsassociated_datar7   r$   )rD   r   r   r   r(   r*   r    r!   rH   r~   r,   rZ   rL   r   r\   r   r   Argon2Errorr   )r8   r   rM   r   r$   r$   r%   r   n  s0   






z_PureBackend._calc_checksumN)r   r   r   r   r   r   r   r$   r$   r$   r%   r   4  s
    
1r   c                   @   s$   e Zd ZdZdZdZeeedZ	dS )r   a	  
    This class implements the Argon2 password hash [#argon2-home]_, and follows the :ref:`password-hash-api`.

    Argon2 supports a variable-length salt, and variable time & memory cost,
    and a number of other configurable parameters.

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

    :type type: str
    :param type:
        Specify the type of argon2 hash to generate.
        Can be one of "ID", "I", "D".

        This defaults to "ID" if supported by the backend, otherwise "I".

    :type salt: str
    :param salt:
        Optional salt string.
        If specified, the length must be between 0-1024 bytes.
        If not specified, one will be auto-generated (this is recommended).

    :type salt_size: int
    :param salt_size:
        Optional number of bytes to use when autogenerating new salts.

    :type rounds: int
    :param rounds:
        Optional number of rounds to use.
        This corresponds linearly to the amount of time hashing will take.

    :type time_cost: int
    :param time_cost:
        An alias for **rounds**, for compatibility with underlying argon2 library.

    :param int memory_cost:
        Defines the memory usage in kibibytes.
        This corresponds linearly to the amount of memory hashing will take.

    :param int parallelism:
        Defines the parallelization factor.
        *NOTE: this will affect the resulting hash value.*

    :param int digest_size:
        Length of the digest in bytes.

    :param int max_threads:
        Maximum number of threads that will be used.
        -1 means unlimited; otherwise hashing will use ``min(parallelism, max_threads)`` threads.

        .. note::

            This option is currently only honored by the argon2pure backend.

    :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.

    .. versionchanged:: 1.7.2

        Added the "type" keyword, and support for type "D" and "ID" hashes.
        (Prior versions could verify type "D" hashes, but not generate them).

    .. todo::

        * Support configurable threading limits.
    )r   r   T)Nr   r   N)
r   r   r   r   backends_backend_mixin_targetr   r   r   _backend_mixin_mapr$   r$   r$   r%   r     s    P
)>r   
__future__r   r   logging	getLoggerr   r   r   typeswarningsr   r   r   passlibr   passlib.crypto.digestr   passlib.utilsr   r   r	   passlib.utils.binaryr
   r   passlib.utils.compatr   r   r   r   r   passlib.utils.handlersutilshandlersrD   __all__r   r6   r   r   setrt   r   r   r   hasattrr   r   r   r   r   r   SubclassBackendMixinParallelismMixin	HasRounds
HasRawSaltHasRawChecksumr   r'   r   r   r   r$   r$   r$   r%   <module>   sj    

	



    *|Z