§
    HŠtjX  ã                   óä   — d Z ddlZ ej        e¦  «        ZddlmZmZmZm	Z	 ddl
mZmZ ddlmZmZmZmZ ddlmZmZ ddlmc mZ dgZ G d„ dej        ej        ej        ej        ¦  «        ZdS )	z:passlib.handlers.scram - hash for SCRAM credential storageé    N)ÚconsteqÚsaslprepÚto_native_strÚ
splitcomma)Úab64_decodeÚab64_encode)Úbascii_to_strÚ	iteritemsÚuÚnative_string_types)Úpbkdf2_hmacÚnorm_hash_nameÚscramc                   ó2  ‡ — e Zd ZdZd ZdZ ed¦  «        ZdZdZ	dZ
dZdZd	Zg d
¢Zg d¢ZdZed„ ¦   «         Zedd„¦   «         Zed„ ¦   «         Zed„ ¦   «         Zd„ Zedˆ fd„	¦   «         Zdˆ fd„	Zdd„Zed„ ¦   «         Zˆ fd„Zdd„Zedd„¦   «         Zˆ xZS )r   aZ  This class provides a format for storing SCRAM passwords, 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:

    :type salt: bytes
    :param salt:
        Optional salt bytes.
        If specified, the length must be between 0-1024 bytes.
        If not specified, a 12 byte salt will be autogenerated
        (this is recommended).

    :type salt_size: int
    :param salt_size:
        Optional number of bytes to use when autogenerating new salts.
        Defaults to 12 bytes, but can be any value between 0 and 1024.

    :type rounds: int
    :param rounds:
        Optional number of rounds to use.
        Defaults to 100000, but must be within ``range(1,1<<32)``.

    :type algs: list of strings
    :param algs:
        Specify list of digest algorithms to use.

        By default each scram hash will contain digests for SHA-1,
        SHA-256, and SHA-512. This can be overridden by specify either be a
        list such as ``["sha-1", "sha-256"]``, or a comma-separated string
        such as ``"sha-1, sha-256"``. Names are case insensitive, and may
        use :mod:`!hashlib` or `IANA <http://www.iana.org/assignments/hash-function-text-names>`_
        hash names.

    :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

    In addition to the standard :ref:`password-hash-api` methods,
    this class also provides the following methods for manipulating Passlib
    scram hashes in ways useful for pluging into a SCRAM protocol stack:

    .. automethod:: extract_digest_info
    .. automethod:: extract_digest_algs
    .. automethod:: derive_digest
    )ÚsaltÚ	salt_sizeÚroundsÚalgsú$scram$é   i   i † é   l   ÿÿ Úlinear)úsha-1úsha-256úsha-512)r   r   zsha-224zsha-384r   Nc                 ó¦   — t          |d¦  «        }|                      |¦  «        }|j        }|st          d¦  «        ‚|j        |j        ||         fS )aè  return (salt, rounds, digest) for specific hash algorithm.

        :type hash: str
        :arg hash:
            :class:`!scram` hash stored for desired user

        :type alg: str
        :arg alg:
            Name of digest algorithm (e.g. ``"sha-1"``) requested by client.

            This value is run through :func:`~passlib.crypto.digest.norm_hash_name`,
            so it is case-insensitive, and can be the raw SCRAM
            mechanism name (e.g. ``"SCRAM-SHA-1"``), the IANA name,
            or the hashlib name.

        :raises KeyError:
            If the hash does not contain an entry for the requested digest
            algorithm.

        :returns:
            A tuple containing ``(salt, rounds, digest)``,
            where *digest* matches the raw bytes returned by
            SCRAM's :func:`Hi` function for the stored password,
            the provided *salt*, and the iteration count (*rounds*).
            *salt* and *digest* are both raw (unencoded) bytes.
        Úianazscram hash contains no digests)r   Úfrom_stringÚchecksumÚ
ValueErrorr   r   )ÚclsÚhashÚalgÚselfÚchkmaps        úT/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/passlib/handlers/scram.pyÚextract_digest_infozscram.extract_digest_info|   sW   € õ> ˜S &Ñ)Ô)ˆØ�Š˜tÑ$Ô$ˆØ”ˆØð 	?ÝÐ=Ñ>Ô>Ð>ØŒy˜$œ+ v¨c¤{Ð2Ð2ó    r   c                 ód   ‡— |                       |¦  «        j        }‰dk    r|S ˆfd„|D ¦   «         S )aê  Return names of all algorithms stored in a given hash.

        :type hash: str
        :arg hash:
            The :class:`!scram` hash to parse

        :type format: str
        :param format:
            This changes the naming convention used by the
            returned algorithm names. By default the names
            are IANA-compatible; possible values are ``"iana"`` or ``"hashlib"``.

        :returns:
            Returns a list of digest algorithms; e.g. ``["sha-1"]``
        r   c                 ó0   •— g | ]}t          |‰¦  «        ‘ŒS © ©r   )Ú.0r#   Úformats     €r&   ú
<listcomp>z-scram.extract_digest_algs.<locals>.<listcomp>º   s#   ø€ Ð@Ð@Ð@°C•N 3¨Ñ/Ô/Ð@Ð@Ð@r(   )r   r   )r!   r"   r.   r   s     ` r&   Úextract_digest_algszscram.extract_digest_algs¢   sC   ø€ ð( �Š˜tÑ$Ô$Ô)ˆØ�VÒÐØˆKà@Ð@Ð@Ð@¸4Ð@Ñ@Ô@Ð@r(   c                 ó”   — t          |t          ¦  «        r|                     d¦  «        }t          |t	          |¦  «        ||¦  «        S )a;  helper to create SaltedPassword digest for SCRAM.

        This performs the step in the SCRAM protocol described as::

            SaltedPassword  := Hi(Normalize(password), salt, i)

        :type password: unicode or utf-8 bytes
        :arg password: password to run through digest

        :type salt: bytes
        :arg salt: raw salt data

        :type rounds: int
        :arg rounds: number of iterations.

        :type alg: str
        :arg alg: name of digest to use (e.g. ``"sha-1"``).

        :returns:
            raw bytes of ``SaltedPassword``
        zutf-8)Ú
isinstanceÚbytesÚdecoder   r   )r!   Úpasswordr   r   r#   s        r&   Úderive_digestzscram.derive_digest¼   sE   € õ. �h¥Ñ&Ô&ð 	0Ø—’ wÑ/Ô/ˆHõ ˜3¥¨Ñ 2Ô 2°D¸&ÑAÔAÐAr(   c                 óÚ  — t          |dd¦  «        }|                     d¦  «        st          j                             | ¦  «        ‚|dd …                              d¦  «        }t          |¦  «        dk    rt          j                             | ¦  «        ‚|\  }}}t          |¦  «        }|t          |¦  «        k    rt          j                             | ¦  «        ‚	 t          |                     d¦  «        ¦  «        }n-# t          $ r  t          j                             | ¦  «        ‚w xY w|st          j                             | ¦  «        ‚d|v rˆd }i }	|                     d¦  «        D ]m}
|
                     d¦  «        \  }}	 t          |                     d¦  «        ¦  «        |	|<   ŒA# t          $ r  t          j                             | ¦  «        ‚w xY wn|}d }	 | |||	|¬	¦  «        S )
NÚasciir"   r   é   ú$é   ú=ú,)r   r   r   r   )r   Ú
startswithÚuhÚexcÚInvalidHashErrorÚsplitÚlenÚMalformedHashErrorÚintÚstrr   ÚencodeÚ	TypeError)r!   r"   ÚpartsÚ
rounds_strÚsalt_strÚchk_strr   r   r   r%   Úpairr#   Údigests                r&   r   zscram.from_stringÝ   sú  € å˜T 7¨FÑ3Ô3ˆØ�Š˜yÑ)Ô)ð 	/Ý”&×)Ò)¨#Ñ.Ô.Ð.Ø�Q�R�R”—’˜sÑ#Ô#ˆÝˆu‰:Œ:˜Š?ˆ?Ý”&×+Ò+¨CÑ0Ô0Ð0Ø(-Ñ%ˆ
�H˜gõ �Z‘”ˆØ�˜V™œÒ$Ð$Ý”&×+Ò+¨CÑ0Ô0Ð0ð	1Ý˜xŸš¨wÑ7Ô7Ñ8Ô8ˆDˆDøÝð 	1ð 	1ð 	1Ý”&×+Ò+¨CÑ0Ô0Ð0ð	1øøøð ð 	å”&×+Ò+¨CÑ0Ô0Ð0Ø�Gˆ^ˆ^àˆDØˆFØŸš cÑ*Ô*ð 9ð 9�Ø"Ÿjšj¨™oœo‘��Vð9Ý"-¨f¯mªm¸GÑ.DÔ.DÑ"EÔ"E�F˜3‘K�KøÝ ð 9ð 9ð 9Ýœ&×3Ò3°CÑ8Ô8Ð8ð9øøøð	9ð ˆDØˆFð ˆsØØØØð	
ñ 
ô 
ð 	
s   Ã"D  Ä *D*Æ%F,Æ,*Gc                 óº   ‡— t          t          | j        ¦  «        ¦  «        }| j        Šd                     ˆfd„| j        D ¦   «         ¦  «        }d| j        ||fz  S )Nr=   c           	   3   óf   •K  — | ]+}|›d t          t          ‰|         ¦  «        ¦  «        ›�V — Œ,dS )r<   N)r	   r   )r-   r#   r%   s     €r&   ú	<genexpr>z"scram.to_string.<locals>.<genexpr>  sW   øè è € ð 
ð 
àð �s�s�M­+°f¸S´kÑ*BÔ*BÑCÔCÐCÐDð
ð 
ð 
ð 
ð 
ð 
r(   z$scram$%d$%s$%s)r	   r   r   r   Újoinr   r   )r$   r   rL   r%   s      @r&   Ú	to_stringzscram.to_string  sr   ø€ Ý�[¨¬Ñ3Ô3Ñ4Ô4ˆØ”ˆØ—(’(ð 
ð 
ð 
ð 
à”yð
ñ 
ô 
ñ 
ô 
ˆð ! D¤K°°wÐ#?Ñ?Ð?r(   c                 ó�   •— |�|�J ‚|} t          t          | ¦  «        j        di |¤Ž}|�|                      |¦  «        |_        |S )Nr+   )Úsuperr   ÚusingÚ
_norm_algsÚdefault_algs)r!   rX   r   ÚkwdsÚsubclsÚ	__class__s        €r&   rV   zscram.using  sa   ø€ ð ÐØÐ'Ð'Ð'ØˆLð )••u˜cÑ"Ô"Ô(Ð0Ð0¨4Ð0Ð0ˆð Ð#Ø"%§.¢.°Ñ">Ô">ˆFÔØˆr(   c                 ó¬  •—  t          t          | ¦  «        j        di |¤Ž | j        }|�'|�t	          d¦  «        ‚|                      |¦  «        }n{|�(|                      |                     ¦   «         ¦  «        }nQ| j        r;t          | j	        ¦  «        }|                      |¦  «        |k    sJ d|›�¦   «         ‚nt          d¦  «        ‚|| _        d S )Nz+checksum & algs kwds are mutually exclusivezinvalid default algs: zno algs list specifiedr+   )rU   r   Ú__init__r   ÚRuntimeErrorrW   ÚkeysÚuse_defaultsÚlistrX   rH   r   )r$   r   rY   Ú
digest_mapr[   s       €r&   r]   zscram.__init__+  sç   ø€ Ø#��e�TÑÔÔ#Ð+Ð+ dÐ+Ð+Ð+ð ”]ˆ
ØÐØÐ%Ý"Ð#PÑQÔQÐQØ—?’? 4Ñ(Ô(ˆDˆDØÐ#à—?’? :§?¢?Ñ#4Ô#4Ñ5Ô5ˆDˆDØÔð 	6Ý˜Ô)Ñ*Ô*ˆDØ—?’? 4Ñ(Ô(¨DÒ0Ð0Ð0Ð0ÐPTÐPTÐ2VÑ0Ô0Ð0Ð0åÐ4Ñ5Ô5Ð5ØˆŒ	ˆ	ˆ	r(   Fc                 óÄ  — t          |t          ¦  «        s!t          j                             |dd¦  «        ‚t          |¦  «        D ]†\  }}|t          |d¦  «        k    rt          d|›�¦  «        ‚t          |¦  «        dk    rt          d|›�¦  «        ‚t          |t          ¦  «        s!t          j                             |dd¦  «        ‚Œ‡d	|vrt          d
¦  «        ‚|S )NÚdictr   r   z(malformed algorithm name in scram hash: é	   z.SCRAM limits algorithm names to 9 characters: z	raw bytesÚdigestsr   ú-sha-1 must be in algorithm list of scram hash)
r2   rd   r?   r@   ÚExpectedTypeErrorr
   r   r    rC   r3   )r$   r   Úrelaxedr#   rN   s        r&   Ú_norm_checksumzscram._norm_checksum>  s   € Ý˜(¥DÑ)Ô)ð 	IÝ”&×*Ò*¨8°V¸ZÑHÔHÐHÝ$ XÑ.Ô.ð 	Oð 	O‰KˆC�Ø•n S¨&Ñ1Ô1Ò1Ð1Ý �jØ"% #ð"(ñ )ô )ð )å�3‰xŒx˜!Š|ˆ|Ý �jØ7:°sð"=ñ >ô >ð >å˜f¥eÑ,Ô,ð OÝ”f×.Ò.¨v°{ÀIÑNÔNÐNðOð ˜(Ð"Ð"åÐLÑMÔMÐMØˆr(   c                 óö   — t          |t          ¦  «        rt          |¦  «        }t          d„ |D ¦   «         ¦  «        }t	          d„ |D ¦   «         ¦  «        rt          d¦  «        ‚d|vrt          d¦  «        ‚|S )znormalize algs parameterc              3   ó6   K  — | ]}t          |d ¦  «        V — ŒdS )r   Nr,   ©r-   r#   s     r&   rQ   z#scram._norm_algs.<locals>.<genexpr>U  s,   è è € ÐBÐB°c•n S¨&Ñ1Ô1ÐBÐBÐBÐBÐBÐBr(   c              3   ó<   K  — | ]}t          |¦  «        d k    V — ŒdS )re   N)rC   rm   s     r&   rQ   z#scram._norm_algs.<locals>.<genexpr>V  s,   è è € Ð*Ð*˜c�s�3‰xŒx˜ŠzÐ*Ð*Ð*Ð*Ð*Ð*r(   z-SCRAM limits alg names to max of 9 charactersr   rg   )r2   r   r   ÚsortedÚanyr    )r!   r   s     r&   rW   zscram._norm_algsP  sŽ   € õ �dÕ/Ñ0Ô0ð 	$Ý˜dÑ#Ô#ˆDÝÐBÐB¸TÐBÑBÔBÑBÔBˆÝÐ*Ð* TÐ*Ñ*Ô*Ñ*Ô*ð 	NÝÐLÑMÔMÐMØ˜$ÐÐåÐLÑMÔMÐMØˆr(   c                 ó    •— t          | j        ¦  «                             | j        ¦  «        sdS  t	          t
          | ¦  «        j        di |¤ŽS )NTr+   )Úsetr   Ú
issupersetrX   rU   r   Ú_calc_needs_update)r$   rY   r[   s     €r&   rt   zscram._calc_needs_update`  sP   ø€ õ �4”9‰~Œ~×(Ò(¨Ô):Ñ;Ô;ð 	Ø�4ð 5�u•U˜DÑ!Ô!Ô4Ð<Ð<°tÐ<Ð<Ð<r(   c                 óš   ‡‡‡‡— | j         Š| j        Š| j        Š|r ‰‰‰‰|¦  «        S t          ˆˆˆˆfd„| j        D ¦   «         ¦  «        S )Nc              3   ó8   •K  — | ]}| ‰‰‰‰|¦  «        fV — Œd S ©Nr+   )r-   r#   r"   r   r   Úsecrets     €€€€r&   rQ   z'scram._calc_checksum.<locals>.<genexpr>v  sL   øè è € ð ð àð �d�d˜6 4¨°Ñ5Ô5Ð6ðð ð ð ð ð r(   )r   r   r6   rd   r   )r$   rx   r#   r"   r   r   s    ` @@@r&   Ú_calc_checksumzscram._calc_checksumm  s…   øøøø€ Ø”ˆØŒyˆØÔ!ˆØð 	à�4˜  f¨cÑ2Ô2Ð2õ ð ð ð ð ð ð ð àœ9ðñ ô ñ ô ð r(   c                 ó–  — t          j        |¦  «         |                      |¦  «        }|j        }|s t	          d| j        ›d| j        ›d�¦  «        ‚|r«dx}}t          |¦  «        D ]‚\  }}	|                     ||¦  «        }
t          |	¦  «        t          |
¦  «        k    r2t	          d|›dt          |	¦  «        ›dt          |
¦  «        ›�¦  «        ‚t          |
|	¦  «        rd}Œ€d}Œƒ|r|rt	          d	¦  «        ‚|S |j
        D ]4}||v r.|                     ||¦  «        }
t          |
||         ¦  «        c S Œ5t          d
¦  «        ‚)Nz	expected z hash, got z config string insteadFz
mis-sized z digest in scram hash: z != Tz4scram hash verified inconsistently, may be corruptedzsha-1 digest not found!)r?   Úvalidate_secretr   r   r    Únamer
   ry   rC   r   Ú_verify_algsÚAssertionError)r!   rx   r"   Úfullr$   r%   ÚcorrectÚfailedr#   rN   Úothers              r&   Úverifyzscram.verify{  s£  € å
Ô˜6Ñ"Ô"Ð"Ø�Š˜tÑ$Ô$ˆØ”ˆØð 	3Ý�*Ø!œh˜h˜h¨¬¨¨ð2ñ 3ô 3ð 3ð ð 	<Ø$Ð$ˆG�fÝ(¨Ñ0Ô0ð "ð "‘��VØ×+Ò+¨F°CÑ8Ô8�õ
 �v‘;”;¥# e¡*¤*Ò,Ð,Ý$˜*Ø(+¨¨­S°©[¬[¨[¨[½#¸e¹*¼*¸*ð&Fñ Gô Gð Gå˜5 &Ñ)Ô)ð "Ø"�G�Gà!�F�FØð ˜6ð Ý ð "4ñ 5ô 5ð 5ð �ð Ô(ð 7ð 7�Ø˜&�=�=Ø ×/Ò/°¸Ñ<Ô<�EÝ" 5¨&°¬+Ñ6Ô6Ð6Ð6Ð6ð !õ
 !Ð!:Ñ;Ô;Ð;r(   )r   )NNrw   )F)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r|   Úsetting_kwdsr   ÚidentÚdefault_salt_sizeÚmax_salt_sizeÚdefault_roundsÚ
min_roundsÚ
max_roundsÚrounds_costrX   r}   r   Úclassmethodr'   r0   r6   r   rS   rV   r]   rj   rW   rt   ry   rƒ   Ú__classcell__)r[   s   @r&   r   r      sÙ  ø€ € € € € ð4ð 4ðB €DØ:€LØˆAˆi‰LŒL€Eð ÐØ€Mð €NØ€JØ€JØ€Kð
 3Ð2Ð2€Lð IÐHÐH€Lð €Dð
 ð#3ð #3ñ „[ð#3ðJ ðAð Að Añ „[ðAð2 ðBð Bñ „[ðBð@ ð-
ð -
ñ „[ð-
ð^@ð @ð @ð ðð ð ð ð ñ „[ðð"ð ð ð ð ð ð&ð ð ð ð$ ð
ð 
ñ „[ð
ð=ð =ð =ð =ð =ðð ð ð ð ð(<ð (<ð (<ñ „[ð(<ð (<ð (<ð (<ð (<r(   )r‡   ÚloggingÚ	getLoggerr„   ÚlogÚpasslib.utilsr   r   r   r   Úpasslib.utils.binaryr   r   Úpasslib.utils.compatr	   r
   r   r   Úpasslib.crypto.digestr   r   Úpasslib.utils.handlersÚutilsÚhandlersr?   Ú__all__Ú	HasRoundsÚ
HasRawSaltÚHasRawChecksumÚGenericHandlerr   r+   r(   r&   ú<module>r¡      s  ðØ @Ð @ð
 €€€Ð'�gÔ'¨Ñ1Ô1�ð GÐ FÐ FÐ FÐ FÐ FÐ FÐ FÐ FÐ FÐ FÐ FØ 9Ð 9Ð 9Ð 9Ð 9Ð 9Ð 9Ð 9Ø QÐ QÐ QÐ QÐ QÐ QÐ QÐ QÐ QÐ QÐ QÐ QØ =Ð =Ð =Ð =Ð =Ð =Ð =Ð =Ø #Ð #Ð #Ð #Ð #Ð #Ð #Ð #Ð #ð ð€ðN<ð N<ð N<ð N<ð N<ˆBŒL˜"œ-¨Ô):¸BÔ<Mñ N<ô N<ð N<ð N<ð N<r(   