ó ö 5Xc@sÏdZddlmZmZddlZddlZejeƒZddl m Z ddl j j ZddlmZmZmZmZddlmZdgZdejejejejfd„ƒYZdS( spasslib.handlers.fshp iÿÿÿÿ(t b64encodet b64decodeN(t to_unicode(t bascii_to_strt iteritemstutunicode(tpbkdf1tfshpcBs`eZdZdZd ZejZedƒZ dZ d!Z dZ d Zd Zd Zd Zid"d6d#d 6d$d6d%d6ZegeD]Zeeƒef^qƒgeeƒD]\ZZedef^q«ƒZed!d„ƒZd!Zd!d„Zed„ƒZed„ƒZed„ƒZ e!j"edƒe!j#ƒZ$ed„ƒZ%d„Z&d„Z'RS(&spThis class implements the FSHP password hash, 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: :param salt: Optional raw salt string. If not specified, one will be autogenerated (this is recommended). :param salt_size: Optional number of bytes to use when autogenerating new salts. Defaults to 16 bytes, but can be any non-negative value. :param rounds: Optional number of rounds to use. Defaults to 480000, must be between 1 and 4294967295, inclusive. :param variant: Optionally specifies variant of FSHP to use. * ``0`` - uses SHA-1 digest (deprecated). * ``1`` - uses SHA-2/256 digest (default). * ``2`` - uses SHA-2/384 digest. * ``3`` - uses SHA-2/512 digest. :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 Rtsaltt salt_sizetroundstvariants{FSHPiiSiIÿÿÿÿtlineartsha1iitsha256i tsha384i0itsha512i@icKs=tt|ƒj|}|dk r9|j|ƒ|_n|S(N(tsuperRtusingtNonet _norm_varianttdefault_variant(tclsR tkwdstsubcls((s9/usr/lib/python2.7/site-packages/passlib/handlers/fshp.pyRfs cKsœ|jdƒ|_|dk r0|j|ƒ}nI|jrm|j}|j|ƒ|ksytd|fƒ‚n tdƒ‚||_tt |ƒj |dS(Nt use_defaultssinvalid default variant: %rsno variant specified( tgetRRRRtAssertionErrort TypeErrorR RRt__init__(tselfR R((s9/usr/lib/python2.7/site-packages/passlib/handlers/fshp.pyRus   +  cCs¤t|tƒr!|jdƒ}nt|tƒrdy|j|}Wqdtk r`tdƒ‚qdXnt|tƒs‚tdƒ‚n||j kr tdƒ‚n|S(Ntasciisinvalid fshp variants'fshp variant must be int or known alias( t isinstancetbytestdecodeRt_variant_aliasestKeyErrort ValueErrortintRt _variant_info(RR ((s9/usr/lib/python2.7/site-packages/passlib/handlers/fshp.pyR‚s cCs|j|jdS(Ni(R(R (R((s9/usr/lib/python2.7/site-packages/passlib/handlers/fshp.pyt checksum_alg‘scCs|j|jdS(Ni(R(R (R((s9/usr/lib/python2.7/site-packages/passlib/handlers/fshp.pyt checksum_size•ss¶ ^ \{FSHP (\d+)\| # variant (\d+)\| # salt size (\d+)\} # rounds ([a-zA-Z0-9+/]+={0,3}) # digest $c Csùt|ddƒ}|jj|ƒ}|s?tjj|ƒ‚n|jddddƒ\}}}}t|ƒ}t|ƒ}t|ƒ}yt|j dƒƒ}Wn#t k rÅtjj |ƒ‚nX|| }||}|d|d|d |d |ƒS( NR thashiiiiR tchecksumR R ( Rt _hash_regextmatchtuhtexctInvalidHashErrortgroupR'RtencodeRtMalformedHashError( RR+tmR R R tdataR tchk((s9/usr/lib/python2.7/site-packages/passlib/handlers/fshp.pyt from_string¦s$      cCsH|j}|j}tt||ƒƒ}d|jt|ƒ|j|fS(Ns{FSHP%d|%d|%d}%s(R,R RRR tlenR (RR7R R6((s9/usr/lib/python2.7/site-packages/passlib/handlers/fshp.pyt to_string¸s  c CsRt|tƒr!|jdƒ}ntd|jd|jd|d|jd|jƒS(Nsutf-8tdigesttsecretR R tkeylen(R!RR3RR)R R R*(RR<((s9/usr/lib/python2.7/site-packages/passlib/handlers/fshp.pyt_calc_checksumÂs   (ssalts salt_sizesroundssvariantN(Ri(Ri (Ri0(Ri@((t__name__t __module__t__doc__tnamet setting_kwdsR/tPADDED_BASE64_CHARStchecksum_charsRtidenttdefault_salt_sizeRt max_salt_sizetdefault_roundst min_roundst max_roundst rounds_costRR(tdicttkRRtvR$t classmethodRR RRtpropertyR)R*tretcompiletXR-R8R:R>(((s9/usr/lib/python2.7/site-packages/passlib/handlers/fshp.pyRs@$   "3    (RAtbase64RRRRtloggingt getLoggerR?tlogt passlib.utilsRtpasslib.utils.handlerstutilsthandlersR/tpasslib.utils.compatRRRRtpasslib.crypto.digestRt__all__t HasRoundst HasRawSalttHasRawChecksumtGenericHandlerR(((s9/usr/lib/python2.7/site-packages/passlib/handlers/fshp.pyts  "