ó
~9Vc           @   s™  d  Z  d d l Z d d l Z d d l Z d d l Z d d l Z d d l m Z d d l m	 Z	 d d l
 m Z d d l m Z d d l m Z m Z m Z m Z m Z m Z m Z d Z d	 Z e d
 ƒ j Z e e d d ƒ Z e	 ƒ  Z e d „  e j j  e j j! g Dƒ ƒ Z" d „  Z# e# ƒ  Z$ e d d d „ Z% e& e d ƒ Z' e d d d „ Z( d „  Z) d „  Z* d „  Z+ d d d „ Z, d „  Z- d „  Z. d S(   sñ   
    werkzeug.security
    ~~~~~~~~~~~~~~~~~

    Security related helpers such as secure password hashing tools.

    :copyright: (c) 2014 by the Werkzeug Team, see AUTHORS for more details.
    :license: BSD, see LICENSE for more details.
iÿÿÿÿN(   t   Struct(   t   SystemRandom(   t   xor(   t   starmap(   t
   range_typet   PY2t	   text_typet   izipt   to_bytest   string_typest	   to_nativet>   abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789iè  s   >It   compare_digestc         c   s!   |  ] } | d k r | Vq d S(   t   /N(   NR   (   t   None(   t   .0t   sep(    (    s3   /tmp/pip-build-zHWFj_/Werkzeug/werkzeug/security.pys	   <genexpr>    s    c          C   sm   t  t d d  ƒ }  |  d  k r' d }  n  i  } x9 |  D]1 } t  t | d  ƒ } | d  k	 r4 | | | <q4 q4 W| S(	   Nt
   algorithmst   md5t   sha1t   sha224t   sha256t   sha384t   sha512(   s   md5s   sha1s   sha224s   sha256s   sha384s   sha512(   t   getattrt   hashlibR   (   t   algost   rvt   algot   func(    (    s3   /tmp/pip-build-zHWFj_/Werkzeug/werkzeug/security.pyt   _find_hashlib_algorithms$   s    	c         C   s.   t  |  | | | | ƒ } t t j | d ƒ ƒ S(   s'  Like :func:`pbkdf2_bin`, but returns a hex-encoded string.

    .. versionadded:: 0.9

    :param data: the data to derive.
    :param salt: the salt for the derivation.
    :param iterations: the number of iterations.
    :param keylen: the length of the resulting key.  If not provided,
                   the digest size will be used.
    :param hashfunc: the hash function to use.  This can either be the
                     string name of a known hash function, or a function
                     from the hashlib module.  Defaults to sha1.
    t	   hex_codec(   t
   pbkdf2_binR
   t   codecst   encode(   t   datat   saltt
   iterationst   keylent   hashfuncR   (    (    s3   /tmp/pip-build-zHWFj_/Werkzeug/werkzeug/security.pyt
   pbkdf2_hex1   s    t   pbkdf2_hmacc      	   C   su  t  | t ƒ r t | } n | s. t j } n  t |  ƒ }  t | ƒ } t r’ | ƒ  } t | d ƒ r’ | j t k r’ t j	 | j |  | | | ƒ Sn  t
 j |  d | ƒ } | s¹ | j } n  | d „ } t ƒ  } x– t d | | j d ƒ D]x }	 | | t |	 ƒ ƒ }
 } xH t | d ƒ D]6 } | t | ƒ ƒ } t t t t |
 | ƒ ƒ ƒ }
 qW| j |
 ƒ që Wt | |  ƒ S(   sî  Returns a binary digest for the PBKDF2 hash algorithm of `data`
    with the given `salt`. It iterates `iterations` times and produces a
    key of `keylen` bytes. By default, SHA-1 is used as hash function;
    a different hashlib `hashfunc` can be provided.

    .. versionadded:: 0.9

    :param data: the data to derive.
    :param salt: the salt for the derivation.
    :param iterations: the number of iterations.
    :param keylen: the length of the resulting key.  If not provided
                   the digest size will be used.
    :param hashfunc: the hash function to use.  This can either be the
                     string name of a known hash function or a function
                     from the hashlib module.  Defaults to sha1.
    t   namec         S   s)   | j  ƒ  } | j |  ƒ t | j ƒ  ƒ S(   N(   t   copyt   updatet	   bytearrayt   digest(   t   xt   mact   h(    (    s3   /tmp/pip-build-zHWFj_/Werkzeug/werkzeug/security.pyt   _pseudorandomm   s    i   N(   t
   isinstanceR	   t   _hash_funcsR   R   R   t   _has_native_pbkdf2t   hasattrR*   R)   t   hmact   HMACR   t   digest_sizeR-   R   t	   _pack_intt   bytesR   R   R   t   extend(   R#   R$   R%   R&   R'   t
   _test_hashR0   R2   t   buft   blockR   t   ut   i(    (    s3   /tmp/pip-build-zHWFj_/Werkzeug/werkzeug/security.pyR    G   s2    		
	#"c         C   sø   t  |  t ƒ r! |  j d ƒ }  n  t  | t ƒ rB | j d ƒ } n  t d k	 r[ t |  | ƒ St |  ƒ t | ƒ k rw t Sd } t rÀ xh t |  | ƒ D]& \ } } | t	 | ƒ t	 | ƒ AO} q“ Wn. x+ t |  | ƒ D] \ } } | | | AO} qÐ W| d k S(   sö   This function compares strings in somewhat constant time.  This
    requires that the length of at least one string is known in advance.

    Returns `True` if the two strings are equal, or `False` if they are not.

    .. versionadded:: 0.7
    s   utf-8i    N(
   R3   R   R"   t   _builtin_safe_str_cmpR   t   lent   FalseR   R   t   ord(   t   at   bR   R/   t   y(    (    s3   /tmp/pip-build-zHWFj_/Werkzeug/werkzeug/security.pyt   safe_str_cmp{   s    !c         C   s8   |  d k r t  d ƒ ‚ n  d j d „  t |  ƒ Dƒ ƒ S(   sA   Generate a random string of SALT_CHARS with specified ``length``.i    s   Salt length must be positivet    c         s   s   |  ] } t  j t ƒ Vq d  S(   N(   t   _sys_rngt   choicet
   SALT_CHARS(   R   t   _(    (    s3   /tmp/pip-build-zHWFj_/Werkzeug/werkzeug/security.pys	   <genexpr>   s    (   t
   ValueErrort   joinR   (   t   length(    (    s3   /tmp/pip-build-zHWFj_/Werkzeug/werkzeug/security.pyt   gen_salt™   s    c   
   	   C   s¥  |  d k r | |  f St  | t ƒ r7 | j d ƒ } n  |  j d ƒ rÄ |  d j d ƒ } t | ƒ d k rz t d ƒ ‚ n  | j d	 ƒ }  | r¥ t | d	 pŸ d	 ƒ p¨ t	 } t
 } d
 |  | f } n t } |  } t j |  ƒ } | d k rþ t d |  ƒ ‚ n  | r4| st d ƒ ‚ n  t | | | d | ƒ} ng | ryt  | t ƒ r[| j d ƒ } n  t j | | | ƒ j ƒ  } n" | ƒ  }	 |	 j | ƒ |	 j ƒ  } | | f S(   s   Internal password hash helper.  Supports plaintext without salt,
    unsalted and salted passwords.  In case salted passwords are used
    hmac is used.
    t   plains   utf-8s   pbkdf2:i   t   :i   i   s&   Invalid number of arguments for PBKDF2i    s   pbkdf2:%s:%ds   invalid method %rs   Salt is required for PBKDF2R'   (   i   i   N(   R3   R   R"   t
   startswitht   splitRC   RO   t   popt   intt   DEFAULT_PBKDF2_ITERATIONSt   TrueRD   R4   t   getR   t	   TypeErrorR(   R7   R8   t	   hexdigestR,   (
   t   methodR$   t   passwordt   argsR%   t	   is_pbkdf2t   actual_methodt	   hash_funcR   R1   (    (    s3   /tmp/pip-build-zHWFj_/Werkzeug/werkzeug/security.pyt   _hash_internal    s<    
"	s   pbkdf2:sha1i   c         C   sG   | d k r t  | ƒ p d } t | | |  ƒ \ } } d | | | f S(   sð  Hash a password with the given method and salt with with a string of
    the given length.  The format of the string returned includes the method
    that was used so that :func:`check_password_hash` can check the hash.

    The format for the hashed string looks like this::

        method$salt$hash

    This method can **not** generate unsalted passwords but it is possible
    to set the method to plain to enforce plaintext passwords.  If a salt
    is used, hmac is used internally to salt the password.

    If PBKDF2 is wanted it can be enabled by setting the method to
    ``pbkdf2:method:iterations`` where iterations is optional::

        pbkdf2:sha1:2000$salt$hash
        pbkdf2:sha1$salt$hash

    :param password: the password to hash.
    :param method: the hash method to use (one that hashlib supports). Can
                   optionally be in the format ``pbkdf2:<method>[:iterations]``
                   to enable PBKDF2.
    :param salt_length: the length of the salt in letters.
    RS   RJ   s   %s$%s$%s(   RR   Rd   (   R_   R^   t   salt_lengthR$   R1   Rb   (    (    s3   /tmp/pip-build-zHWFj_/Werkzeug/werkzeug/security.pyt   generate_password_hashË   s    c         C   sQ   |  j  d ƒ d k  r t S|  j d d ƒ \ } } } t t | | | ƒ d | ƒ S(   sÉ  check a password against a given salted and hashed password value.
    In order to support unsalted legacy passwords this method supports
    plain text passwords, md5 and sha1 hashes (both salted and unsalted).

    Returns `True` if the password matched, `False` otherwise.

    :param pwhash: a hashed string like returned by
                   :func:`generate_password_hash`.
    :param password: the plaintext password to compare against the hash.
    t   $i   i    (   t   countRD   RV   RI   Rd   (   t   pwhashR_   R^   R$   t   hashval(    (    s3   /tmp/pip-build-zHWFj_/Werkzeug/werkzeug/security.pyt   check_password_hashé   s    c         C   sh   t  j | ƒ } x t D] } | | k r d Sq Wt j j | ƒ sQ | j d ƒ rU d St j j |  | ƒ S(   sÜ   Safely join `directory` and `filename`.  If this cannot be done,
    this function returns ``None``.

    :param directory: the base directory.
    :param filename: the untrusted filename relative to that directory.
    s   ../N(	   t	   posixpatht   normpatht   _os_alt_sepsR   t   ost   patht   isabsRU   RP   (   t	   directoryt   filenameR   (    (    s3   /tmp/pip-build-zHWFj_/Werkzeug/werkzeug/security.pyt	   safe_joinú   s    !(/   t   __doc__Ro   R7   R   Rl   R!   t   structR    t   randomR   t   operatorR   t	   itertoolsR   t   werkzeug._compatR   R   R   R   R   R	   R
   RM   RY   t   packR:   R   R   RB   RK   t   listRp   R   t   altsepRn   R   R4   R(   R6   R5   R    RI   RR   Rd   Rf   Rk   Rt   (    (    (    s3   /tmp/pip-build-zHWFj_/Werkzeug/werkzeug/security.pyt   <module>
   s:   4	(	
	3			+	