
    g                        S r SSKJr  SSKJrJrJr  SSKJ	r	J
r
   SSKJr  SSKJr  SSKJr  SSKJr  SS	KrSS	KrSS	Kr\R0                  " \5      rSS	KrSS	KrSS	KrSS	KrSS	Kr\(       a   SS	K r OSS	K r SS	K"r"\ (       a  SS	K#r# SS	K$r$SS	K%r%SS	K&r&SSK'J(r(  SSK)J*r*J+r+J,r,J-r-J.r.J/r/J0r0J1r1J2r2J3r3J4r4J5r5J6r6  SSK7J8r8J9r9J:r:J;r;J<r<  SSK=J>r>J?r?  SSKJ@r@JArAJBrBJCrCJDrDJErEJFrFJGrGJHrHJIrIJJrJJKrKJLrLJMrMJNrNJOrOJPrP  / SQrQ\R" \R4                  " \F(       a  \R                  O\R                  S5      S-   5      rU/ SQrVSS/rWSSK=JXrX  SrY\G" S5      rZ\G" S5      r[\R" \R                  R                  S5      =(       d    S5      r^ " S S\_5      r`\F(       a8  \R                  R                  rc\d" \c\R                  R                  /5      rfS rgOS rg  SjS! jrhS" riS# rj\jrk SS$KlJmrj  SkS% jrnSlS& jro\ c  SlS' jroS( rp\F(       a  S) rqS* rrOSS+KJsrsJtrt  S, rqS- rr\@" \qS.5        \@" \rS/5        S0 ruS1 rvS2 rwS3rx\G" S45      rySmS5 jrzS6 r{S7r|\|R                  S85      r~S9 rS: rS;r\G" S<5      rS= rSnS> jrSoS? jr\F(       a  SoS@ jrOSoSA jr\@" \SB5        \8" SCSDSE9SpSF j5       r\d" SGGR                  5       5      r\d" SHGR                  5       5      r\d" SSI/5      rSqSJ jrSK r SSLKJr  SMrS4r\$(       a7  \P(       a0  SN\GR$                  s=::  a  SO::  a  O  O\$GR&                  " 5       rSMrOSSPKJr  \" 5       rS r\G" SQ5      r\F(       a  SMr \" SRSS5        ST rOSMrSU r \@" \SW5        SX r\%GR8                  r\rSY r \GR@                  " SZ5        SMrSmS[ jr\(       a  \GRH                  " 5       rO\GRL                  " \" 5       5      rS\ rS] rS^r\8" SDS_S`Sa9Sb\4Sc j5       rSdrSe rSfrSg rSh rSi rg	! \ a    SSKJr  SSKJr   GNf = f! \ a    S	r S
r! GNf = f! \ a    S	r$ GNf = f! \ a     GNMf = f! \ a    S r N   N= f! \ a    S	rS rS rS rS	rSV r GNf = f! \ a    S r Nf = f)rz4passlib.utils -- helpers for writing password hashes    )JYTHON)
b2a_base64
a2b_base64Error)	b64encode	b64decode)Sequence)Iterable)lookup)update_wrapperNznot present under Jython)warn)BASE64_CHARS
AB64_CHARSHASH64_CHARSBCRYPT_CHARSBase64EngineLazyBase64Engineh64h64bigbcrypt64ab64_encodeab64_decodeb64s_encodeb64s_decode)deprecated_functiondeprecated_methodmemoized_propertyclasspropertyhybrid_method)ExpectedStringErrorExpectedTypeError)add_doc
join_bytesjoin_byte_valuesjoin_byte_elemsirangeimapPY3ujoin_unicodeunicodebyte_elem_value
nextgetterunicode_or_strunicode_or_bytes_typesget_method_functionsuppress_causePYPY)r   sys_bitsunix_crypt_schemesrounds_cost_valuesconsteqsaslprep	xor_bytesrender_bytesis_same_codecis_ascii_safeto_bytes
to_unicodeto_native_str	has_crypt
test_crypt
safe_crypttickrnggetrandbytes
getrandstrgenerate_passwordis_crypt_handleris_crypt_contexthas_rounds_infohas_salt_info   g      ?)sha512_cryptsha256_crypt
sha1_cryptbcrypt	md5_crypt
bsdi_crypt	des_cryptlinearlog2)MissingBackendError      PASSLIB_MAX_PASSWORD_SIZEi   c                   B    \ rS rSrSrS rS rS rS rS r	S r
S	 rS
rg)SequenceMixin   zw
helper which lets result object act like a fixed-length sequence.
subclass just needs to provide :meth:`_as_tuple()`.
c                     [        S5      e)Nzimplement in subclass)NotImplementedErrorselfs    O/home/matz/Project1/venv/lib/python3.13/site-packages/passlib/utils/__init__.py	_as_tupleSequenceMixin._as_tuple   s    !"9::rV   c                 4    [        U R                  5       5      $ N)reprrb   r_   s    ra   __repr__SequenceMixin.__repr__       DNN$%%rV   c                 (    U R                  5       U   $ re   rb   )r`   idxs     ra   __getitem__SequenceMixin.__getitem__   s    ~~$$rV   c                 4    [        U R                  5       5      $ re   )iterrb   r_   s    ra   __iter__SequenceMixin.__iter__   ri   rV   c                 4    [        U R                  5       5      $ re   )lenrb   r_   s    ra   __len__SequenceMixin.__len__   s    4>>#$$rV   c                 (    U R                  5       U:H  $ re   rk   r`   others     ra   __eq__SequenceMixin.__eq__   s    ~~5((rV   c                 .    U R                  U5      (       + $ re   )rz   rx   s     ra   __ne__SequenceMixin.__ne__   s    ;;u%%%rV    N)__name__
__module____qualname____firstlineno____doc__rb   rg   rm   rq   ru   rz   r}   __static_attributes__r   rV   ra   r[   r[      s*    ;&%&%)&rV   r[   c                    [         R                  " [        U 5      5      R                  nU(       d  gUR	                  U5      nU(       a  UR
                  [        ;  a  gU[        U5      S      R
                  [        :H  $ )*test if function accepts specified keywordFT)	inspect	signaturer0   
parametersgetkind_VAR_ANY_SETlist_VAR_KEYWORD)funckeyparamsargs       ra   accepts_keywordr      sa    ""#6t#<=HHjjo388</d6l2&',,<<rV   c                     [         R                  " [        U 5      5      nXR                  ;   =(       d    UR                  SL$ )r   N)r   
getargspecr0   argskeywords)r   r   specs      ra   r   r      s3    !!"5d";<ii<4==#<<rV   Fc                   ^ [        U[        5      (       a  U/n[        U R                  5      nU(       aI  [        U[        5      (       a  U/nU H+  mU(       a  TU;   a  M  TU;   d  M  UR	                  T5        M-     U(       a  U H  m[        U4S jU 5       5      (       a  M  U(       aN  [        U5       H3  u  p[        TU	5      (       a    OU(       d  M!  [        X5      (       d  M3    Od   [        U5      nOVU(       aM  [        [        U5      5       H2  u  p[        X5      (       d  M  [        U5      U
-
  nXxS-
     U	:X  d   e  O   SnOSnUR                  UT5        M     U(       d  [        U5      U l        gg)a  
helper to update mixin classes installed in target class.

:param target:
    target class whose bases will be modified.

:param add:
    class / classes to install into target's base class list.

:param remove:
    class / classes to remove from target's base class list.

:param append:
    by default, prepends mixins to front of list.
    if True, appends to end of list instead.

:param after:
    optionally make sure all mixins are inserted after
    this class / classes.

:param before:
    optionally make sure all mixins are inserted before
    this class / classes.

:param dryrun:
    optionally perform all calculations / raise errors,
    but don't actually modify the class.
c              3   <   >#    U  H  n[        UT5      v   M     g 7fre   )
issubclass).0basemixins     ra   	<genexpr>'update_mixin_classes.<locals>.<genexpr>   s     =ut:dE**u      r   N)
isinstancetyper   	__bases__removeany	enumerater   rt   reversedinserttuple)targetaddr   appendbeforeafterdryrunbasesrl   r   end_idxr   s              @ra   update_mixin_classesr      sO   < #te!!"E fd##XFEu|~U#	  E=u=== !*5!1IC!%..v*T":": "2 e*C%.x%?MG!$..!%j72$U|t333 &@ C  LLe$? D  < rV   c              #     #    US:  a  [        S5      e[        U [        5      (       a'  [        U 5      nSnX2:  a  X1-   nXU v   UnX2:  a  M  gg[        U [        5      (       aJ  [        U 5      n [        R                  " XQ5      n [        U5      n[        R                  " U4U5      v   M>  [        S5      e! [         a     gf = f7f)z0
split iterable into chunks of <size> elements.
r   zsize must be positive integerr   zsource must be iterableN)
ValueErrorr   r	   rt   r
   rp   	itertoolsislicenextStopIterationchain	TypeError)sourcesizeendinitr	chunk_itrfirsts           ra   batchr     s      ax899&(##&kgA1+A g 
FH	%	%6l!((3IY //5(I66  122	 ! s0   A
C
9C
B: 'C
:
CC
CC
c                    [        U [        5      (       a#  [        U[        5      (       d  [        S5      eSnOG[        U [        5      (       a'  [        U[        5      (       d  [        S5      e[        nO[        S5      e[        U 5      [        U5      :H  nU(       a  U nSnU(       d  UnSnU(       a!  [        WU5       H  u  pgWXg-  -  nM     WS:H  $ [        WU5       H  u  pgW[        U5      [        U5      -  -  nM!     WS:H  $ )a  Check two strings/bytes for equality.

This function uses an approach designed to prevent
timing analysis, making it appropriate for cryptography.
a and b must both be of the same type: either str (ASCII only),
or any type that supports the buffer protocol (e.g. bytes).

Note: If a and b are of different lengths, or if an error occurs,
a timing attack could theoretically reveal information about the
types and lengths of a and b--but not their values.
z)inputs must be both unicode or both bytesFr   r   )r   r+   r   bytesr(   rt   zipord)leftrightis_py3_bytes	same_sizetmpresultlrs           ra   r6   r6   ;  s    * $  %))GHH	D%	 	 %''GHHCDD Tc%j(I  sE?CAaeOF #
 Q; sE?CAc!fs1vo%F #Q;rV   )compare_digestc                     U R                  5       n U R                  U5      (       a  U SS n U (       d  / $ U R                  U5       Vs/ s H  o"R                  5       PM     sn$ s  snf )zJsplit comma-separated string into list of elements,
stripping whitespace.
Nr   )stripendswithsplit)r   sepelems      ra   
splitcommar     sX     \\^Fs	&,ll3&79&7dZZ\&7999s   A$c                 \  ^^ [        U [        5      (       d  [        S[        U 5      < 35      e[        R
                  m[        R                  m[        UU4S jU  5       5      n[        R                  " SU5      nU(       d  [        $ [        R                  nU" US   5      (       a/  U" US   5      (       d  [        SU-   5      e[        R                  nOUn[        R                  n[        R                  n[        R                   n[        R"                  n[        R$                  n	[        R&                  n
[        R(                  n[        R*                  n[        R,                  nU GH:  nT" U5      (       a   S5       eT" U5      (       a   S5       eU" U5      (       a  [        S	U-   5      eU" U5      (       a  [        S
U-   5      eU" U5      (       a  [        SU-   5      eU" U5      (       a  [        SU-   5      eU	" U5      (       a  [        SU-   5      eU
" U5      (       a  [        SU-   5      eU" U5      (       a  [        SU-   5      eU" U5      (       a  [        SU-   5      eU" U5      (       a  [        SU-   5      eU" U5      (       d  GM/  [        SU-   5      e   U$ )a  Normalizes unicode strings using SASLPrep stringprep profile.

The SASLPrep profile is defined in :rfc:`4013`.
It provides a uniform scheme for normalizing unicode usernames
and passwords before performing byte-value sensitive operations
such as hashing. Among other things, it normalizes diacritic
representations, removes non-printing characters, and forbids
invalid characters such as ``\n``. Properly internationalized
applications should run user passwords through this function
before hashing.

:arg source:
    unicode string to normalize & validate

:param param:
    Optional noun identifying source parameter in error messages
    (Defaults to the string ``"value"``). This is mainly useful to make the caller's error
    messages make more sense contextually.

:raises ValueError:
    if any characters forbidden by the SASLPrep profile are encountered.

:raises TypeError:
    if input is not :class:`!unicode`

:returns:
    normalized unicode string

.. note::

    This function is not available under Jython,
    as the Jython stdlib is missing the :mod:`!stringprep` module
    (`Jython issue 1758320 <http://bugs.jython.org/issue1758320>`_).

.. versionadded:: 1.6
z"input must be unicode string, not c              3   l   >#    U  H)  nT" U5      (       a  M  T" U5      (       a  [         OUv   M+     g 7fre   )_USPACE)r   cin_table_b1in_table_c12s     ra   r   saslprep.<locals>.<genexpr>  s.      
A1~ 	*<??)s   44NFKCr   r   zmalformed bidi sequence in z$failed to strip B.1 in mapping stagez(failed to replace C.1.2 in mapping stagez$unassigned code points forbidden in z control characters forbidden in z$private use characters forbidden in z"non-char code points forbidden in zsurrogate codes forbidden in z!non-plaintext chars forbidden in z!non-canonical chars forbidden in z1display-modifying / deprecated chars forbidden inztagged characters forbidden in zforbidden bidi character in )r   r+   r   r   
stringprepr   r   r*   unicodedata	normalize_UEMPTYin_table_d1r   in_table_d2in_table_a1in_table_c21_c22in_table_c3in_table_c4in_table_c5in_table_c6in_table_c7in_table_c8in_table_c9)r   paramdatais_ral_charis_forbidden_bidi_charr   r   r   r   r   r   r   r   r   r   r   r   s                  @@ra   r7   r7     s   X fg&&f( ) 	) **L((K 

 
D   .D ((K4748$$:UBCC!+!7!7 "- ((K!22((K((K((K((K((K((K((Kq>>I#II!??N$NN" q>>CeKLLA?%GHHq>>CeKLLq>>AEIJJq>><uDEEq>>@5HIIq>> @5HIIq>> ,.34 5 5q>>>FGG "!$$;eCDD= @ KrV   c                 &    [        S[        -   5      e)zstub for saslprep()z>saslprep() support requires the 'stringprep' module, which is )r^   _stringprep_missing_reason)r   r   s     ra   r7   r7     s    ! #02L#M N 	NrV   c                     [        U [        5      (       a  U R                  S5      n U [        S U 5       5      -  nUR	                  S5      $ )at  Peform ``%`` formating using bytes in a uniform manner across Python 2/3.

This function is motivated by the fact that
:class:`bytes` instances do not support ``%`` or ``{}`` formatting under Python 3.
This function is an attempt to provide a replacement:
it converts everything to unicode (decoding bytes instances as ``latin-1``),
performs the required formatting, then encodes the result to ``latin-1``.

Calling ``render_bytes(source, *args)`` should function roughly the same as
``source % args`` under Python 2.

.. todo::
    python >= 3.5 added back limited support for bytes %,
    can revisit when 3.3/3.4 is dropped.
latin-1c              3   r   #    U  H-  n[        U[        5      (       a  UR                  S 5      OUv   M/     g7f)r   N)r   r   decode)r   r   s     ra   r   render_bytes.<locals>.<genexpr>,  s5      604 6@U5K5KCJJy1!$%04s   57)r   r   r   r   encode)r   r   r   s      ra   r9   r9     sL      &%  y)e 6046 6 6F==##rV   c                 .    [         R                  U S5      $ Nbig)int
from_bytesvalues    ra   bytes_to_intr  2  s    ~~eU++rV   c                 &    U R                  US5      $ r   )r<   r  counts     ra   int_to_bytesr
  4  s    ~~eU++rV   )hexlify	unhexlifyc                 ,    [        [        U 5      S5      $ )N   )r  r  r  s    ra   r  r  9  s    75>"%%rV   c                 *    [        SUS-  -  U -  5      $ )Nz%%0%dxr   )r  r  s     ra   r
  r
  ;  s    (eQh/5899rV   z/decode byte string as single big-endian integerz/encode integer as single big-endian byte stringc                 V    [        [        U 5      [        U5      -  [        U 5      5      $ )z;Perform bitwise-xor of two byte strings (must be same size))r
  r  rt   r   r   s     ra   r8   r8   A  s"    T*\%-@@#d)LLrV   c                 8    SUS-
  [        U 5      -  -   nX-  SU $ )z=
repeat or truncate <source> string, so it has length <size>
r   N)rt   r   r   mults      ra   repeat_stringr  E  s*     qS[((DM5D!!rV   c                 F    SUS-
  [        U 5      -  -   n[        X-  U5      $ )zF
variant of repeat_string() which truncates to nearest UTF8 boundary.
r   )rt   utf8_truncater  s      ra   utf8_repeat_stringr  M  s*     qS[((D--rV        c                     [        U 5      nX:  a-  Uc!  [        U [        5      (       a  [        O[        nXX-
  -  -   $ U SU $ )z>right-pad or truncate <source> string, so it has length <size>N)rt   r   r+   _UNULL_BNULL)r   r   padcurs       ra   right_pad_stringr   X  sC    
f+Cz;&vw77&VC48n$$et}rV   c                 P  ^ ^ [        T [        5      (       d  [        T [        S5      e[        T 5      nUS:  a  [	        SX-   5      nX:  a  T $ [        US-   U5      nX:  a"  [        T U   5      S-  S:w  a  OUS-  nX:  a  M"  X:X  d   eT SU mUU 4S jnU" 5       (       d   eT$ )	a  
helper to truncate UTF8 byte string to nearest character boundary ON OR AFTER <index>.
returned prefix will always have length of at least <index>, and will stop on the
first byte that's not a UTF8 continuation byte (128 - 191 inclusive).
since utf8 should never take more than 4 bytes to encode known unicode values,
we can stop after ``index+3`` is reached.

:param bytes source:
:param int index:
:rtype: bytes
r   r            r   Nc                     >  TR                  S5      n U R                  TR                  S5      5      (       d   eg! [         a     gf = f)Nutf-8T)r   UnicodeDecodeError
startswith)textr   r   s    ra   sanity_check#utf8_truncate.<locals>.sanity_check  sM    	==)D v}}W56666 " 		s   < 
A	A	)r   r   r!   rt   maxminr,   )r   indexr   r*  r   s   `   @ra   r  r  c  s    2 fe$$x88 f+CqyAu{#| eai
C +6%=)D0D8
 + || FU^F
 >>>MrV   s	    
 aA:#!asciic                 :    [         R                  U 5      [        :H  $ )zRTest if codec is compatible with 7-bit ascii (e.g. latin-1, utf-8; but not utf-16))_ASCII_TEST_UNICODEr   _ASCII_TEST_BYTES)codecs    ra   is_ascii_codecr4    s    %%e,0AAArV   c                     X:X  a  gU (       a  U(       d  g[        U 5      R                  [        U5      R                  :H  $ )z3Check if two codec names are aliases for same codecTF)_lookup_codecnamer  s     ra   r:   r:     s3    }U##}U';'@'@@@rV   r$     c                 p   ^ [        U [        5      (       a  [        O[        m[	        U4S jU  5       5      $ )z<Check if string (bytes or unicode) contains only 7-bit asciic              3   ,   >#    U  H	  oT:  v   M     g 7fre   r   )r   r   r   s     ra   r    is_ascii_safe.<locals>.<genexpr>  s     %f1ufs   )r   r   _B80_U80all)r   r   s    @ra   r;   r;     s'    65))tA%f%%%rV   c                    U(       d   e[        U [        5      (       a9  U(       a0  [        X15      (       d   U R                  U5      R	                  U5      $ U $ [        U [
        5      (       a  U R	                  U5      $ [        X5      e)a  Helper to normalize input to bytes.

:arg source:
    Source bytes/unicode to process.

:arg encoding:
    Target encoding (defaults to ``"utf-8"``).

:param param:
    Optional name of variable/noun to reference when raising errors

:param source_encoding:
    If this is specified, and the source is bytes,
    the source will be transcoded from *source_encoding* to *encoding*
    (via unicode).

:raises TypeError: if source is not unicode or bytes.

:returns:
    * unicode strings will be encoded using *encoding*, and returned.
    * if *source_encoding* is not specified, byte strings will be
      returned unchanged.
    * if *source_encoding* is specified, byte strings will be transcoded
      to *encoding*.
)r   r   r:   r   r   r+   r    )r   encodingr   source_encodings       ra   r<   r<     sk    4 O8&%  =#K#K==188BBM	FG	$	$}}X&&!&00rV   c                     U(       d   e[        U [        5      (       a  U $ [        U [        5      (       a  U R                  U5      $ [	        X5      e)a  Helper to normalize input to unicode.

:arg source:
    source bytes/unicode to process.

:arg encoding:
    encoding to use when decoding bytes instances.

:param param:
    optional name of variable/noun to reference when raising errors.

:raises TypeError: if source is not unicode or bytes.

:returns:
    * returns unicode strings unchanged.
    * returns bytes strings decoded using *encoding*
)r   r+   r   r   r    r   r@  r   s      ra   r=   r=     sD    $ O8&'""	FE	"	"}}X&&!&00rV   c                     [        U [        5      (       a  U R                  U5      $ [        U [        5      (       a  U $ [	        X5      ere   )r   r   r   r+   r    rC  s      ra   r>   r>     s;    fe$$==**((M%f44rV   c                     [        U [        5      (       a  U $ [        U [        5      (       a  U R                  U5      $ [	        X5      ere   )r   r   r+   r   r    rC  s      ra   r>   r>     s;    fe$$M((==**%f44rV   a>  Take in unicode or bytes, return native string.

    Python 2: encodes unicode using specified encoding, leaves bytes alone.
    Python 3: leaves unicode alone, decodes bytes using specified encoding.

    :raises TypeError: if source is not unicode or bytes.

    :arg source:
        source unicode or bytes string.

    :arg encoding:
        encoding to use when encoding unicode or decoding bytes.
        this defaults to ``"utf-8"``.

    :param param:
        optional name of variable/noun to reference when raising errors.

    :returns: :class:`str` instance
    z1.6z1.7)
deprecatedremovedc                     [        XSS9$ )z'deprecated, use to_native_str() insteadhash)r   )r>   )r   r@  s     ra   to_hash_strrJ  $  s     88rV   z true t yes y on 1 enable enabledz#false f no n off 0 disable disablednonec                 0   US;   d   e[        U [        5      (       aS  U R                  5       R                  5       nU[        ;   a  gU[
        ;   a  gU[        ;   a  U$ [        SU< SU < 35      e[        U [        5      (       a  U $ U c  U$ [        U 5      $ )zP
helper to convert value to boolean.
recognizes strings such as "true", "false"
)TFNTFzunrecognized z value: )	r   r/   lowerr   	_true_set
_false_set	_none_setr   bool)r  rK  r   cleans       ra   as_boolrS  -  s    
 &&&&%/00##%IJIKuEFF	E4	 	 	E{rV   c                     [         (       d  [        U [        5      (       d  g U R                  S5        g! [         a     gf = f)zs
UT helper --
test if value is safe to pass to crypt.crypt();
under PY3, can't pass non-UTF8 bytes to crypt.crypt.
Tr&  F)crypt_accepts_bytesr   r   r   r'  r  s    ra   is_safe_crypt_inputrV  G  s?     *UE":":W s   5 
AA)cryptT)   rK   r   )rX  r"  r"  )nullcontextz*:!   xxc                    [         (       ab  [        U [        5      (       a  U R                  S5      n [        U ;   a  [        S5      e[        U[        5      (       a  UR                  S5      nO[        U [        5      (       a0  U n U R                  S5      n U R                  S5      U:X  d   S5       e[        U ;   a  [        S5      e[        U[        5      (       a  UR                  S5      n [           [        X5      nS S S 5        [        W[        5      (       a  UR                  S5      nU(       a  US   [        ;   a  g U$ ! [         a     g f = f! , (       d  f       N[= f! [         a     g f = f)Nr&  null character in secretr/  z"utf-8 spec says this can't happen!r   )rU  r   r+   r   r  r   r   r   r'  _NULL_safe_crypt_lock_cryptOSError_invalid_prefixes)secretrI  origr   s       ra   rA   rA     sJ   "" fg..#]]73FV#$%?@@dG,,;;w/D
 fe,,!D$!'w!7
 "==1T9 E DE9F?$%?@@dE**;;w/D%#F1F & &%((w/VAY*;;M3 . $#$ &%  	sB   E /E' 5EE' 
EE
E$ E' $E' '
E43E4c                 l   [        U [        5      (       a  U R                  S5      n [        U ;   a  [	        S5      e[        U[        5      (       a  UR                  S5      n[
           [        X5      nS S S 5        W(       d  g UR                  S5      nUS   [        ;   a  g U$ ! , (       d  f       N7= f)Nr&  r]  r/  r   )	r   r+   r   r^  r   r_  r`  r   rb  )rc  rI  r   s      ra   rA   rA     s    &'**w/ !;<<$(({{7+!- "]]7+Fay--M "!s   (B%%
B3c                     g re   r   rc  rI  s     ra   rA   rA   ]  s    rV   a  Wrapper around stdlib's crypt.

    This is a wrapper around stdlib's :func:`!crypt.crypt`, which attempts
    to provide uniform behavior across Python 2 and 3.

    :arg secret:
        password, as bytes or unicode (unicode will be encoded as ``utf-8``).

    :arg hash:
        hash or config string, as ascii bytes or unicode.

    :returns:
        resulting hash as ascii unicode; or ``None`` if the password
        couldn't be hashed due to one of the issues:

        * :func:`crypt()` not available on platform.

        * Under Python 3, if *secret* is specified as bytes,
          it must be use ``utf-8`` or it can't be passed
          to :func:`crypt()`.

        * Some OSes will return ``None`` if they don't recognize
          the algorithm being used (though most will simply fall
          back to des-crypt).

        * Some OSes will return an error string if the input config
          is recognized but malformed; current code converts these to ``None``
          as well.
    c                     [        U[        5      (       d   S[        U5      -  5       eU(       d   S5       e[        X5      U:H  $ )zcheck if :func:`crypt.crypt` supports specific hash
:arg secret: password to test
:arg hash: known hash of password to use as reference
:returns: True or False
z#hash must be unicode_or_str, got %szhash must be non-empty)r   r.   r   rA   rg  s     ra   r@   r@     sH     dN++ ;-T
:;+)))4f#t++rV   c                     [         R                  " SU 5      nU(       a0  [        S UR                  S5      R	                  S5       5       5      $ g)zhelper to parse version stringz(\d+(?:\.\d+)+)c              3   8   #    U  H  n[        U5      v   M     g 7fre   )r  )r   r   s     ra   r    parse_version.<locals>.<genexpr>  s     A+@4SYY+@s   r   .N)researchr   groupr   )r   ms     ra   parse_versionrq    s=    
		$f-AA1771:+;+;C+@AAArV   r   c           	      H   SSK Jn  [        U S5      (       a"  [        U S5      (       a   U R                  5       n [        S5      U [        [        S5      (       a  [        R                  " 5       OS[        [        5       5      [        R                  " 5       [        5       [        (       a%  [        R                  " S	5      R                  S
5      OS4-  n[!        U" UR#                  S5      5      R%                  5       S5      $ ! [         a    U R                  S5      n  Nf = f)z.generate prng seed value from system resourcesr   )sha512getstategetrandbitsi   z%s %s %s %.15f %.15f %sgetpidN    r   r&  r  )hashlibrs  hasattrrt  r^   ru  r)   osrv  idobjecttimerB   has_urandomurandomr   r  r   	hexdigest)r  rs  r)  s      ra   genseedr    s    uj!!ge]&C&C	/NN$E
 &' r8,,		$ 	68 			 -8K

2i(Q#+
 
D( vdkk'*+557<<1 # 	/ %%g.E	/s   D D! D!c                 N   ^ ^ T(       d  [         $ UU 4S jn[        U" 5       5      $ )z]return byte-string containing *count* number of randomly generated bytes, using specified rngc               3   z   >#    TR                  TS-  5      n SnUT:  a  U S-  v   U S-  n US-  nUT:  a  M  g g 7f)Nr"  r      r   )ru  )r  r   r	  rC   s     ra   helpergetrandbytes.<locals>.helperM  sI     q)%i$,aKEFA %is   4;;)_BEMPTYr$   )rC   r	  r  s   `` ra   rD   rD   B  s!      FH%%rV   c                    ^ ^^^ TS:  a  [        S5      e[        T5      mTS:X  a  [        S5      eTS:X  a  TT-  $ UUUU 4S jn[        T[        5      (       a  [	        U" 5       5      $ [        U" 5       5      $ )z|return string containing *count* number of chars/bytes, whose elements are drawn from specified charset, using specified rngr   zcount must be >= 0zalphabet must not be emptyr   c               3      >#    TR                  STT-  5      n SnUT:  a  TU T-     v   U T-  n US-  nUT:  a  M  g g 7f)Nr   r   )	randrange)r  r   charsetr	  lettersrC   s     ra   r  getrandstr.<locals>.helperf  sQ     a%0%i%'/**gEFA %is   8??)r   rt   r   r+   r*   r%   )rC   r  r	  r  r  s   ``` @ra   rE   rE   W  sx     qy-..'lG!|566!|  '7##FH%%vx((rV   42346789ABCDEFGHJKMNPQRTUVWXYZabcdefghjkmnpqrstuvwxyzz2.0z/passlib.pwd.genword() / passlib.pwd.genphrase())rF  rG  replacement
   c                 "    [        [        X5      $ )aG  generate random password using given length & charset

:param size:
    size of password.

:param charset:
    optional string specified set of characters to draw from.

    the default charset contains all normal alphanumeric characters,
    except for the characters ``1IiLl0OoS5``, which were omitted
    due to their visual similarity.

:returns: :class:`!str` containing randomly generated password.

.. note::

    Using the default character set, on a OS with :class:`!SystemRandom` support,
    this function should generate passwords with 5.7 bits of entropy per character.
)rE   rC   )r   r  s     ra   rF   rF   v  s    , c7))rV   )r7  setting_kwdscontext_kwdsverifyrI  identifyc                 6   ^  [        U 4S j[         5       5      $ )z4check if object follows the :ref:`password-hash-api`c              3   <   >#    U  H  n[        TU5      v   M     g 7fre   ry  r   r7  objs     ra   r   #is_crypt_handler.<locals>.<genexpr>       =ndwsD!!nr   )r>  _handler_attrsr  s   `ra   rG   rG          =n===rV   )needs_update	genconfiggenhashr  encryptr  c                 6   ^  [        U 4S j[         5       5      $ )zOcheck if object appears to be a :class:`~passlib.context.CryptContext` instancec              3   <   >#    U  H  n[        TU5      v   M     g 7fre   r  r  s     ra   r   #is_crypt_context.<locals>.<genexpr>  r  r   )r>  _context_attrsr  s   `ra   rH   rH     r  rV   c                 L    SU R                   ;   =(       a    [        U SS5      SL$ )z_check if handler provides the optional :ref:`rounds information <rounds-attributes>` attributesrounds
min_roundsNr  getattrhandlers    ra   rI   rI     s+    ,,, =G\40<>rV   c                 L    SU R                   ;   =(       a    [        U SS5      SL$ )z[check if handler provides the optional :ref:`salt information <salt-attributes>` attributessaltmin_salt_sizeNr  r  s    ra   rJ   rJ     s-    g*** @G_d34?ArV   )NNFNNF),r  re   )r&  r  N)r&  r  )r/  )Nboolean)r   passlib.utils.compatr   binasciir   r   r   _BinAsciiErrorbase64r   r   collections.abcr	   r
   ImportErrorcollectionscodecsr   r6  	functoolsr   r   r   logging	getLoggerr   logmathrz  sysrandomrm  r   r   r}  r   	threadingtimeittypeswarningsr   passlib.utils.binaryr   r   r   r   r   r   r   r   r   r   r   r   r   passlib.utils.decorr   r   r   r   r   passlib.excr    r!   r"   r#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   __all__r  maxsizemaxintr3   r4   r5   rU   r  r   r   environr   MAX_PASSWORD_SIZEr|  r[   	ParameterVAR_KEYWORDr   setVAR_POSITIONALr   r   r   r   r6   str_consteqhmacr   r   r7   r9   r  r
  r  r  r8   r  r  r  r  r   r  r2  r   r1  r4  r:   r<  r=  r;   r<   r=   r>   rJ  r   rN  rO  rP  rS  rV  rW  r`  r?   r^  pypy_version_infoLockr_  crypt_needs_lockrY  rb  rU  r   rA   r@   default_timertimerrB   rq  r  r~  r^   r  SystemRandomrC   RandomrD   rE   
_52charsetrF   r  rG   r  rH   rI   rJ   r   rV   ra   <module>r     s   : ( D D '%((
 + $   g''1  	 
  		@
          ?M M M M M'\ txxs

A>DE   )  , 
B%
C& 

'BCKtL &F &4  $$00Lg&7&7&F&FGHL	==
 @E9>R(n3>8| 	.	:}@ N$, ,, ,&: G H G HM". 
	
6AL ( '..w7 BA y&
#1J14 55 	* u59 69 288:;	6<<>?
V	4s% IE Ti3+@+@MIM %>>+   	5&=  %

 #	7D!+	^ #	  
  	<, 	,JJqMK=B 



C --	
"C
&*): D
u!RTz *T*2
>

>>
AK%  %$$$%&  @
%?"@  Ij
  		D  	("'	 _  FIz  Ks}   O( .P P P! P> ?	P. 1Q (O>=O>
PPPP!P+*P+.P;8P;>QQQ#"Q#