+
    iX                     
   R t ^ RIt]P                  ! ]4      t^ RIHtHtHt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u Ht R.t ! R R]P4                  ]P6                  ]P8                  ]P:                  4      tR# )z:passlib.handlers.scram - hash for SCRAM credential storageN)consteqsaslprepto_native_str
splitcomma)ab64_decodeab64_encode)bascii_to_str	iteritemsunative_string_types)pbkdf2_hmacnorm_hash_namescramc                   &  a a ] tR t^t oRtR tRt]! R4      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   &&&  T/var/www/html/photoedit/myenv/lib/python3.14/site-packages/passlib/handlers/scram.pyextract_digest_infoscram.extract_digest_info|   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K;?@4CN3/4@@@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: 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_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G^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,          # )r3   c           	   3   h   <"   T F'  pV: R \        \        SV,          4      4      : 2x  K)  	  R# 5i)r2   N)r   r   ).0r   r   s   & r   	<genexpr>"scram.to_string.<locals>.<genexpr>  s+      
  M+fSk*BCD s   /2z$scram$%d$%s$%s)r   r   r   r   joinr#   r   )r   r   rB   r   s   &  @r   	to_stringscram.to_string  sT    [34(( 
yy
 
 !DKK#???r!   c                |   < Ve	   Ve   Q hTp\         \        V `
  ! R/ VB pVe   V P                  V4      Vn        V# )N )superr   using
_norm_algsdefault_algs)r   rS   r#   kwdssubcls	__class__s   &&&, r   rQ   scram.using  sP     '''L uc(040 #"%..">Fr!   c                  < \         \        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 specifiedrO   )rP   r   __init__r   RuntimeErrorrR   keysuse_defaultslistrS   r>   r#   )r   r#   rT   
digest_maprV   s   &&, r   rY   scram.__init__+  s    eT#+d+ ]]
%"#PQQ??4(D#??:??#45D))*D??4(D0VPT2VV0455	r!   c                   \        V\        4      '       g"   \        P                  P	                  VR R4      h\        V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(   ra   r5   r6   ExpectedTypeErrorr	   r   r   r9   r)   )r   r   relaxedr   rD   s   &&&  r   _norm_checksumscram._norm_checksum>  s    (D))&&**8VZHH$X.KCnS&11 "%"( ) )3x!| 7:"= > >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   rH   r   s   & r   rI   #scram._norm_algs.<locals>.<genexpr>U  s     BTcnS&11Ts   c              3   >   "   T F  p\        V4      ^	8  x  K  	  R# 5i)	   N)r9   rk   s   & r   rI   rl   V  s     *Tcs3xzTs   TFz-SCRAM limits alg names to max of 9 charactersrc   rd   )r(   r   r   sortedanyr   )r   r#   s   &&r   rR   scram._norm_algsP  sr     d/00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 # \        \
        V `  ! R/ VB # )TrO   )setr#   
issupersetrS   rP   r   _calc_needs_update)r   rT   rV   s   &,r   ru   scram._calc_needs_update`  s>     499~(():):;; UD4<t<<r!   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  pVS! SSSV4      3x  K  	  R # 5iNrO   )rH   r   r   r   r   secrets   & r   rI   'scram._calc_checksum.<locals>.<genexpr>v  s(      $C d6456$s   )r   r   r,   ra   r#   )r   rz   r   r   r   r   s   &f&@@@r   _calc_checksumscram._calc_checksumm  sT    yy!!fc22  99  r!   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;rg\        V4       Fo  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Km  RpKq  	  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!)r5   validate_secretr   r   r   namer	   r|   r9   r   _verify_algsAssertionError)r   rz   r   fullr   r   correctfailedr   rD   others   &&&&       r   verifyscram.verify{  s&   
6"t$!hh2 3 3 $$G(0++F8
 v;#e*,$(+S[#e*&F G G5))"G!F  1 6  "4 5 5  ((= //<E"5+66 ) !!:;;r!   )r#   )r   	salt_sizer   r#   l    )rc   sha-256sha-512)r   r   zsha-224zsha-384rc   )r   )NNry   )F)"__name__
__module____qualname____firstlineno____doc__r   setting_kwdsr
   identdefault_salt_sizemax_salt_sizedefault_rounds
min_rounds
max_roundsrounds_costrS   r   r#   classmethodr   r%   r,   r   rL   rQ   rY   rg   rR   ru   r|   r   __static_attributes____classdictcell____classcell__)rV   __classdict__s   @@r   r   r      s    4B D:LiLE M NJJK
 3L IL D
 #3 #3J 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handlersr5   __all__	HasRounds
HasRawSaltHasRawChecksumGenericHandlerr   rO   r!   r   <module>r      sk    @
 g''1 G F 9 Q Q = # # N<BLL"--):):B<M<M N<r!   