;Xc@sbdZddlmZddlmZmZmZddlm Z m Z ddl Z ddl m ZddlmZddlZddlZddlZejeZddlZddlZddlZddlZddlZeryddlZWq(ek rdZdZq(Xn ddlZddl Z erIddl!Z!nddl"Z"dd l#m$Z$dd l%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2dd l3m4Z4m5Z5m6Z6m7Z7m8Z8dd l9m:Z:dd lm;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZEmFZFmGZGmHZHmIZIddddddddddddddddddd d!d"d#d$d%d&gZJeKejeArejLnejMd'd(ZNd)d*d+d,d-d.d/gZOd0d1gZPdd2l9mQZQd3ZReBd3ZSeBd4ZTeKejUjVd5pEd6ZWd7eXfd8YZYeArejZj[Z\e]e\ejZj^gZ_d9Z`n d:Z`ddeaddead;Zbd<Zcd=ZdedZeydd>lfmgZdWnek rnXd?d@ZhdAdBZiedkr.dAdCZindDZjeArRdEZkdFZln(ddGlmmZmmnZndHZkdIZle;ekdJe;eldKdLZodMZpdNZqeBdNZrddOZsdPZtetjudQZvdRZwdSZxdZyeBdTZzdVZ{dWdAddXZ|dWdAdYZ}eAr?dWdAdZZ~ndWdAd[Z~e;e~d\e4d]d^d_d`dQdaZe]dbjZe]dcjZe]d3ddgZddedfZyddglmZWn&ek rdZeaZdhZn4XeZdNZeBdiZeAr(djZn dkZe;edldmZejdnkriddol mZnddpl m ZeZdqZyejdreZWnek reaZnXddsZerejZnejeZdtZduZdvZe4d]d`d_dwdxdydzed{ZdZdZdZdZdZdZdS(s4passlib.utils -- helpers for writing password hashesi(tJYTHON(t b2a_base64t a2b_base64tError(t b64encodet b64decodeN(tlookup(tupdate_wrappersnot present under Jython(twarn( t BASE64_CHARSt AB64_CHARSt HASH64_CHARSt BCRYPT_CHARSt Base64EnginetLazyBase64Engineth64th64bigtbcrypt64t ab64_encodet ab64_decodet b64s_encodet b64s_decode(tdeprecated_functiontdeprecated_methodtmemoized_propertyt classpropertyt hybrid_method(tExpectedStringError(tadd_doct join_bytestjoin_byte_valuestjoin_byte_elemstirangetimaptPY3tut join_unicodetunicodetbyte_elem_valuet nextgettertunicode_or_bytes_typestget_method_functiontsuppress_causeRtsys_bitstunix_crypt_schemestrounds_cost_valuestconsteqtsaslprept xor_bytest render_bytest is_same_codect is_ascii_safetto_bytest to_unicodet to_native_strt has_cryptt test_cryptt safe_crypttticktrngt getrandbytest getrandstrtgenerate_passwordtis_crypt_handlertis_crypt_contextthas_rounds_infot has_salt_infoig?t sha512_cryptt sha256_cryptt sha1_crypttbcryptt md5_cryptt bsdi_cryptt des_crypttlineartlog2(tMissingBackendErrortt tPASSLIB_MAX_PASSWORD_SIZEit SequenceMixincBsMeZdZdZdZdZdZdZdZdZ RS(s helper which lets result object act like a fixed-length sequence. subclass just needs to provide :meth:`_as_tuple()`. cCstddS(Nsimplement in subclass(tNotImplemented(tself((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyt _as_tuplescCst|jS(N(treprRS(RR((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyt__repr__scCs|j|S(N(RS(RRtidx((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyt __getitem__scCst|jS(N(titerRS(RR((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyt__iter__scCst|jS(N(tlenRS(RR((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyt__len__scCs|j|kS(N(RS(RRtother((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyt__eq__scCs|j| S(N(R](RRR\((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyt__ne__s( t__name__t __module__t__doc__RSRURWRYR[R]R^(((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyRPs      cCsetjt|j}|s"tS|j|}|rJ|jtkrJtS|t |djt kS(s*test if function accepts specified keywordi( tinspectt signatureR)t parameterstFalsetgettkindt _VAR_ANY_SETtTruetlistt _VAR_KEYWORD(tfunctkeytparamstarg((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pytaccepts_keywordscCs1tjt|}||jkp0|jdk S(s*test if function accepts specified keywordN(Rbt getargspecR)targstkeywordstNone(RlRmtspec((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyRpsc st|tr|g}nt|j}|rt|trK|g}nxE|D]:|rp|krpqRn|krR|jqRqRWn|rx|D]tfd|Drqn|r&xt|D]8\}} t| rPn|rt| |rPqqWt|}n[|r{xRtt |D]/\} } t| |r?t|| }Pq?q?Wd}nd}|j |qWn|st ||_ndS(s 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. c3s|]}t|VqdS(N(t issubclass(t.0tbase(tmixin(s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pys siN( t isinstancettypeRjt __bases__tremovetanyt enumerateRvRZtreversedtinsertttuple( ttargettaddR}tappendtbeforetaftertdryruntbasesRVRxtend_idx((Rys:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pytupdate_mixin_classess@      ccs|dkrtdnt|tjrqt|}d}x||krm||}|||!V|}qBWnt|tjrt|}xdtrtj ||}yt |}Wnt k rPnXtj |f|VqWn t ddS(s8 split iterable into chunks of elements. issize must be positive integerissource must be iterableN(t ValueErrorRzt collectionstSequenceRZtIterableRXRit itertoolstislicetnextt StopIterationtchaint TypeError(tsourcetsizetendtitntitrt chunk_itrtfirst((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pytbatchs&        cCs5t|tr6t|ts-tdnt}nBt|trlt|tsctdnt}n tdt|t|k}|r|}d}n|s|}d}n|rxht||D]\}}|||AO}qWn:x7t||D]&\}}|t|t|AO}qW|dkS(sCheck 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. s)inputs must be both unicode or both bytesii( RzR%RRetbytesR"RZtziptord(tlefttrightt is_py3_bytest same_sizettmptresulttltr((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyR./s,     (tcompare_digestt,cCsX|j}|j|r(|d }n|s2gSg|j|D]}|j^qBS(sRsplit comma-separated string into list of elements, stripping whitespace. i(tstriptendswithtsplit(Rtseptelem((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyt splitcommazs   tvaluecsbt|ts+tdt|fntjtjtfd|D}tj d|}|sxt Stj }||dr||dst d|ntj }n|}tj}tj}tj}tj}tj} tj} tj} tj} tj} xD|D]<}||rCt d|n||rbt d|n||rt d |n||rt d |n| |rt d |n| |rt d |n| |rt d |n| |rt d|n| |r;t d|n||rt d|qqW|S(sNormalizes 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 `_). .. versionadded:: 1.6 s$input must be unicode string, not %sc3s3|])}|s|r'tn|VqdS(N(t_USPACE(Rwtc(t in_table_b1t in_table_c12(s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pys stNFKCiismalformed bidi sequence in s$unassigned code points forbidden in s control characters forbidden in s$private use characters forbidden in s"non-char code points forbidden in ssurrogate codes forbidden in s!non-plaintext chars forbidden in s!non-canonical chars forbidden in s1display-modifying / deprecated chars forbidden instagged characters forbidden in sforbidden bidi character in (RzR%RR{t stringprepRRR$t unicodedatat normalizet_UEMPTYt in_table_d1Rt in_table_d2t in_table_a1tin_table_c21_c22t in_table_c3t in_table_c4t in_table_c5t in_table_c6t in_table_c7t in_table_c8t in_table_c9(Rtparamtdatat is_ral_chartis_forbidden_bidi_charRRRRRRRRRR((RRs:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyR/sb,                          cCstdtdS(sstub for saslprep()s>saslprep() support requires the 'stringprep' module, which is N(tNotImplementedErrort_stringprep_missing_reason(RR((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyR/scGsHt|tr!|jd}n|td|D}|jdS(s&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. slatin-1css3|])}t|tr'|jdn|VqdS(slatin-1N(RzRtdecode(RwRo((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pys s(RzRRRtencode(RRrR((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyR1s  cCstj|dS(Ntbig(tintt from_bytes(R((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyt bytes_to_int"scCs|j|dS(NR(R4(Rtcount((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyt int_to_bytes$s(thexlifyt unhexlifycCstt|dS(Ni(RR(R((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyR)scCstd|d>|S(Ns%%0%dxi(R(RR((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyR+ss/decode byte string as single big-endian integers/encode integer as single big-endian byte stringcCs#tt|t|At|S(s;Perform bitwise-xor of two byte strings (must be same size)(RRRZ(RR((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyR01scCsBt|}||kr6||d|}||| S|| SdS(s;repeat or truncate string, so it has length iN(RZ(RRtcurtmult((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyt repeat_string5s    tcCs^t|}||krR|dkrBt|tr9tnt}n||||S|| SdS(s>right-pad or truncate string, so it has length N(RZRtRzR%t_UNULLt_BNULL(RRtpadR((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pytright_pad_stringAs    t aA:#!tasciicCstj|tkS(sRTest if codec is compatible with 7-bit ascii (e.g. latin-1, utf-8; but not utf-16)(t_ASCII_TEST_UNICODERt_ASCII_TEST_BYTES(tcodec((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pytis_ascii_codecQscCs<||krtS|o|s tSt|jt|jkS(s3Check if two codec names are aliases for same codec(RiRet _lookup_codectname(RR((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyR2Us   sics5t|trtnttfd|DS(s<Check if string (bytes or unicode) contains only 7-bit asciic3s|]}|kVqdS(N((RwR(R(s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pys bs(RzRt_B80t_U80tall(R((Rs:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyR3_ssutf-8cCsqt|trB|r;t|| r;|j|j|S|Sn+t|tr^|j|St||dS(sHelper 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*. N(RzRR2RRR%R(RtencodingRtsource_encoding((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyR4ds cCsBt|tr|St|tr/|j|St||dS(sHelper 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* N(RzR%RRR(RRR((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyR5s  cCsBt|tr|j|St|tr/|St||dS(N(RzRRR%R(RRR((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyR6s  cCsBt|tr|St|tr/|j|St||dS(N(RzRR%RR(RRR((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyR6s  s>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 t deprecateds1.6tremoveds1.7cCst||ddS(s'deprecated, use to_native_str() insteadRthash(R6(RR((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyt to_hash_strss true t yes y on 1 enable enableds#false f no n off 0 disable disabledtnonetbooleancCst|trj|jj}|tkr1tS|tkrAtS|tkrQ|St d||fn-t|t r}|S|dkr|St |SdS(s\ helper to convert value to boolean. recognizes strings such as "true", "false" sunrecognized %s value: %rN( RzR(tlowerRt _true_setRit _false_setRet _none_setRtboolRt(RRRtclean((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pytas_bools    (tcryptcCsdS(N(Rt(tsecretR((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyR9ss*:!cCst|tr@|}y|jd}Wq@tk r<dSXnt|kr[tdnt|tr||jd}nt||}| s|dtkrdS|S(Nsutf-8snull character in secretRi( RzRRtUnicodeDecodeErrorRtt_NULLRt_cryptt_invalid_prefixes(RRtorigR((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyR9s  cCst|tr!|jd}nt|kr<tdnt|tr]|jd}nt||}|svdS|jd}|dtkrdS|S(Nsutf-8snull character in secretRi( RzR%RRRRRtRR(RRR((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyR9s sWrapper 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. cCst|||kS(scheck 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 (R9(RR((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyR8Astwin32(tclock(ttimecCsBtjd|}|r>td|jdjdDSdS(shelper to parse version strings(\d+(?:\.\d+)+)css|]}t|VqdS(N(R(RwR((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pys Ysit.N(tretsearchRtgroupRRt(Rtm((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyt parse_versionUs&ic Csddlm}t|drdt|drdy|j}Wqdtk r`|jd}qdXntd|ttdrtjndt t t j t j trtjd jd nd f}t||jd jd S(s.generate prng seed value from system resourcesi(tsha512tgetstatet getrandbitsiis%s %s %s %.15f %.15f %stgetpidi slatin-1isutf-8iiN(thashlibR thasattrR RR R#tosR RttidtobjectRRt has_urandomturandomRRRt hexdigest(RR ttext((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pytgenseedqs     (cs)s tSfd}t|S(s]return byte-string containing *count* number of randomly generated bytes, using specified rngc3sMjd>}d}x-|krH|d@V|dL}|d7}qWdS(Niiii(R (RR(RR;(s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pythelpers   (t_BEMPTYR(R;RR((RR;s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyR<s csdkrtdntdkrBtdndkrVSfd}ttrt|St|SdS(s|return string containing *count* number of chars/bytes, whose elements are drawn from specified charset, using specified rngiscount must be >= 0salphabet must not be emptyic3sTjd}d}x1|krO|V|}|d7}qWdS(Nii(t randrange(RR(tcharsetRtlettersR;(s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyRs   N(RRZRzR%R$R(R;RRR((RRRR;s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyR=s      t42346789ABCDEFGHJKMNPQRTUVWXYZabcdefghjkmnpqrstuvwxyzs2.0t replacements/passlib.pwd.genword() / passlib.pwd.genphrase()i cCstt||S(swgenerate 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. (R=R;(RR((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyR>sRt setting_kwdst context_kwdstverifyRtidentifycstfdtDS(s4check if object follows the :ref:`password-hash-api`c3s|]}t|VqdS(N(R(RwR(tobj(s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pys s(Rt_handler_attrs(R"((R"s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyR?st needs_updatet genconfigtgenhashtencryptcstfdtDS(sOcheck if object appears to be a :class:`~passlib.context.CryptContext` instancec3s|]}t|VqdS(N(R(RwR(R"(s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pys s(Rt_context_attrs(R"((R"s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyR@scCs%d|jko$t|dddk S(s_check if handler provides the optional :ref:`rounds information ` attributestroundst min_roundsN(RtgetattrRt(thandler((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyRAscCs%d|jko$t|dddk S(s[check if handler provides the optional :ref:`salt information ` attributestsaltt min_salt_sizeN(RR+Rt(R,((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pyRB st(snames setting_kwdsRR shashR!(R$R%R&R R'R!(Ratpasslib.utils.compatRtbinasciiRRRt_BinAsciiErrortbase64RRRtcodecsRRt functoolsRRRbtloggingt getLoggerR_tlogtmathRtsystrandomRRt ImportErrorRtRRRttypestwarningsRtpasslib.utils.binaryR R R R R RRRRRRRRtpasslib.utils.decorRRRRRt passlib.excRRRRRR R!R"R#R$R%R&R'R(R)R*t__all__RtmaxsizetmaxintR+R,R-RLRRRtenvironRftMAX_PASSWORD_SIZERRPt Parametert VAR_KEYWORDRktsettVAR_POSITIONALRhRpReRRR.t str_consteqthmacRRR/R1RRRRR0RRRRRRRRR2RRR3R4R5R6RRRRRRRRR7R9RiRRR8tplatformRttimerR:RRRRRt SystemRandomR;tRandomR<R=t _52charsetR>R#R?R(R@RARB(((s:/usr/lib/python2.7/site-packages/passlib/utils/__init__.pytsJ              X(d .       V  >                 %            !