Current File : //usr/lib/python2.7/site-packages/passlib/handlers/scram.pyc
�
�
5Xc@s�dZddlZeje�ZddlmZmZmZm	Z	ddl
mZmZddl
mZmZmZmZddlmZmZddljjZdgZdejejejejfd��YZdS(	s:passlib.handlers.scram - hash for SCRAM credential storagei����N(tconsteqtsaslprept
to_native_strt
splitcomma(tab64_decodetab64_encode(t
bascii_to_strt	iteritemstutnative_string_types(tpbkdf2_hmactnorm_hash_nametscramcBseZdZdZd Zed�ZdZdZd	Z	d
Z
d"Zd
ZdddgZ
dddddgZd#Zed��Zedd��Zed��Zed��Zd�Zed#d#d��Zd#d�Zed�Zed��Zd�Zd#d�Zeed��ZRS($sZThis class provides a format for storing SCRAM passwords, and follows
    the :ref:`password-hash-api`.

    It supports a variable-length salt, and a variable number of rounds.

    The :meth:`~passlib.ifc.PasswordHash.using` method accepts the following optional keywords:

    :type salt: bytes
    :param salt:
        Optional salt bytes.
        If specified, the length must be between 0-1024 bytes.
        If not specified, a 12 byte salt will be autogenerated
        (this is recommended).

    :type salt_size: int
    :param salt_size:
        Optional number of bytes to use when autogenerating new salts.
        Defaults to 12 bytes, but can be any value between 0 and 1024.

    :type rounds: int
    :param rounds:
        Optional number of rounds to use.
        Defaults to 100000, but must be within ``range(1,1<<32)``.

    :type algs: list of strings
    :param algs:
        Specify list of digest algorithms to use.

        By default each scram hash will contain digests for SHA-1,
        SHA-256, and SHA-512. This can be overridden by specify either be a
        list such as ``["sha-1", "sha-256"]``, or a comma-separated string
        such as ``"sha-1, sha-256"``. Names are case insensitive, and may
        use :mod:`!hashlib` or `IANA <http://www.iana.org/assignments/hash-function-text-names>`_
        hash names.

    :type relaxed: bool
    :param relaxed:
        By default, providing an invalid value for one of the other
        keywords will result in a :exc:`ValueError`. If ``relaxed=True``,
        and the error can be corrected, a :exc:`~passlib.exc.PasslibHashWarning`
        will be issued instead. Correctable errors include ``rounds``
        that are too small or too large, and ``salt`` strings that are too long.

        .. versionadded:: 1.6

    In addition to the standard :ref:`password-hash-api` methods,
    this class also provides the following methods for manipulating Passlib
    scram hashes in ways useful for pluging into a SCRAM protocol stack:

    .. automethod:: extract_digest_info
    .. automethod:: extract_digest_algs
    .. automethod:: derive_digest
    Rtsaltt	salt_sizetroundstalgss$scram$iii��iii tlinearssha-1ssha-256ssha-512ssha-224ssha-384cCsSt|d�}|j|�}|j}|s<td��n|j|j||fS(s�return (salt, rounds, digest) for specific hash algorithm.

        :type hash: str
        :arg hash:
            :class:`!scram` hash stored for desired user

        :type alg: str
        :arg alg:
            Name of digest algorithm (e.g. ``"sha-1"``) requested by client.

            This value is run through :func:`~passlib.crypto.digest.norm_hash_name`,
            so it is case-insensitive, and can be the raw SCRAM
            mechanism name (e.g. ``"SCRAM-SHA-1"``), the IANA name,
            or the hashlib name.

        :raises KeyError:
            If the hash does not contain an entry for the requested digest
            algorithm.

        :returns:
            A tuple containing ``(salt, rounds, digest)``,
            where *digest* matches the raw bytes returned by
            SCRAM's :func:`Hi` function for the stored password,
            the provided *salt*, and the iteration count (*rounds*).
            *salt* and *digest* are both raw (unencoded) bytes.
        tianasscram hash contains no digests(Rtfrom_stringtchecksumt
ValueErrorR
R(tclsthashtalgtselftchkmap((s:/usr/lib/python2.7/site-packages/passlib/handlers/scram.pytextract_digest_info|s	RcCsF|j|�j}|dkr"|Sg|D]}t||�^q)SdS(s�Return names of all algorithms stored in a given hash.

        :type hash: str
        :arg hash:
            The :class:`!scram` hash to parse

        :type format: str
        :param format:
            This changes the naming convention used by the
            returned algorithm names. By default the names
            are IANA-compatible; possible values are ``"iana"`` or ``"hashlib"``.

        :returns:
            Returns a list of digest algorithms; e.g. ``["sha-1"]``
        RN(RRR(RRtformatRR((s:/usr/lib/python2.7/site-packages/passlib/handlers/scram.pytextract_digest_algs�scCs:t|t�r!|jd�}nt|t|�||�S(s;helper to create SaltedPassword digest for SCRAM.

        This performs the step in the SCRAM protocol described as::

            SaltedPassword  := Hi(Normalize(password), salt, i)

        :type password: unicode or utf-8 bytes
        :arg password: password to run through digest

        :type salt: bytes
        :arg salt: raw salt data

        :type rounds: int
        :arg rounds: number of iterations.

        :type alg: str
        :arg alg: name of digest to use (e.g. ``"sha-1"``).

        :returns:
            raw bytes of ``SaltedPassword``
        sutf-8(t
isinstancetbytestdecodeR
R(RtpasswordR
RR((s:/usr/lib/python2.7/site-packages/passlib/handlers/scram.pyt
derive_digest�sc
	Cs�t|dd�}|jd�s6tjj|��n|djd�}t|�dkrptjj|��n|\}}}t|�}|t	|�kr�tjj|��nyt
|jd��}Wn#tk
r�tjj|��nX|stjj|��n�d|kr�d}i}	x~|jd�D]^}
|
jd�\}}yt
|jd��|	|<Wq4tk
r�tjj|��q4Xq4Wn|}d}	|d	|d
|d|	d|�S(
NtasciiRs$scram$it$it=t,RR
RR(Rt
startswithtuhtexctInvalidHashErrortsplittlentMalformedHashErrortinttstrRtencodet	TypeErrortNone(
RRtpartst
rounds_strtsalt_strtchk_strRR
RRtpairRtdigest((s:/usr/lib/python2.7/site-packages/passlib/handlers/scram.pyR�s@

csTtt|j��}|j�dj�fd�|jD��}d|j||fS(NR&c3s/|]%}d|tt�|��fVqdS(s%s=%sN(RR(t.0R(R(s:/usr/lib/python2.7/site-packages/passlib/handlers/scram.pys	<genexpr>ss$scram$%d$%s$%s(RRR
RtjoinRR(RR
R6((Rs:/usr/lib/python2.7/site-packages/passlib/handlers/scram.pyt	to_string
s	cKsd|dk	r'|dkst�|}ntt|�j|�}|dk	r`|j|�|_n|S(N(R2tAssertionErrortsuperRtusingt
_norm_algstdefault_algs(RR@Rtkwdstsubcls((s:/usr/lib/python2.7/site-packages/passlib/handlers/scram.pyR>s	cKs�tt|�j|�|j}|dk	rX|dk	rFtd��n|j|�}ns|dk	r||j|j��}nO|jr�t	|j
�}|j|�|ks�td|f��ntd��||_
dS(Ns+checksum & algs kwds are mutually exclusivesinvalid default algs: %rsno algs list specified(R=Rt__init__RR2tRuntimeErrorR?tkeystuse_defaultstlistR@R<R1R(RRRAt
digest_map((s:/usr/lib/python2.7/site-packages/passlib/handlers/scram.pyRC+s		+cCs�t|t�s*tjj|dd��nx�t|�D]�\}}|t|d�krntd|f��nt|�dkr�td|f��nt|t	�s7tjj|dd��q7q7Wd	|kr�td
��n|S(NtdictRRs*malformed algorithm name in scram hash: %ri	s0SCRAM limits algorithm names to 9 characters: %rs	raw bytestdigestsssha-1s-sha-1 must be in algorithm list of scram hash(
RRIR(R)tExpectedTypeErrorRRRR,R(RRtrelaxedRR8((s:/usr/lib/python2.7/site-packages/passlib/handlers/scram.pyt_norm_checksum>scCsxt|t�rt|�}ntd�|D��}td�|D��rYtd��nd|krttd��n|S(snormalize algs parametercss|]}t|d�VqdS(RN(R(R9R((s:/usr/lib/python2.7/site-packages/passlib/handlers/scram.pys	<genexpr>Uscss!|]}t|�dkVqdS(i	N(R,(R9R((s:/usr/lib/python2.7/site-packages/passlib/handlers/scram.pys	<genexpr>Vss-SCRAM limits alg names to max of 9 charactersssha-1s-sha-1 must be in algorithm list of scram hash(RR	RtsortedtanyR(RR((s:/usr/lib/python2.7/site-packages/passlib/handlers/scram.pyR?PscKs5t|j�j|j�stStt|�j|�S(N(tsetRt
issupersetR@tTrueR=Rt_calc_needs_update(RRA((s:/usr/lib/python2.7/site-packages/passlib/handlers/scram.pyRS`scs^|j�|j�|j�|r4����|�St����fd�|jD��SdS(Nc3s*|] }|����|�fVqdS(N((R9R(RRR
tsecret(s:/usr/lib/python2.7/site-packages/passlib/handlers/scram.pys	<genexpr>ws(RR
R"RIR(RRTR((RRR
RTs:/usr/lib/python2.7/site-packages/passlib/handlers/scram.pyt_calc_checksumms			cCs\tj|�|j|�}|j}|sJtd|j|jf��n|r	t}}x�t|�D]|\}}	|j||�}
t	|	�t	|
�kr�td|t	|	�t	|
�f��nt
|
|	�r�t}qgt}qgW|r|rtd��qX|SnOx@|jD]5}||kr|j||�}
t
|
||�SqWt
d��dS(Ns.expected %s hash, got %s config string insteads+mis-sized %s digest in scram hash: %r != %rs4scram hash verified inconsistently, may be corruptedssha-1 digest not found!(R(tvalidate_secretRRRtnametFalseRRUR,RRRt_verify_algsR<(RRTRtfullRRtcorrecttfailedRR8tother((s:/usr/lib/python2.7/site-packages/passlib/handlers/scram.pytverify{s0
	
"	
(ssaltRsroundssalgsII����N(t__name__t
__module__t__doc__RWtsetting_kwdsRtidenttdefault_salt_sizet
max_salt_sizetdefault_roundst
min_roundst
max_roundstrounds_costR@RYR2RtclassmethodRRR"RR;R>RCRXRMR?RSRUR^(((s:/usr/lib/python2.7/site-packages/passlib/handlers/scram.pyRs85
&!0		
(Ratloggingt	getLoggerR_tlogt
passlib.utilsRRRRtpasslib.utils.binaryRRtpasslib.utils.compatRRRR	tpasslib.crypto.digestR
Rtpasslib.utils.handlerstutilsthandlersR(t__all__t	HasRoundst
HasRawSalttHasRawChecksumtGenericHandlerR(((s:/usr/lib/python2.7/site-packages/passlib/handlers/scram.pyt<module>s""