+
    THiN                         R t ^ RIHu Ht ^ RIHtHt ^ RIH	t	H
t
HtHt ^ RIHtHt ^ RIHt R.t ! R R]P&                  ]P(                  ]P*                  ]P,                  4      tR# )z!hash for SCRAM credential storageN)norm_hash_namepbkdf2_hmac)consteqsaslprep
splitcommato_native_str)ab64_decodeab64_encode)bascii_to_strscramc                     a a ] tR t^t oRtR tRtRt^tRt	Rt
^tRtRt. ROt. ROtRt]R 4       t]RR l4       t]R	 4       t]R
 4       tR t]RV 3R ll4       tRV 3R lltRR lt]R 4       tV 3R ltRR lt]RR l4       tRtVtV ;t # )r   a  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
$scram$i   i linearNc                    \        VR4      pV P                  V4      pVP                  pV'       g   \        R4      hVP                  VP
                  WB,          3# )aH  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
ValueErrorsaltrounds)clshashalgselfchkmaps   &&&  8/usr/lib/python3/dist-packages/passlib/handlers/scram.pyextract_digest_infoscram.extract_digest_infoj   sM    > S&)t$=>>yy$++v{22    c                    V P                  V4      P                  pVR8X  d   V# V Uu. uF  p\        WB4      NK  	  up# u upi )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   algsr   )r   r   formatr    r   s   &&&  r   extract_digest_algsscram.extract_digest_algs   sB    ( t$))VK7;<ts+t<<<s   A c                |    \        V\        4      '       d   VP                  R4      p\        V\	        V4      W#4      # )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: str 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_digestscram.derive_digest   s5    . h&&w/H 3 2DAAr   c                   \        VR R4      pVP                  R4      '       g    \        P                  P	                  V 4      hVR,          P                  R4      p\        V4      ^8w  d    \        P                  P                  V 4      hVw  r4p\        V4      pV\        V4      8w  d    \        P                  P                  V 4      h \        VP                  R 4      4      pT'       g    \        P                  P                  T 4      hRT9   dN   Rp/ p	TP                  R4       F3  p
T
P                  R4      w  r \        TP                  R 4      4      Y&   K5  	  MTpRp	T ! TTT	TR7      #   \         d!    \        P                  P                  T 4      hi ; i  \         d!    \        P                  P                  T 4      hi ; i)	asciir   r   :   NN$=N,)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   scram.from_string   s   T7F3y))&&))#..Rs#u:?&&++C00(-%
g ZV$&&++C00	1xw78D
 &&++C00'>DFc*"jjo9"-fmmG.D"EFK + DF 	
 	
/  	1&&++C00	1 ! 9&&33C889s   E0 ?F0+F+G	c                   a \        \        V P                  4      4      pV P                  oR P	                  V3R lV P
                   4       4      pRV P                  W3,          # )r0   c           	   3   b   <"   T F$  q R \        \        SV,          4      4       2x  K&  	  R# 5i)r/   N)r
   r	   ).0r   r   s   & r   	<genexpr>"scram.to_string.<locals>.<genexpr>   s,      
JS3e1];vc{#;<=>)s   ,/z$scram$%d$%s$%s)r
   r	   r   r   joinr    r   )r   r   r?   r   s   &  @r   	to_stringscram.to_string   sT    [34(( 
JN))
 
 !DKK#???r   c                t   < Ve	   Ve   Q hTp\         SV `  ! R/ VB pVe   V P                  V4      Vn        V# )N )superusing
_norm_algsdefault_algs)r   rP   r    kwdssubcls	__class__s   &&&, r   rN   scram.using   sM     '''L && #"%..">Fr   c                  < \         SV `  ! R/ VB  V P                  pVe"   Ve   \        R4      hV P	                  V4      pMxVe!   V P	                  VP                  4       4      pMTV P                  '       d8   \        V P                  4      pV P	                  V4      V8X  g   Q RV: 24       hM\        R4      hWn
        R # )Nz+checksum & algs kwds are mutually exclusivezinvalid default algs: zno algs list specifiedrL   )rM   __init__r   RuntimeErrorrO   keysuse_defaultslistrP   r;   r    )r   r    rQ   
digest_maprS   s   &&, r   rV   scram.__init__  s     4  ]]
%"#PQQ??4(D#??:??#45D))*D??4(D0S4J4(2SS0455	r   c                   \        V\        4      '       g"   \        P                  P	                  VR R4      hVP                  4        F{  w  r4V\        VR4      8w  d   \        RV: 24      h\        V4      ^	8  d   \        RV: 24      h\        V\        4      '       d   K\  \        P                  P	                  VRR4      h	  RV9  d   \        R4      hV# )	dictr   r   z(malformed algorithm name in scram hash: z.SCRAM limits algorithm names to 9 characters: z	raw bytesdigestssha-1-sha-1 must be in algorithm list of scram hash)
r%   r^   r2   r3   ExpectedTypeErroritemsr   r   r6   r&   )r   r   relaxedr   rA   s   &&&  r   _norm_checksumscram._norm_checksum   s    (D))&&**8VZHH#>>+KCnS&11 #KC7!STT3x!| DSGL  fe,,ff..v{INN , ("LMMr   c                   \        V\        4      '       d   \        V4      p\        R V 4       4      p\        ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      '       d   \        R4      hRV9  d   \        R4      hV# )znormalize algs parameterc              3   :   "   T F  p\        VR 4      x  K  	  R# 5i)r   N)r   rE   r   s   & r   rF   #scram._norm_algs.<locals>.<genexpr>7  s     BTcnS&11Ts   c              3   >   "   T F  p\        V4      ^	8  x  K  	  R# 5i)	   N)r6   ri   s   & r   rF   rj   8  s     ,ts3x!|ts   TFz-SCRAM limits alg names to max of 9 charactersr`   ra   )r%   r9   r   sortedanyr   )r   r    s   &&r   rO   scram._norm_algs2  sq     dC  d#DBTBB3,t,333,t,,,LMM$LMMr   c                   < \        V P                  4      P                  V P                  4      '       g   R # \        SV `  ! R/ VB # )TrL   )setr    
issupersetrP   rM   _calc_needs_update)r   rQ   rS   s   &,r   rs   scram._calc_needs_update?  s<     499~(():):;; w)1D11r   c                   aaaa V P                   oV P                  oV P                  oV'       d   S! SSSV4      # \        VVVV3R  lV P                   4       4      # )c              3   <   <"   T F  qS! SSSV4      3x  K  	  R # 5iNrL   )rE   r   r   r   r   secrets   & r   rF   'scram._calc_checksum.<locals>.<genexpr>Q  s     Pis$vtVS9:is   )r   r   r)   r^   r    )r   rx   r   r   r   r   s   &f&@@@r   _calc_checksumscram._calc_checksumI  sI    yy!!fc22PdiiPPPr   c                   \         P                  ! V4       V P                  V4      pVP                  pV'       g'   \	        R V P
                   RV P
                   R24      hV'       d   R;rgVP                  4        Fn  w  rVP                  W4      p
\        V	4      \        V
4      8w  d)   \	        RV R\        V	4      : R\        V
4      : 24      h\        W4      '       d   RpKl  RpKp  	  V'       d   V'       d   \	        R4      hV# VP                   F.  pW9   g   K  VP                  W4      p
\        WV,          4      u # 	  \        R	4      h)
z	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!)r2   validate_secretr   r   r   namerc   rz   r6   r   _verify_algsAssertionError)r   rx   r   fullr   r   correctfailedr   rA   others   &&&&       r   verifyscram.verifyS  s6   
6"t$CHH:[
:PQ  $$G%||~++F8
 v;#e*,$$SE)@VtTWX]T^Sab  5))"G!F  . 6 !WXXN $$C}++F8uSk22 % 677r   )r    )r   	salt_sizer   r    l    )r`   sha-256sha-512)r   r   zsha-224zsha-384r`   )r   )NNrw   )F)!__name__
__module____qualname____firstlineno____doc__r~   setting_kwdsidentdefault_salt_sizemax_salt_sizedefault_rounds
min_rounds
max_roundsrounds_costrP   r   r    classmethodr   r"   r)   r   rI   rN   rV   re   rO   rs   rz   r   __static_attributes____classdictcell____classcell__)rS   __classdict__s   @@r   r   r      s    4| D:LE M NJJK
 3L IL D#3 #3J = =0 B B8 -
 -
^@  &$ 
 
2Q '8 '8 '8r   )r   passlib.utils.handlersutilshandlersr2   passlib.crypto.digestr   r   passlib.utilsr   r   r   r   passlib.utils.binaryr   r	   passlib.utils.compatr
   __all__	HasRounds
HasRawSaltHasRawChecksumGenericHandlerr   rL   r   r   <module>r      sQ    ' # # = F F 9 . 
m8BLL"--):):B<M<M m8r   