Current File : //usr/lib/python2.7/site-packages/passlib/utils/handlers.pyc
�
���Xc@�s:dZddlmZddlZddlZeje�ZddlZddl	Z	ddl
mZddlj
Z
ddljZddlmZmZmZddlmZddlmZddlmZmZmZmZmZmZmZmZmZm Z m!Z!dd	l"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)dd
l*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m0Z0m3Z3m4Z4m5Z5ddl6m7Z7m8Z8dd
ddddddddddddgZ9e$Z:e#Z;e%Z<e'Z=e(Z>d�Z?dd�Z@d�ZAd�ZBe-d�ZCe-d �ZDd!�ZEd"�ZFeCeGd#�ZHeCd$eGeGd%�ZId$eGd&eGd'�ZJe-d�d(�ZKe-d�d$d)�ZLd&d*�ZMdeGd&eNd+�ZOd,efd-��YZPd.ePfd/��YZQdePfd0��YZRdeRfd1��YZSd2eRfd3��YZTdeRfd4��YZUdeRfd5��YZVdeRfd6��YZWdeRfd7��YZXdeXfd8��YZYdeRfd9��YZZd:eRfd;��YZ[e	j\�Z]d<efd=��YZ^d>e^fd?��YZ_de^eRfd@��YZ`deafdA��YZbdS(BsRpasslib.handler - code for implementing handlers, and global registry for handlersi����(twith_statementN(twarn(tMissingBackendErrortPasslibConfigWarningtPasslibHashWarning(tPasswordHash(tget_crypt_handler(tconsteqt
getrandstrtgetrandbytestrngt
to_native_strtis_crypt_handlert
to_unicodetMAX_PASSWORD_SIZEtaccepts_keywordtas_booltupdate_mixin_classes(tBASE64_CHARStHASH64_CHARStPADDED_BASE64_CHARSt	HEX_CHARStUPPER_HEX_CHARStLOWER_HEX_CHARStALL_BYTE_VALUES(tjoin_byte_valuestirangetutnative_string_typest
uascii_to_strtjoin_unicodetunicodet
str_to_uasciiRtunicode_or_bytes_typestPY2t	int_types(t
classpropertytdeprecated_methodt	parse_mc2t	parse_mc3t
render_mc2t
render_mc3tGenericHandlert
StaticHandlertHasUserContexttHasRawChecksumt
HasManyIdentstHasSaltt
HasRawSaltt	HasRoundstHasManyBackendst
PrefixWrappercC�s@|r8|r8ddl}t||jt|�d��SdSdS(shelper for bitsize() methodsi����Nii(tmathtinttlogtlen(tcounttcharsR4((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyt_bitsizeJs icC�s�tj�}|}zix^|rv|jjdd�}|jd�sS|jd�r`td|�S|d7}|j}qW|SWd~XdS(si
    try to guess stacklevel for application warning.
    looks for first frame not part of passlib.
    t__name__tspasslib.tests.spasslib.iN(tinspecttcurrentframet	f_globalstgett
startswithtmaxtf_back(tstarttframeR8tname((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pytguess_app_stacklevelRs	


cC�s-tdtd|j�tdtd��dS(Ns�passing settings to %(handler)s.hash() is deprecated, and won't be supported in Passlib 2.0; use '%(handler)s.using(**settings).hash(secret)' insteadthandlert
stackleveli(RtdictRFtDeprecationWarningRG(RHtkwds((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pytwarn_hash_settings_deprecationdsc�s2t|j��t��fd�t��D��S(s�
    helper to extract settings kwds from mix of context & settings kwds.
    pops settings keys from kwds, returns them as a dict.
    c3�s0|]&}|�kr|�j|�fVqdS(N(tpop(t.0tkey(tcontext_keysRL(s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pys	<genexpr>os(tsettcontext_kwdsRJtlist(RHRL((RQRLs:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pytextract_settings_kwdsist$t0cC�sLt|t�s$tj|d��nt|�tkrHtjt��ndS(s%ensure secret has correct type & sizetsecretN(t
isinstanceR!texctExpectedStringErrorR7RtPasswordSizeError(RX((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pytvalidate_secretwscC�sjt|t�r|St|t�rTy|jd�SWqftk
rP|jd�SXntj|d��dS(s+convert hash to unicode for identify methodsutf-8slatin-1thashN(RYRtbytestdecodetUnicodeDecodeErrorRZR[(R^((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pytto_unicode_for_identify~s
cC�s�t|dd�}t|t�s't�|j|�sHtj|��nt|t�s]t�|t|�j|�}t|�dkr�|\}}||p�dfSt|�dkr�|ddfStj
|��dS(s�parse hash using 2-part modular crypt format.

    this expects a hash of the format :samp:`{prefix}{salt}[${checksum}]`,
    such as md5_crypt, and parses it into salt / checksum portions.

    :arg hash: the hash to parse (bytes or unicode)
    :arg prefix: the identifying prefix (unicode)
    :param sep: field separator (unicode, defaults to ``$``).
    :param handler: handler class to pass to error constructors.

    :returns:
        a ``(salt, chk | None)`` tuple.
    tasciiR^iiiN(R
RYRtAssertionErrorRARZtInvalidHashErrorR7tsplittNonetMalformedHashError(R^tprefixtsepRHtpartstsalttchk((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR&�si
c
C�sOt|dd�}t|t�s't�|j|�sHtj|��nt|t�s]t�|t|�j|�}t|�dkr�|\}}}	n6t|�dkr�|\}}d}	ntj
|��|jt�r�|tkr�tj|��n?|rt
||�}n'|dkr6tj
|d��n|}|||	pKdfS(srparse hash using 3-part modular crypt format.

    this expects a hash of the format :samp:`{prefix}[{rounds}]${salt}[${checksum}]`,
    such as sha1_crypt, and parses it into rounds / salt / checksum portions.
    tries to convert the rounds to an integer,
    and throws error if it has zero-padding.

    :arg hash: the hash to parse (bytes or unicode)
    :arg prefix: the identifying prefix (unicode)
    :param sep: field separator (unicode, defaults to ``$``).
    :param rounds_base:
        the numeric base the rounds are encoded in (defaults to base 10).
    :param default_rounds:
        the default rounds value to return if the rounds field was omitted.
        if this is ``None`` (the default), the rounds field is *required*.
    :param handler: handler class to pass to error constructors.

    :returns:
        a ``(rounds : int, salt, chk | None)`` tuple.
    RcR^iisempty rounds fieldN(R
RYRRdRARZReR7RfRgRht_UZEROtZeroPaddedRoundsErrorR5(
R^RiRjtrounds_basetdefault_roundsRHRktroundsRlRm((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR'�s(	tvaluecC�st|jt�r4|tkr4tj|d|��n<|rGt||�S|dkrltj|d|��n|SdS(s
    helper to parse an integer config field

    :arg source: unicode source string
    :param base: numeric base
    :param default: optional default if source is empty
    :param param: name of variable, for error msgs
    :param handler: handler class, for error msgs
    szero-padded %s fieldsempty %s fieldN(RARnRZRhR5Rg(tsourcetbasetdefaulttparamRH((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyt	parse_int�s

cC�s7|r||||g}n||g}tt|��S(s�format hash using 2-part modular crypt format; inverse of parse_mc2()

    returns native string with format :samp:`{ident}{salt}[${checksum}]`,
    such as used by md5_crypt.

    :arg ident: identifier prefix (unicode)
    :arg salt: encoded salt (unicode)
    :arg checksum: encoded checksum (unicode or None)
    :param sep: separator char (unicode, defaults to ``$``)

    :returns:
        config or hash (native str)
    (RR(tidentRltchecksumRjRk((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR(
scC�s�|dkrtd�}n=|dkr:td�|}n|dksLt�t|�}|ry||||||g}n||||g}tt|��S(s.format hash using 3-part modular crypt format; inverse of parse_mc3()

    returns native string with format :samp:`{ident}[{rounds}$]{salt}[${checksum}]`,
    such as used by sha1_crypt.

    :arg ident: identifier prefix (unicode)
    :arg rounds: rounds field (int or None)
    :arg salt: encoded salt (unicode)
    :arg checksum: encoded checksum (unicode or None)
    :param sep: separator char (unicode, defaults to ``$``)
    :param rounds_base: base to encode rounds value (defaults to base 10)

    :returns:
        config or hash (native str)
    R<is%xi
N(RgRRdRRR(RyRrRlRzRjRpRk((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR)!scC�sW|dk	s%td|j|f��||�|ksStd|j||f��tS(s�
    assert helper that quickly validates default value.
    designed to get out of the way and reduce overhead when asserts are stripped.
    s%s lacks default %ss%s: invalid default %s: %rN(RgRdRFtTrue(RHRvtnormRw((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pytvalidate_default_valueBs%.cC�s�t|t�s'tj|d|��n||krzd|j|||f}|rkt|tj�|}qzt|��n|r�||kr�d|j|||f}|r�t|tj�|}q�t|��n|S(s�
    helper to normalize and validate an integer value (e.g. rounds, salt_size)

    :arg value: value provided to constructor
    :arg default: default value if none provided. if set to ``None``, value is required.
    :arg param: name of parameter (xxx: move to first arg?)
    :param min: minimum value (defaults to 1)
    :param max: maximum value (default ``None`` means no maximum)
    :returns: validated value
    tintegers+%s: %s (%d) is too low, must be at least %ds0%s: %s (%d) is too large, cannot be more than %d(RYR#RZtExpectedTypeErrorRFRRt
ValueError(RHRstminRBRwtrelaxedtmsg((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pytnorm_integerKs
		tMinimalHandlercB�s&eZdZeZeed��ZRS(s�
    helper class for implementing hash handlers.
    provides nothing besides a base implementation of the .using() subclass constructor.
    cC�sD|j}|jsd|}nt||ftd|jdt��S(Ns<customized %s hasher>t
__module__t_configured(R;R�ttypeRJR�R{(tclsR�RF((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pytusing�s		
(R;R�t__doc__tFalseR�tclassmethodR�(((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�rst
TruncateMixincB�s;eZdZeZeZedd��Zed��Z	RS(s�
    PasswordHash mixin which provides a method
    that will check if secret would be truncated,
    and can be configured to throw an error.

    .. warning::

        Hashers using this mixin will generally need to override
        the default PasswordHash.truncate_error policy of "True",
        and will similarly want to override .truncate_verify_reject as well.

        TODO: This should be done explicitly, but for now this mixin sets
        these flags implicitly.
    cK�sUtt|�j|�}|dk	rQt|dd�}|dk	rQ||_qQn|S(NRwttruncate_error(tsuperR�R�RgRR�(R�R�RLtsubcls((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��scC�sO|jdk	std��|jrKt|�|jkrKtj|��ndS(s�
        make sure secret won't be truncated.
        NOTE: this should only be called for .hash(), not for .verify(),
        which should honor the .truncate_verify_reject policy.
        s%truncate_size must be set by subclassN(t
truncate_sizeRgRdR�R7RZtPasswordTruncateError(R�RX((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyt_check_truncate_policy�sN(
R;R�R�R�R�ttruncate_verify_rejectR�RgR�R�(((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��scB�sseZdZdZdZdZdZdZdZ	e
ZdZde
d�Z
e
d�Zed��Zed��Zd�Zed��Zd�Zed��Zed	��Zed
ddd
�ed���Zed
ddd
�ed���Zedd��Zdd�ZdZdZed��Z e!e"d�d��Z#ee$e
d��Z%ed��Z&RS(s4helper class for implementing hash handlers.

    GenericHandler-derived classes will have (at least) the following
    constructor options, though others may be added by mixins
    and by the class itself:

    :param checksum:
        this should contain the digest portion of a
        parsed hash (mainly provided when the constructor is called
        by :meth:`from_string()`).
        defaults to ``None``.

    :param use_defaults:
        If ``False`` (the default), a :exc:`TypeError` should be thrown
        if any settings required by the handler were not explicitly provided.

        If ``True``, the handler should attempt to provide a default for any
        missing values. This means generate missing salts, fill in default
        cost parameters, etc.

        This is typically only set to ``True`` when the constructor
        is called by :meth:`hash`, allowing user-provided values
        to be handled in a more permissive manner.

    :param relaxed:
        If ``False`` (the default), a :exc:`ValueError` should be thrown
        if any settings are out of bounds or otherwise invalid.

        If ``True``, they should be corrected if possible, and a warning
        issue. If not possible, only then should an error be raised.
        (e.g. under ``relaxed=True``, rounds values will be clamped
        to min/max rounds).

        This is mainly used when parsing the config strings of certain
        hashes, whose specifications implementations to be tolerant
        of incorrect values in salt strings.

    Class Attributes
    ================

    .. attribute:: ident

        [optional]
        If this attribute is filled in, the default :meth:`identify` method will use
        it as a identifying prefix that can be used to recognize instances of this handler's
        hash. Filling this out is recommended for speed.

        This should be a unicode str.

    .. attribute:: _hash_regex

        [optional]
        If this attribute is filled in, the default :meth:`identify` method
        will use it to recognize instances of the hash. If :attr:`ident`
        is specified, this will be ignored.

        This should be a unique regex object.

    .. attribute:: checksum_size

        [optional]
        Specifies the number of characters that should be expected in the checksum string.
        If omitted, no check will be performed.

    .. attribute:: checksum_chars

        [optional]
        A string listing all the characters allowed in the checksum string.
        If omitted, no check will be performed.

        This should be a unicode str.

    .. attribute:: _stub_checksum

        Placeholder checksum that will be used by genconfig()
        in lieu of actually generating a hash for the empty string.
        This should be a string of the same datatype as :attr:`checksum`.

    Instance Attributes
    ===================
    .. attribute:: checksum

        The checksum string provided to the constructor (after passing it
        through :meth:`_norm_checksum`).

    Required Subclass Methods
    =========================
    The following methods must be provided by handler subclass:

    .. automethod:: from_string
    .. automethod:: to_string
    .. automethod:: _calc_checksum

    Default Methods
    ===============
    The following methods have default implementations that should work for
    most cases, though they may be overridden if the hash subclass needs to:

    .. automethod:: _norm_checksum

    .. automethod:: genconfig
    .. automethod:: genhash
    .. automethod:: identify
    .. automethod:: hash
    .. automethod:: verify
    cK�sD||_tt|�j|�|dk	r@|j|�|_ndS(N(tuse_defaultsR�R*t__init__Rgt_norm_checksumRz(tselfRzR�RL((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�Ls	c�s|j}|r9t|t�s�tj|dd��q�n[t|t�s�t|t�r||r|tdt�|jd�}q�tj|dd��n|j	}|r�t
|�|kr�tj|d|��n|s|j��rt
�fd�|D��rtd|jf��qn|S(	sovalidates checksum keyword against class requirements,
        returns normalized version of checksum.
        R_Rzs%checksum should be unicode, not bytesRcRtrawc3�s|]}|�kVqdS(N((ROtc(tcs(s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pys	<genexpr>tss!invalid characters in %s checksum(t_checksum_is_bytesRYR_RZRRRRR`t
checksum_sizeR7tChecksumSizeErrortchecksum_charstanyR�RF(R�RzR�R�tcc((R�s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�Us"		
		"cC�s�t|�}|stS|j}|dk	r8|j|�S|j}|dk	r`|j|�dk	Sy|j|�tSWnt	k
r�tSXdS(N(
RbR�RyRgRAt_hash_regextmatchtfrom_stringR{R�(R�R^Rytpat((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pytidentify|s	
	

cK�std|f��dS(sV
        return parsed instance from hash/configuration string

        :param \*\*context:
            context keywords to pass to constructor (if applicable).

        :raises ValueError: if hash is incorrectly formatted

        :returns:
            hash parsed into components,
            for formatting / calculating checksum.
        s%s must implement from_string()N(tNotImplementedError(R�R^tcontext((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��scC�std|jf��dS(s�render instance to hash or configuration string

        :returns:
            hash string with salt & digest included.

            should return native string type (ascii-bytes under python 2,
            unicode under python 3)
        s%s must implement from_string()N(R�t	__class__(R�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyt	to_string�s	cC�s�|jr;|jrd|jS|jr;|jd|jSnt|t�r�|j}|jp_d|_z|jd�SWd||_Xn|jd�S(si
        placeholder used by default .genconfig() so it can avoid expense of calculating digest.
        tiiR<N(R�R�R�RYR1Rrt
min_roundst_calc_checksum(R�torig((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyt_stub_checksum�s				
cC�std|jf��dS(sgiven secret; calcuate and return encoded checksum portion of hash
        string, taking config from object state

        calc checksum implementations may assume secret is always
        either unicode or bytes, checks are performed by verify/etc.
        s"%s must implement _calc_checksum()N(R�R�(R�RX((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��scK�s||rDt||�}|rDt||�|j|�j||�Snt|�|dt|�}|j|�|_|j�S(NR�(	RURMR�R^R]R{R�RzR�(R�RXRLtsettingsR�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR^�s

cK�sYt|�|j||�}|j}|dkrCtj|��nt|j|�|�S(N(R]R�RzRgRZtMissingDigestErrorRR�(R�RXR^R�R�Rm((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pytverify�s
	t
deprecateds1.7tremoveds2.0cK�sSt||�}|r+|j|�j|�S|dt|�}|j|_|j�S(NR�(RUR�t	genconfigR{R�RzR�(R�RLR�R�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��scK�sS|dkrtd��nt|�|j||�}|j|�|_|j�S(Nsconfig must be string(Rgt	TypeErrorR]R�R�RzR�(R�RXtconfigR�R�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pytgenhashs
cK�s7|j|�}t||�s$t�|jd||�S(NRX(R�RYRdt_calc_needs_update(R�R^RXRLR�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pytneeds_updatescC�stS(s;
        internal helper for :meth:`needs_update`.
        (R�(R�RX((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�"st	salt_sizeR�RlRzc�s�fd��jD�S(Nc3�s$|]}|�jkr|VqdS(N(t_unparsed_settings(RORP(R�(s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pys	<genexpr>3s(tsetting_kwds(R�((R�s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyt_parsed_settings1st*cC�s�|dkrdSt|t�rGddlm}||�jd�}nt|t�set|�}nt|�}td|d�}|| |||S(s*default method to obscure sensitive fieldsi����(tab64_encodeRciiN(	RgRYR_tpasslib.utils.binaryR�R`RR7R�(RstcharR�tsizetclip((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyt	_sanitize7sc�s��j|��t��t���fd��jD��}|rb�jdk	rb�j|d<n|r�|tkr��j}nx7�jD])}||kr�|||�||<q�q�Wn|S(s�[experimental method] parse hash into dictionary of settings.

        this essentially acts as the inverse of :meth:`hash`: for most
        cases, if ``hash = cls.hash(secret, **opts)``, then
        ``cls.parsehash(hash)`` will return a dict matching the original options
        (with the extra keyword *checksum*).

        this method may not work correctly for all hashes,
        and may not be available on some few. its interface may
        change in future releases, if it's kept around at all.

        :arg hash: hash to parse
        :param checksum: include checksum keyword? (defaults to True)
        :param sanitize: mask data for sensitive fields? (defaults to False)
        c3�sE|];}t�|�t�|��kr|t�|�fVqdS(N(tgetattr(RORP(tUNSETR�R�(s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pys	<genexpr>]sRzN(	R�tobjectRJR�RzRgR{R�t_unsafe_settings(R�R^RztsanitizeRLRP((R�R�R�s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyt	parsehashEs	%cK�szytt|�j|�}Wntk
r5i}nX|jrEtn|j}|jrv|rvt|j|�|d<n|S(s8[experimental method] return info about bitsizes of hashRz(	R�R*tbitsizetAttributeErrorR�RR�R�R:(R�RLtinfoR�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�is

N((s	salt_sizesrelaxed(ssaltschecksum('R;R�R�RgR�RSRyR�R�R�R�R�RzR�R�R�R�R�R�tpropertyR�R�R^R�R%R�R�R�R�R�R�R$R�tstaticmethodRR�R{R�R�(((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR*�sBj	'		

#cB�sVeZdZdZed�Zed��Zed��Zd�Z	dZd�ZRS(s;GenericHandler mixin for classes which have no settings.

    This mixin assumes the entirety of the hash ise stored in the
    :attr:`checksum` attribute; that the hash has no rounds, salt,
    etc. This class provides the following:

    * a default :meth:`genconfig` that always returns None.
    * a default :meth:`from_string` and :meth:`to_string`
      that store the entire hash within :attr:`checksum`,
      after optionally stripping a constant prefix.

    All that is required by subclasses is an implementation of
    the :meth:`_calc_checksum` method.
    R<cK�stt|dd�}|j|�}|j}|rd|j|�rR|t|�}qdtj|��n|d||�S(NRcR^Rz(R
t
_norm_hasht_hash_prefixRAR7RZRe(R�R^R�Ri((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��s	cC�s|S(s1helper for subclasses to normalize case if needed((R�R^((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��scC�st|j|j�S(N(RR�Rz(R�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��sc�s�j��jtkst��j}|d	krz�fd�}t�jd�ftd|d�j��}�_nt�fd��jD��}y|j	|d	|�}Wn>t
k
r�}t|�dkr�td�f��q��nXt
d�t�t|�S(
s{given secret; calcuate and return encoded checksum portion of hash
        string, taking config from object state
        c�std�f��dS(Ns"%s must implement _calc_checksum()(R�(R�RX(R�(s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pytinner�st_wrapperR�R�c3�s$|]}|t�|�fVqdS(N(R�(ROtk(R�(s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pys	<genexpr>�ssconfig must be strings"%s must implement _calc_checksum()s�%r should be updated to implement StaticHandler._calc_checksum() instead of StaticHandler.genhash(), support for the latter style will be removed in Passlib 1.8N(R�R�R;Rdt_StaticHandler__cc_compat_hackRgR�RJRSR�R�tstrR�RRKR (R�RXtwrapper_clsR�R�R^terr((R�R�s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��s&
		
+(N(
R;R�R�R�RR�R�R�R�R�RgR�R�(((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR+{s	tHasEncodingContextcB�s&eZdZdZdZdd�ZRS(s?helper for classes which require knowledge of the encoding usedtencodingsutf-8cK�s,tt|�j|�|p"|j|_dS(N(R�R�R�tdefault_encodingR�(R�R�RL((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��s(sencodingN(R;R�R�RSR�RgR�(((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��scB�skeZdZd
Zdd�Zedd��Zedd��Ze	dddd�edd	���Z
RS(s7helper for classes which require a user context keywordtusercK�s#tt|�j|�||_dS(N(R�R,R�R�(R�R�RL((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��scK�stt|�j|d||�S(NR�(R�R,R^(R�RXR�R�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR^�scK�s"tt|�j||d||�S(NR�(R�R,R�(R�RXR^R�R�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��sR�s1.7R�s2.0cK�s"tt|�j||d||�S(NR�(R�R,R�(R�RXR�R�R�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��s(suserN(R;R�R�RSRgR�R�R^R�R%R�(((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR,�scB�seZdZeZRS(sqmixin for classes which work with decoded checksum bytes

    .. todo::

        document this class's usage
    (R;R�R�R{R�(((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR-scB�steZdZdZdZdZdZeddd��Z	dd�Z
ed��Zed��Zed��Z
RS(s mixin for hashes which use multiple prefix identifiers

    For the hashes which may use multiple identifier prefixes,
    this mixin adds an ``ident`` keyword to constructor.
    Any value provided is passed through the :meth:`norm_idents` method,
    which takes care of validating the identifier,
    as well as allowing aliases for easier specification
    of the identifiers by the user.

    .. todo::

        document this class's usage

    Class Methods
    =============
    .. todo:: document using() and needs_update() options
    cK�sv|dk	r0|dk	r'td��n|}ntt|�j|�}|dk	rr|d|dt�j|_n|S(s4
        This mixin adds support for the following :meth:`~passlib.ifc.PasswordHash.using` keywords:

        :param default_ident:
            default identifier that will be used by resulting customized hasher.

        :param ident:
            supported as alternate alias for **default_ident**.
        s2'default_ident' and 'ident' are mutually exclusiveRyR�N(RgR�R�R.R�R{Ryt
default_ident(R�R�RyRLR�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�>s
	cK�s�tt|�j|�|dk	r4|j|�}nB|jrj|j}t|||jdd�svt�nt	d��||_
dS(NRwR�sno ident specified(R�R.R�Rgt_norm_identR�R�R}RdR�Ry(R�RyRL((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�\s		$cC�s�|dk	st�t|t�r3|jd�}n|j}||krL|S|j}|r�y||}Wntk
r|q�X||kr�|Sntd|f��dS(sD
        helper which normalizes & validates 'ident' value.
        Rcsinvalid ident: %rN(	RgRdRYR_R`tident_valuest
ident_aliasestKeyErrorR�(R�RytivtiaRs((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�is		
cC�st|�}|j|j�S(N(RbRAR�(R�R^((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��scC�s\t|dd�}x4|jD])}|j|�r||t|�fSqWtj|��dS(sDextract ident prefix from hash, helper for subclasses' from_string()RcR^N(R
R�RAR7RZRe(R�R^Ry((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyt_parse_ident�s
N(R;R�R�RgR�R�R�RyR�R�R�R�R�R�(((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR.s
 cB�s�eZdZdZdZdZed��Zed��Z	e
ZdZdZ
edddd��Zeded��Zdd�Zd	�Zee
d
��Zed��Zed��Zedd
��ZRS(s2
mixin for validating salts.

    This :class:`GenericHandler` mixin adds a ``salt`` keyword to the class constuctor;
    any value provided is passed through the :meth:`_norm_salt` method,
    which takes care of validating salt length and content,
    as well as generating new salts if one it not provided.

    :param salt:
        optional salt string

    :param salt_size:
        optional size of salt (only used if no salt provided);
        defaults to :attr:`default_salt_size`.

    Class Attributes
    ================
    In order for :meth:`!_norm_salt` to do its job, the following
    attributes should be provided by the handler subclass:

    .. attribute:: min_salt_size

        The minimum number of characters allowed in a salt string.
        An :exc:`ValueError` will be throw if the provided salt is too small.
        Defaults to ``0``.

    .. attribute:: max_salt_size

        The maximum number of characters allowed in a salt string.
        By default an :exc:`ValueError` will be throw if the provided salt is
        too large; but if ``relaxed=True``, it will be clipped and a warning
        issued instead. Defaults to ``None``, for no maximum.

    .. attribute:: default_salt_size

        [required]
        If no salt is provided, this should specify the size of the salt
        that will be generated by :meth:`_generate_salt`. By default
        this will fall back to :attr:`max_salt_size`.

    .. attribute:: salt_chars

        A string containing all the characters which are allowed in the salt
        string. An :exc:`ValueError` will be throw if any other characters
        are encountered. May be set to ``None`` to skip this check (but see
        in :attr:`default_salt_chars`).

    .. attribute:: default_salt_chars

        [required]
        This attribute controls the set of characters use to generate
        *new* salt strings. By default, it mirrors :attr:`salt_chars`.
        If :attr:`!salt_chars` is ``None``, this attribute must be specified
        in order to generate new salts. Aside from that purpose,
        the main use of this attribute is for hashes which wish to generate
        salts from a restricted subset of :attr:`!salt_chars`; such as
        accepting all characters, but only using a-z.

    Instance Attributes
    ===================
    .. attribute:: salt

        This instance attribute will be filled in with the salt provided
        to the constructor (as adapted by :meth:`_norm_salt`)

    Subclassable Methods
    ====================
    .. automethod:: _norm_salt
    .. automethod:: _generate_salt
    icC�s|jS(s/default salt size (defaults to *max_salt_size*)(t
max_salt_size(R�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pytdefault_salt_size�scC�s|jS(sDcharset used to generate new salt strings (defaults to *salt_chars*)(t
salt_chars(R�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pytdefault_salt_chars�sR9c�s�|dk	r0|dk	r'td��n|}ntt|�j|�}|jd�}|dk	r�t|t�r�t|�}n|j	|ddd|�|_
n�dk	r�|j�d|��t�fd��|_
n|S(NsB'salt_size' and 'default_salt_size' aliases are mutually exclusiveR�RwR�c�s�S(N(((Rl(s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyt<lambda>&s(RgR�R�R/R�R@RYRR5t_clip_to_valid_salt_sizeR�t
_norm_saltR�t_generate_salt(R�R�R�RlRLR�R�((Rls:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�	s 	R�cC�s|j}|j}||krl||krhd|j|||f}|rYt|t�qht|��n|S||kr�d|j|||f}|r�t|t�|}q�t|��n|r||krd|j|||f}|rt|t�|}qt|��n|S(s�
        internal helper --
        clip salt size value to handler's absolute limits (min_salt_size / max_salt_size)

        :param relaxed:
            if ``True`` (the default), issues PasslibHashWarning is rounds are outside allowed range.
            if ``False``, raises a ValueError instead.

        :param param:
            optional name of parameter to insert into error/warning messages.

        :returns:
            clipped rounds value
        s%s: %s (%d) must be exactly %ds$%s: %s (%r) below min_salt_size (%d)s$%s: %s (%r) above max_salt_size (%d)(t
min_salt_sizeR�RFRRR�(R�R�RwR�tmntmxR�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�+s,		
	
	cK�s�tt|�j|�|dk	r4|j|�}nL|jrt|j�}|j|�|ks�td|f��nt	d��||_
dS(Nsgenerated invalid salt: %rsno salt specified(R�R/R�Rgt_parse_saltR�R�R�RdR�Rl(R�RlRL((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�_s	+cC�s
|j|�S(N(R�(R�Rl((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�ksc
�s�|jr3t|t�s�tj|dd��q�n�t|t�s�t|t�rots]|ro|jd�}q�tj|dd��n|j��dk	r�t
�fd�|D��r�td|j��n|j
}|r/t|�|kr/d|j||jkr
dnd	||jf}t|��n|j}|r�t|�|kr�d
|j||krkdnd||jf}|r�t|t�|j||�}q�t|��n|S(
sThelper to normalize & validate user-provided salt string

        :arg salt:
            salt string

        :raises TypeError:
            If salt not correct type.

        :raises ValueError:

            * if salt contains chars that aren't in :attr:`salt_chars`.
            * if salt contains less than :attr:`min_salt_size` characters.
            * if ``relaxed=False`` and salt has more than :attr:`max_salt_size`
              characters (if ``relaxed=True``, the salt is truncated
              and a warning is issued instead).

        :returns:
            normalized salt
        R_RlRcRc3�s|]}|�kVqdS(N((ROR�(tsc(s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pys	<genexpr>�ssinvalid characters in %s salts%salt too small (%s requires %s %d %s)texactlys>=s%salt too large (%s requires %s %d %s)s<=N(t_salt_is_bytesRYR_RZRRR"R`R�RgR�R�RFR�R7R�t
_salt_unitRRt_truncate_salt(R�RlR�R�R�R�((R�s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�ns0		(		(		%
cC�s|| S(N((RlR�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��scC�stt|j|j�S(sU
        helper method for _init_salt(); generates a new random salt string.
        (RR
R�R�(R�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��scK�sJtt|�j|�}|dkr0|j}nt||j�|d<|S(s8[experimental method] return info about bitsizes of hashRlN(R�R/R�RgR�R:R�(R�R�RLR�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��s
N(R;R�R�R�RgR�R�R$R�R�R�R�R�RlR�R�R{R�R�R�R�R�R�R�R�(((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR/�s.E3	9cB�s/eZdZeZeZdZed��Z	RS(s�mixin for classes which use decoded salt parameter

    A variant of :class:`!HasSalt` which takes in decoded bytes instead of an encoded string.

    .. todo::

        document this class's usage
    R_cC�s+|jdtgkst�tt|j�S(N(R�RgRRdR	R
R�(R�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��s(
R;R�R�RR�R{R�R�R�R�(((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR0�s
c	B�s�eZdZdZdZdZdZdZdZ	dZ
dZdZe
dddddddd	��Ze
d
��Ze
d��Zdd�Zd
�Ze
edd��Ze
d��Zd�Ze
ddd��ZRS(s3mixin for validating rounds parameter

    This :class:`GenericHandler` mixin adds a ``rounds`` keyword to the class
    constuctor; any value provided is passed through the :meth:`_norm_rounds`
    method, which takes care of validating the number of rounds.

    :param rounds: optional number of rounds hash should use

    Class Attributes
    ================
    In order for :meth:`!_norm_rounds` to do its job, the following
    attributes must be provided by the handler subclass:

    .. attribute:: min_rounds

        The minimum number of rounds allowed. A :exc:`ValueError` will be
        thrown if the rounds value is too small. Defaults to ``0``.

    .. attribute:: max_rounds

        The maximum number of rounds allowed. A :exc:`ValueError` will be
        thrown if the rounds value is larger than this. Defaults to ``None``
        which indicates no limit to the rounds value.

    .. attribute:: default_rounds

        If no rounds value is provided to constructor, this value will be used.
        If this is not specified, a rounds value *must* be specified by the
        application.

    .. attribute:: rounds_cost

        [required]
        The ``rounds`` parameter typically encodes a cpu-time cost
        for calculating a hash. This should be set to ``"linear"``
        (the default) or ``"log2"``, depending on how the rounds value relates
        to the actual amount of time that will be required.

    Class Methods
    =============
    .. todo:: document using() and needs_update() options

    Instance Attributes
    ===================
    .. attribute:: rounds

        This instance attribute will be filled in with the rounds value provided
        to the constructor (as adapted by :meth:`_norm_rounds`)

    Subclassable Methods
    ====================
    .. automethod:: _norm_rounds
    itlineartmin_desired_roundstmax_desired_roundsR�t
max_roundsRqtvary_roundsc
	K�s�|dk	r0|dk	r'td��n|}n|dk	r`|dk	rWtd��n|}n|dk	r�|dkr�|}n|dkr�|}n|dkr�|}q�ntt|�j|�}	|jd�}
|dkr�t}|j}nBt}t	|t
�rt|�}n|	j|ddd|
�|	_|dkrM|j
}n�t	|t
�rkt|�}n|r�||kr�d|	j||f}|r�t|��q�t|t�|}n|	j|ddd|
�|	_
|dk	r�t	|t
�rt|�}n|r7||kr7td|	j||f��n1|rh||krhtd	|	j||f��n|	j|dd
d|
�|	_n|	jdk	r�|	j|	j�|	_n|dk	r�t	|t
�r|jd�r�t|d �d
}qd|krt|�}qt|�}n|dkrCtd|	j|f��nXt	|t�r}|dkr�td|	j|f��q�nt	|t�s�td��n|r�tdt�n||	_n|	S(NsD'min_rounds' and 'min_desired_rounds' aliases are mutually exclusivesD'max_rounds' and 'max_desired_rounds' aliases are mutually exclusiveR�RwR�s9%s: max_desired_rounds (%r) below min_desired_rounds (%r)R�s5%s: default_rounds (%r) below min_desired_rounds (%r)s5%s: default_rounds (%r) above max_desired_rounds (%r)Rqt%i����g{�G�z�?t.is%s: vary_rounds (%r) below 0is%s: vary_rounds (%r) above 1.0s vary_rounds must be int or floats\The 'vary_rounds' option is deprecated as of Passlib 1.7, and will be removed in Passlib 2.0(RgR�R�R1R�R@R�R�R{RYRR5t_norm_roundsR�RFR�RRRqt_clip_to_desired_roundstendswithtfloatR�(
R�R�R�RqR�R�R�RrRLR�R�texplicit_min_roundsR�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�6s�				
	
cC�sB|jpd}||kr|S|j}|r>||kr>|S|S(s|
        helper for :meth:`_generate_rounds` --
        clips rounds value to desired min/max set by class (if any)
        i(R�R�(R�Rrtmndtmxd((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�s	cC�s�|st�|j}d�}t|t�r�d|koDdknsOt�|jdkrtd|>}d�}nt||�}n|dkr�t|t�s�t�|||t�}|||t�}|j	|�|j	|�fS(s�
        helper for :meth:`_generate_rounds` --
        returns range for vary rounds generation.

        :returns:
            (lower, upper) limits suitable for random.randint()
        cS�s|S(N((Rstupper((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pytlinear_to_native�siitlog2cS�sO|dkrdS|r,ttj|d��Sttjtj|d���SdS(Nii(R5R4R6tceil(RsR((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�s
(
RdR�RYRtrounds_costR5R#R�R{R(R�RqR�RtlowerR((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyt_calc_vary_rounds_range�s		"
!cK�s�tt|�j|�|dk	r4|j|�}nL|jrt|j�}|j|�|ks�td|f��nt	d��||_
dS(Nsgenerated invalid rounds: %rsno rounds specified(R�R1R�Rgt
_parse_roundsR�t_generate_roundsR�RdR�Rr(R�RrRL((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��s	+cC�s
|j|�S(N(R�(R�Rr((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR
�sRrc	C�s%t|||j|jd|d|�S(s�
        helper for normalizing rounds value.

        :arg rounds:
            an integer cost parameter.

        :param relaxed:
            if ``True`` (the default), issues PasslibHashWarning is rounds are outside allowed range.
            if ``False``, raises a ValueError instead.

        :param param:
            optional name of parameter to insert into error/warning messages.

        :raises TypeError:
            * if ``use_defaults=False`` and no rounds is specified
            * if rounds is not an integer.

        :raises ValueError:

            * if rounds is ``None`` and class does not specify a value for
              :attr:`default_rounds`.
            * if ``relaxed=False`` and rounds is outside bounds of
              :attr:`min_rounds` and :attr:`max_rounds` (if ``relaxed=True``,
              the rounds value will be clamped, and a warning issued).

        :returns:
            normalized rounds value
        RwR�(R�R�R�(R�RrR�Rw((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��scC�s�|j}|dkr.td|jf��n|jr�|j|�\}}||koc|knsnt�||kr�tj||�}q�n|S(s�
        internal helper for :meth:`_norm_rounds` --
        returns default rounds value, incorporating vary_rounds,
        and any other limitations hash may place on rounds parameter.
        s,%s rounds value must be specified explicitlyN(	RqRgR�RFR�RRdR
trandint(R�RrRR((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyRs		"cK�sZ|j}|r"|j|kr"tS|j}|rD|j|krDtStt|�j|�S(sR
        mark hash as needing update if rounds is outside desired bounds.
        (R�RrR{R�R�R1R�(R�RLR�R�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�)s		g�������?cK�stt|�j|�}|jdkr{ddl}|dkrK|j}ntdtd|j	||d���|d<n|S(s8[experimental method] return info about bitsizes of hashRi����NiiiRr(
R�R1R�R
R4RgRqRBR5R6(R�RrR�RLR�R4((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�8s0N(smin_desired_roundssmax_desired_roundss
min_roundss
max_roundssdefault_roundssvary_rounds(R;R�R�R�RgR�R
tusing_rounds_kwdsR�R�RqR�RrR�R�RRR�R
R�R�RR�R�(((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR1�s45
h+	 	tParallelismMixincB�sMeZdZdZedd��Zdd�Zeed��Z	d�Z
RS(sH
    mixin which provides common behavior for 'parallelism' setting
    icK�sjtt|�j|�}|dk	rft|t�rBt|�}n|j|d|jd��|_	n|S(NR�(
R�RR�RgRYRR5t_norm_parallelismR@tparallelism(R�RRLR�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�js$cK�s_tt|�j|�|dkrIt||j|jdd�s[t�n|j|�|_dS(NRwR(R�RR�RgR}RRRd(R�RRL((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�vs
c	C�st||ddddd|�S(NR�iRwRR�(R�(R�RR�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�scK�s2|jt|�jkrtStt|�j|�S(sR
        mark hash as needing update if rounds is outside desired bounds.
        (RR�R{R�RR�(R�RL((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��sN(R;R�R�RR�RgR�R�R�RR�(((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyRUs
tBackendMixincB�s�eZdZd	Zd	Zd	Zd	ZeZ	e
d��Ze
dd��Ze
ded��Z
e
d��Ze
d��Ze
d��Ze
d��ZRS(
s�
    PasswordHash mixin which provides generic framework for supporting multiple backends
    within the class.

    Public API
    ----------

    .. attribute:: backends

        This attribute should be a tuple containing the names of the backends
        which are supported. Two common names are ``"os_crypt"`` (if backend
        uses :mod:`crypt`), and ``"builtin"`` (if the backend is a pure-python
        fallback).

    .. automethod:: get_backend
    .. automethod:: set_backend
    .. automethod:: has_backend

    .. warning::

        :meth:`set_backend` is intended to be called during application startup --
        it affects global state, and switching backends is not guaranteed threadsafe.

    Private API (Subclass Hooks)
    ----------------------------
    Subclasses should set the :attr:`!backends` attribute to a tuple of the backends
    they wish to support.  They should also define one method:

    .. classmethod:: _load_backend_{name}(dryrun=False)

        One copy of this method should be defined for each :samp:`name` within :attr:`!backends`.

        It will be called in order to load the backend, and should take care of whatever
        is needed to enable the backend.  This may include importing modules, running tests,
        issuing warnings, etc.

        :param name:
            [Optional] name of backend.

        :param dryrun:
            [Optional] True/False if currently performing a "dry run".

            if True, the method should perform all setup actions *except*
            switching the class over to the new backend.

        :raises passlib.exc.PasslibSecurityError:
            if the backend is available, but cannot be loaded due to a security issue.

        :returns:
            False if backend not available, True if backend loaded.

        .. warning::

            Due to the way passlib's internals are arranged,
            backends should generally store stateful data at the class level
            (not the module level), and be prepared to be called on subclasses
            which may be set to a different backend from their parent.

            (Idempotent module-level data such as lazy imports are fine).

    .. automethod:: _finalize_backend

    .. versionadded:: 1.7
    cC�s2|js+|j�|js+td��n|jS(s
        Return name of currently active backend.
        if no backend has been loaded, loads and returns name of default backend.

        :raises passlib.exc.MissingBackendError:
            if no backends are available.

        :returns:
            name of active backend
        s.set_backend() failed to load a default backend(t_BackendMixin__backendtset_backendRd(R�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pytget_backend�s	
R�cC�s@y|j|dt�tSWntjtjfk
r;tSXdS(s�
        Check if support is currently available for specified backend.

        :arg name:
            name of backend to check for.
            can be any string accepted by :meth:`set_backend`.

        :raises ValueError:
            if backend name is unknown

        :returns:
            * ``True`` if backend is available.
            * ``False`` if it's available / can't be loaded.
            * ``None`` if it's present, but won't load due to a security issue.
        tdryrunN(RR{RZRtPasslibSecurityErrorR�(R�RF((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pythas_backends
cC�s�|dkr|js*|r1||jkr1|jS|j�}||k	r\|j|d|�S|dkst|dkr9d}xo|jD]d}y|j|d|�SWq�tjk
r�q�q�tjk
r�}|dkr�|}q�q�q�Xq�W|dkr0d|j}|j	r||j	7}ntj|�}n|�n||jkr]tj
||��nt�i|j|j
f}z&||_||_
|j||�Wd|\|_|_
X|s�||_n|SWdQXdS(s
        Load specified backend.

        :arg name:
            name of backend to load, can be any of the following:

            * ``"any"`` -- use current backend if one is loaded,
              otherwise load the first available backend.

            * ``"default"`` -- use the first available backend.

            * any string in :attr:`backends`, loads specified backend.

        :param dryrun:
            If True, this perform all setup actions *except* switching over to the new backend.
            (this flag is used to implement :meth:`has_backend`).

            .. versionadded:: 1.7

        :raises ValueError:
            If backend name is unknown.

        :raises passlib.exc.MissingBackendError:
            If specific backend is missing;
            or in the case of ``"any"`` / ``"default"``, if *no* backends are available.

        :raises passlib.exc.PasslibSecurityError:

            If ``"any"`` or ``"default"`` was specified,
            but the only backend available has a PasslibSecurityError.
        R�RRvs%s: no backends availableN(Rt_get_backend_ownerRRgtbackendsRZRRRFt_no_backend_suggestiontUnknownBackendErrort
_backend_lockt_pending_backendt_pending_dry_runt_set_backend(R�RFRtownert
default_errorR�R�R�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR"sD"*	
				cC�s|S(s�
        return class that set_backend() should actually be modifying.
        for SubclassBackendMixin, this may not always be the class that was invoked.
        ((R�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyRvscC�s�|j|�}i}t|d�r1||d<nt|d�rM||d<n||�}|tkr�tjd|j|f��n"|tk	r�td|f��ndS(s%
        Internal method invoked by :meth:`set_backend`.
        handles actual loading of specified backend.

        global _backend_lock will be held for duration of this method,
        and _pending_dry_run & _pending_backend will also be set.

        should return True / False.
        RFRs%s: backend not available: %ss-backend loaders must return True or False: %rN(t_get_backend_loaderRR�RZRRFR{Rd(R�RFRtloaderRLtok((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR"~s

	cC�std��dS(sf
        Hook called to get the specified backend's loader.
        Should return callable which optionally takes ``"name"`` and/or
        ``"dryrun"`` keywords.

        Callable should return True if backend initialized successfully.

        If backend can't be loaded, callable should return False
        OR raise MissingBackendError directly.
        simplement in subclassN(R�(R�RF((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR%�scC�sU|jr(td|j|jf��n|j�|jsQtd|j��ndS(sW
        helper for subclasses to create stub methods which auto-load backend.
        s7%s: _finalize_backend(%r) failed to replace lazy loaders2%s: set_backend() failed to load a default backendN(RRdRFR(R�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyt_stub_requires_backend�s	
	N(R;R�R�RgRRRR R�R!R�RRRRR"R%R((((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�s@StSubclassBackendMixincB�sGeZdZeZdZed��Zed��Z	ed��Z
RS(s�
    variant of BackendMixin which allows backends to be implemented
    as separate mixin classes, and dynamically switches them out.

    backend classes should implement a _load_backend() classmethod,
    which will be invoked with an optional 'dryrun' keyword,
    and should return True or False.

    _load_backend() will be invoked with ``cls`` equal to the mixin,
    *not* the overall class.

    .. versionadded:: 1.7
    cC�sR|jstd��nx'|jD]}|jjd�r"|Sq"Wtd��dS(s�
        return base class that we're actually switching backends on
        (needed in since backends frequently modify class attrs,
        and .set_backend may be called from a subclass).
        s_backend_mixin_target not sett_backend_mixin_targets5expected to find class w/ '_backend_mixin_target' setN(R*Rdt__mro__t__dict__R@(R�Ru((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�s	cC�s�tt|�j||�||j�ks7td��|j}|sRtd��||}t|t�swtd��t|d|d|j�dt	dtd|�dS(	Ns(_finalize_backend() not invoked on owners _backend_mixin_map not specifiedsinvalid mixin classtaddtremovetappendtbeforeR(
R�R)R"RRdt_backend_mixin_mapt
issubclassRtvaluesR{(R�RFRt	mixin_mapt	mixin_cls((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR"�s	
	cC�s#|jstd��|j|jS(Ns _backend_mixin_map not specified(R1Rdt_load_backend_mixin(R�RF((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR%�sN(R;R�R�R�R*RgR1R�RR"R%(((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR)�s
	cB�sMeZdZd�Zd�Zed��Zed��Zed��ZRS(s�
    GenericHandler mixin which provides selecting from multiple backends.

    .. todo::

        finish documenting this class's usage

    For hashes which need to select from multiple backends,
    depending on the host environment, this class
    offers a way to specify alternate :meth:`_calc_checksum` methods,
    and will dynamically chose the best one at runtime.

    .. versionchanged:: 1.7

        This class now derives from :class:`BackendMixin`, which abstracts
        out a more generic framework for supporting multiple backends.
        The public api (:meth:`!get_backend`, :meth:`!has_backend`, :meth:`!set_backend`)
        is roughly the same.

    Private API (Subclass Hooks)
    ----------------------------
    As of version 1.7, classes should implement :meth:`!_load_backend_{name}`, per
    :class:`BackendMixin`.  This hook should invoke :meth:`!_set_calc_checksum_backcend`
    to install it's backend method.

    .. deprecated:: 1.7

        The following api is deprecated, and will be removed in Passlib 2.0:

    .. attribute:: _has_backend_{name}

        private class attribute checked by :meth:`has_backend` to see if a
        specific backend is available, it should be either ``True``
        or ``False``. One of these should be provided by
        the subclass for each backend listed in :attr:`backends`.

    .. classmethod:: _calc_checksum_{name}

        private class method that should implement :meth:`_calc_checksum`
        for a given backend. it will only be called if the backend has
        been selected by :meth:`set_backend`. One of these should be provided
        by the subclass for each backend listed in :attr:`backends`.
    cC�s
|j|�S(s$wrapper for backend, for common code(t_calc_checksum_backend(R�RX((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�4	scC�s|j�|j|�S(s�
        stub for _calc_checksum_backend() --
        should load backend if one hasn't been loaded;
        if one has been loaded, this method should have been monkeypatched by _finalize_backend().
        (R(R7(R�RX((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR7;	s
c�skt�d�d�}|dkr7��fd�}n0t�d��sgtd�j��f��|S(sp
        subclassed to support legacy 1.6 HasManyBackends api.
        (will be removed in passlib 2.0)
        t_load_backend_c�s
�j��S(N(t%_HasManyBackends__load_legacy_backend((R�RF(s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR&Q	st
_has_backend_s?%s: can't specify both ._load_backend_%s() and ._has_backend_%sN(R�RgthasattrRdRF(R�RFR&((R�RFs:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR%G	scC�sbt|d|�}td|j||ft�|rZt|d|�}|j|�tStSdS(NR:s�%s: support for ._has_backend_%s is deprecated as of Passlib 1.7, and will be removed in Passlib 1.9/2.0, please implement ._load_backend_%s() insteadt_calc_checksum_(R�RRFRKt_set_calc_checksum_backendR{R�(R�RFRstfunc((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyt__load_legacy_backend[	s
cC�s_|j}|std��t|�sFtd|j||f��n|js[||_ndS(sl
        helper used by subclasses to validate & set backend-specific
        calc checksum helper.
        s*should only be called during set_backend()s,%s: backend %r returned invalid callable: %rN(R RdtcallabletRuntimeErrorRFR!R7(R�R>tbackend((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR=j	s		(	R;R�R�R�R7R�R%R9R=(((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR2	s+		cB�s[eZdZd2Zed�ed�ed3d3d�Zd3Zd3Z	d�Z
d�Zee�Z
eZed��ZeZed��Zd4Zd�Zd�Zd �Zd!�Zd"�Zd#�Zd3Zd$�Zd%�Zd&�Zed'd(d)d*�d+��Zed'd(d)d*�d,��Zed'd(d)d*d-d.�d/��Z d0�Z!d1�Z"RS(5sUwraps another handler, adding a constant prefix.

    instances of this class wrap another password hash handler,
    altering the constant prefix that's prepended to the wrapped
    handlers' hashes.

    this is used mainly by the :doc:`ldap crypt <passlib.hash.ldap_crypt>` handlers;
    such as :class:`~passlib.hash.ldap_md5_crypt` which wraps :class:`~passlib.hash.md5_crypt` and adds a ``{CRYPT}`` prefix.

    usage::

        myhandler = PrefixWrapper("myhandler", "md5_crypt", prefix="$mh$", orig_prefix="$1$")

    :param name: name to assign to handler
    :param wrapped: handler object or name of registered handler
    :param prefix: identifying prefix to prepend to all hashes
    :param orig_prefix: prefix to strip (defaults to '').
    :param lazy: if True and wrapped handler is specified by name, don't look it up until needed.
    R<cC�s@||_t|t�r*|jd�}n||_t|t�rT|jd�}n||_|ro||_nt|d�r�|j|�n||_	|s�|j
�n|dk	r<|tkr�|r�|}q�t
d��nt|t�r|jd�}n|t|� |t|� kr0t
d��n||_ndS(NRcRFsno prefix specifiedsident must agree with prefix(RFRYR_R`Ritorig_prefixR�R;t_set_wrappedt
_wrapped_namet_get_wrappedRgR{R�R7t_ident(R�RFtwrappedRiRCtlazytdocRy((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��	s0				
	 cC�sBd|jkr5|jr5td|jftj�n||_dS(NRyskPrefixWrapper: 'orig_prefix' option may not work correctly for handlers which have multiple identifiers: %r(R�RCRRFRZtPasslibRuntimeWarningt_wrapped_handler(R�RH((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyRD�	scC�s8|j}|dkr4t|j�}|j|�n|S(N(RLRgRRERD(R�RH((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyRF�	s
	cC�sp|j}|tkrld}|js`|j}t|dd�}|dk	r`|j|�}q`n||_n|S(NRy(RGR�RgRCRHR�t
_wrap_hash(R�RsRHRy((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyRy�	s			c�sw�j}|tkrsd}�jsg�j}t|dd�}|rgt�fd�|D��}qgn|�_n|S(NR�c3�s|]}�j|�VqdS(N(RM(RORy(R�(s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pys	<genexpr>�	s(t
_ident_valuesR�RgRCRHR�ttuple(R�RsRHtidents((R�s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR��	s			"R�RSRqR�R�R
R�R�R�R�R�R�R�R�RRRRtis_disabledR�R�R�R�cC�s{t|jp|j�g}|jr;|jd|j�n|jr[|jd|j�ndj|�}d|j|fS(Ns	prefix=%rsorig_prefix=%rs, sPrefixWrapper(%r, %s)(treprRERLRiR/RCtjoinRF(R�targs((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyt__repr__
s		c�sXtt|j��}|j|j�|j�|j�fd�|jD��t|�S(Nc3�s$|]}t�|�r|VqdS(N(R;(ROtattr(RH(s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pys	<genexpr>
s(RRtdirR�tupdateR,RHt_proxy_attrsRT(R�tattrs((RHs:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyt__dir__
s	cC�s6||jkrt|j|�Std|f��dS(sFproxy most attributes from wrapped class (e.g. rounds, salt size, etc)smissing attribute: %rN(RYR�RHR�(R�RV((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyt__getattr__
scC�sZ||jkrG|jrG|j}t||�rGt|||�dSntj|||�S(N(RYt
_derived_fromRHR;tsetattrR�t__setattr__(R�RVRsRH((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR_
s	cC�s?|j}|j|�s*tj|��n|j|t|�S(s4given hash belonging to wrapper, return orig version(RiRARZReRCR7(R�R^Ri((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyt_unwrap_hash+
s	cC�sot|t�r!|jd�}n|j}|j|�sNtj|j��n|j|t	|�}t
|�S(s0given orig hash; return one belonging to wrapperRc(RYR_R`RCRARZReRHRiR7R(R�R^RCRH((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyRM4
s	cK�s�|jj|�}||jk	s't�t|j|d|jd|j�}||_x*|jD]}t	||t
||��q^W|S(NRiRC(RHR�RdR3RFRiRCR]t_using_clone_attrsR^R�(R�RLR�twrapperRV((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�C
s$	cK�s"|j|�}|jj||�S(N(R`RHR�(R�R^RL((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�N
scC�sAt|�}|j|j�s"tS|j|�}|jj|�S(N(RbRARiR�R`RHR�(R�R^((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�R
s
R�s1.7R�s2.0cK�s:|jj|�}|dkr-td��n|j|�S(Ns+.genconfig() must return a string, not None(RHR�RgRARM(R�RLR�((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�Y
scK�sO|dk	r0t|dd�}|j|�}n|j|jj|||��S(NRcsconfig/hash(RgR
R`RMRHR�(R�RXR�RL((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�`
streplacements.hash()cK�s|j||�S(N(R^(R�RXRL((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pytencrypth
scK�s|j|jj||��S(N(RMRHR^(R�RXRL((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR^l
scK�s7t|dd�}|j|�}|jj|||�S(NRcR^(R
R`RHR�(R�RXR^RL((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR�o
s(N(ssetting_kwdsscontext_kwdssdefault_roundss
min_roundss
max_roundssrounds_costsmin_desired_roundssmax_desired_roundssvary_roundssdefault_salt_sizes
min_salt_sizes
max_salt_sizes
salt_charssdefault_salt_charssbackendsshas_backendsget_backendsset_backendRQs
truncate_sizestruncate_errorstruncate_verify_rejects_salt_is_bytes(#R;R�R�RaRR�RgR�RERLRDRFR�RHRGRyRNR�RYRUR[R\R_R`RMR]R�R�R�R%R�R�RdR^R�(((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyR3�	sJ					
		
			
			$	(cR�t
__future__RR=tloggingt	getLoggerR;R6R4t	threadingtwarningsRtpasslib.excRZtpasslib.ifctifcRRRRtpasslib.registryRt
passlib.utilsRRR	R
RRR
RRRRR�RRRRRRRtpasslib.utils.compatRRRRRRRR R!R"R#tpasslib.utils.decorR$R%t__all__t	H64_CHARSt	B64_CHARStPADDED_B64_CHARStUC_HEX_CHARStLC_HEX_CHARSR:RGRMRUt_UDOLLARRnR]RbRgR&R'RxR(R)R}R�R�R�R�R*R+R�R,R-R.R/R0R1RtRLockRRR)R2R�R3(((s:/usr/lib/python2.7/site-packages/passlib/utils/handlers.pyt<module>s�L4R						J!	&!*��Z	'��&�xH�N|