Ë
    àU.j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j4                  ej6                  ej8                  ej:                  «      Zy)	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                   ó  ‡ — 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                  |«      }|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        úXC:\xampp\htdocs\tradingbinance\backend\.venv\Lib\site-packages\passlib/handlers/scram.pyÚextract_digest_infozscram.extract_digest_info|   sO   € ô> ˜S &Ó)ˆØ�‰˜tÓ$ˆØ—‘ˆÙÜÐ=Ó>Ð>Ø�y‰y˜$Ÿ+™+ v¨c¡{Ð2Ð2ó    c                 ó„   — | j                  |«      j                  }|dk(  r|S |D �cg c]  }t        ||«      ‘Œ c}S c c}w )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   )r   r   r   )r!   r"   Úformatr   r#   s        r&   Úextract_digest_algszscram.extract_digest_algs¢   sD   € ð( �‰˜tÓ$×)Ñ)ˆØ�VÒØˆKá;?Ó@¹4°C”N 3¨Õ/¸4Ñ@Ð@ùÒ@s   §=c                 ór   — t        |t        «      r|j                  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¼   s4   € ô. �h¤Ô&Ø—‘ wÓ/ˆHô ˜3¤¨Ó 2°D¸&ÓAÐAr(   c                 ód  — t        |dd«      }|j                  d«      st        j                  j	                  | «      ‚|dd  j                  d«      }t        |«      dk7  rt        j                  j                  | «      ‚|\  }}}t        |«      }|t        |«      k7  rt        j                  j                  | «      ‚	 t        |j                  d«      «      }|st        j                  j                  | «      ‚d|v rMd }i }	|j                  d«      D ]4  }
|
j                  d«      \  }}	 t        |j                  d«      «      |	|<   Œ6 n|}d }	 | |||	|¬	«      S # t        $ r  t        j                  j                  | «      ‚w xY w# t        $ r  t        j                  j                  | «      ‚w xY w)
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ˆØ�‰˜yÔ)Ü—&‘&×)Ñ)¨#Ó.Ð.Ø�Q�R�—‘˜sÓ#ˆÜˆu‹:˜Š?Ü—&‘&×+Ñ+¨CÓ0Ð0Ø(-Ñ%ˆ
�H˜gô �Z“ˆØœ˜V›Ò$Ü—&‘&×+Ñ+¨CÓ0Ð0ð	1Ü˜xŸ™¨wÓ7Ó8ˆDñ
 ä—&‘&×+Ñ+¨CÓ0Ð0Ø�G‰^àˆDØˆFØŸ™ cÖ*�Ø"Ÿj™j¨›o‘��Vð9Ü"-¨f¯m©m¸GÓ.DÓ"E�F˜3’Kñ +ð ˆDØˆFñ ØØØØô	
ð 	
øô/ ò 	1Ü—&‘&×+Ñ+¨CÓ0Ð0ð	1ûô !ò 9ÜŸ&™&×3Ñ3°CÓ8Ð8ð9ús   Â>E Ä*FÅ)FÆ)F/c                 óÄ   ‡— t        t        | j                  «      «      }| j                  Šdj	                  ˆfd„| j
                  D «       «      }d| j                  ||fz  S )Nr8   c           	   3   óV   •K  — | ]   }|›d t        t        ‰|   «      «      ›�–— Œ" y­w)r7   N)r	   r   )Ú.0r#   r%   s     €r&   Ú	<genexpr>z"scram.to_string.<locals>.<genexpr>  s,   øè ø€ ð 
á �ò œM¬+°f¸S±kÓ*BÔCÔDÙ ùs   ƒ&)z$scram$%d$%s$%s)r	   r   r   r   Újoinr   r   )r$   r   rG   r%   s      @r&   Ú	to_stringzscram.to_string  sV   ø€ Üœ[¨¯©Ó3Ó4ˆØ—‘ˆØ—(‘(ó 
à—y’yó
ó 
ˆð ! D§K¡K°°wÐ#?Ñ?Ð?r(   c                 ón   •— |�|�J ‚|}t        t        | �
  di |¤Ž}|�| j                  |«      |_        |S )N© )Úsuperr   ÚusingÚ
_norm_algsÚdefault_algs)r!   rU   r   ÚkwdsÚsubclsÚ	__class__s        €r&   rS   zscram.using  sP   ø€ ð ÐØÐ'Ð'Ð'ØˆLô ”u˜cÑ(Ñ0¨4Ñ0ˆð Ð#Ø"%§.¡.°Ó">ˆFÔØˆr(   c                 óˆ  •— t        t        | �
  di |¤Ž | j                  }|�&|�t	        d«      ‚| j                  |«      }|| _        y |�'| j                  |j                  «       «      }|| _        y | j                  r3t        | j                  «      }| j                  |«      |k(  sJ d|›�«       ‚t        d«      ‚|| _        y )Nz+checksum & algs kwds are mutually exclusivezinvalid default algs: zno algs list specifiedrQ   )rR   r   Ú__init__r   ÚRuntimeErrorrT   ÚkeysÚuse_defaultsÚlistrU   rC   r   )r$   r   rV   Ú
digest_maprX   s       €r&   rZ   zscram.__init__+  sÃ   ø€ ÜŒe�TÑ#Ñ+ dÒ+ð —]‘]ˆ
ØÐØÐ%Ü"Ð#PÓQÐQØ—?‘? 4Ó(ˆDð ˆ�	ð Ð#à—?‘? :§?¡?Ó#4Ó5ˆDð ˆ�	ð ×ÒÜ˜×)Ñ)Ó*ˆDØ—?‘? 4Ó(¨DÒ0ÑVÑPTÐ2VÓVÐ0äÐ4Ó5Ð5Øˆ�	r(   c                 ó€  — t        |t        «      s!t        j                  j	                  |dd«      ‚t        |«      D ]o  \  }}|t        |d«      k7  rt        d|›�«      ‚t        |«      dkD  rt        d|›�«      ‚t        |t        «      rŒPt        j                  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)
r-   ra   r:   r;   ÚExpectedTypeErrorr
   r   r    r>   r.   )r$   r   Úrelaxedr#   rI   s        r&   Ú_norm_checksumzscram._norm_checksum>  sº   € Ü˜(¤DÔ)Ü—&‘&×*Ñ*¨8°V¸ZÓHÐHÜ$ XÖ.‰KˆC�Ø”n S¨&Ó1Ò1Ý Ù"%ð"(ó )ð )ä�3‹x˜!Š|Ý Ù7:ð"=ó >ð >ä˜f¤eÕ,Ü—f‘f×.Ñ.¨v°{ÀIÓNÐNð /ð ˜(Ñ"äÐLÓ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   ó4   K  — | ]  }t        |d «      –— Œ y­w)r   N)r   ©rL   r#   s     r&   rM   z#scram._norm_algs.<locals>.<genexpr>U  s   è ø€ ÐB¹T°c”n S¨&×1¹Tùs   ‚c              3   ó8   K  — | ]  }t        |«      d kD  –— Œ y­w)rb   N)r>   rj   s     r&   rM   z#scram._norm_algs.<locals>.<genexpr>V  s   è ø€ Ð*¡T˜cŒs�3‹x˜�z¡Tùs   ‚z-SCRAM limits alg names to max of 9 charactersr   rd   )r-   r   r   ÚsortedÚanyr    )r!   r   s     r&   rT   zscram._norm_algsP  s\   € ô �dÔ/Ô0Ü˜dÓ#ˆDÜÑB¹TÓBÓBˆÜÑ*¡TÓ*Ô*ÜÐLÓMÐMØ˜$ÑäÐLÓMÐMØˆr(   c                 óˆ   •— t        | j                  «      j                  | j                  «      syt	        t
        | �  di |¤ŽS )NTrQ   )Úsetr   Ú
issupersetrU   rR   r   Ú_calc_needs_update)r$   rV   rX   s     €r&   rq   zscram._calc_needs_update`  s;   ø€ ô �4—9‘9‹~×(Ñ(¨×):Ñ):Ô;Øô ”U˜DÑ4Ñ<°tÑ<Ð<r(   c                 ó®   ‡‡‡‡— | j                   Š| j                  Š| j                  Š|r ‰‰‰‰|«      S t        ˆˆˆˆfd„| j                  D «       «      S )Nc              3   ó8   •K  — | ]  }| ‰‰‰‰|«      f–— Œ y ­w©NrQ   )rL   r#   r"   r   r   Úsecrets     €€€€r&   rM   z'scram._calc_checksum.<locals>.<genexpr>v  s)   øè ø€ ð á$�Cð ‘d˜6 4¨°Ó5Ô6Ù$ùs   ƒ)r   r   r1   ra   r   )r$   ru   r#   r"   r   r   s    ` @@@r&   Ú_calc_checksumzscram._calc_checksumm  sT   û€ Ø—‘ˆØ�y‰yˆØ×!Ñ!ˆÙá˜  f¨cÓ2Ð2ô ö àŸ9š9óó ð r(   c                 óP  — t        j                  |«       | j                  |«      }|j                  }|s&t	        d| j
                  ›d| j
                  ›d�«      ‚|rˆdx}}t        |«      D ]e  \  }}	|j                  ||«      }
t        |	«      t        |
«      k7  r&t	        d|›dt        |	«      ›dt        |
«      ›�«      ‚t        |
|	«      rd}Œdd}Œg |r|rt	        d	«      ‚|S |j                  D ])  }||v sŒ|j                  ||«      }
t        |
||   «      c S  t        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
   rv   r>   r   Ú_verify_algsÚAssertionError)r!   ru   r"   Úfullr$   r%   ÚcorrectÚfailedr#   rI   Úothers              r&   Úverifyzscram.verify{  s1  € ä
×Ñ˜6Ô"Ø�‰˜tÓ$ˆØ—‘ˆÙÝØ!Ÿh›h¨¯«ð2ó 3ð 3ñ Ø$Ð$ˆG�fÜ(¨Ö0‘��VØ×+Ñ+¨F°CÓ8�ô
 �v“;¤# e£*Ò,Ý$Ú(+¬S°­[¼#¸e¼*ð&Fó Gð Gä˜5 &Ô)Ø"‘Gà!‘Fð  1ñ ™6Ü ð "4ó 5ð 5ð �ð ×(Ô(�Ø˜&’=Ø ×/Ñ/°¸Ó<�EÜ" 5¨&°©+Ó6Ò6ð )ô !Ð!:Ó;Ð;r(   )r   )NNrt   )F)Ú__name__Ú
__module__Ú__qualname__Ú__doc__ry   Úsetting_kwdsr   ÚidentÚdefault_salt_sizeÚmax_salt_sizeÚdefault_roundsÚ
min_roundsÚ
max_roundsÚrounds_costrU   rz   r   Úclassmethodr'   r+   r1   r   rO   rS   rZ   rg   rT   rq   rv   r€   Ú__classcell__)rX   s   @r&   r   r      s  ø„ ñ4ðB €DØ:€LÙˆi‹L€Eð ÐØ€Mð €NØ€JØ€JØ€Kò
 3€Lò I€Lð €Dð
 ñ#3ó ð#3ðJ òAó ðAð2 ñ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   rQ   r(   r&   Ú<module>rž      sn   ðÙ @ó
 Ð'�g×'Ñ'¨Ó1�÷ GÓ Fß 9ß QÓ Qß =ß #Ð #ð ð€ôN<ˆB�L‰L˜"Ÿ-™-¨×):Ñ):¸B×<MÑ<Mõ N<r(   