ó
`¾Tc           @   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 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(    (    sW   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/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(   R   s   sha1R   R   R   R   (   t   getattrt   hashlibR   (   t   algost   rvt   algot   func(    (    sW   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/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   (    (    sW   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/werkzeug/security.pyt
   pbkdf2_hex1   s    c         C   s#  t  | t ƒ r t | } n | s. t j } n  t | ƒ } t j t |  ƒ d | ƒ } | sg | 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` time 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.
    c         S   s)   | j  ƒ  } | j |  ƒ t | j ƒ  ƒ S(   N(   t   copyt   updatet	   bytearrayt   digest(   t   xt   mact   h(    (    sW   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/werkzeug/security.pyt   _pseudorandom^   s    i   N(   t
   isinstanceR	   t   _hash_funcsR   R   R   t   hmact   HMACR   t   digest_sizeR+   R   t	   _pack_intt   bytesR   R   R   t   extend(   R#   R$   R%   R&   R'   R.   R0   t   buft   blockR   t   ut   i(    (    sW   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/werkzeug/security.pyR    D   s"    	#"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(
   R1   R   R"   t   _builtin_safe_str_cmpR   t   lent   FalseR   R   t   ord(   t   at   bR   R-   t   y(    (    sW   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/werkzeug/security.pyt   safe_str_cmpl   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   requested salt of length <= 0t    c         s   s   |  ] } t  j t ƒ Vq d  S(   N(   t   _sys_rngt   choicet
   SALT_CHARS(   R   t   _(    (    sW   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/werkzeug/security.pys	   <genexpr>Ž   s    (   t
   ValueErrort   joinR   (   t   length(    (    sW   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/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(   R1   R   R"   t
   startswitht   splitR>   RJ   t   popt   intt   DEFAULT_PBKDF2_ITERATIONSt   TrueR?   R2   t   getR   t	   TypeErrorR(   R3   R4   t	   hexdigestR*   (
   t   methodR$   t   passwordt   argsR%   t	   is_pbkdf2t   actual_methodt	   hash_funcR   R/   (    (    sW   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/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 ``pbpdf2:<method>[:iterations]``
                   to enable PBKDF2.
    :param salt_length: the length of the salt in letters
    RN   RE   s   %s$%s$%s(   RM   R_   (   RZ   RY   t   salt_lengthR$   R/   R]   (    (    sW   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/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   countR?   RQ   RD   R_   (   t   pwhashRZ   RY   R$   t   hashval(    (    sW   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/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   isabsRP   RK   (   t	   directoryt   filenameR   (    (    sW   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/werkzeug/security.pyt	   safe_joinë   s    !(-   t   __doc__Rj   R3   R   Rg   R!   t   structR    t   randomR   t   operatorR   t	   itertoolsR   t   werkzeug._compatR   R   R   R   R   R	   R
   RH   RT   t   packR6   R   R   R=   RF   t   listRk   R   t   altsepRi   R   R2   R(   R    RD   RM   R_   Ra   Rf   Ro   (    (    (    sW   /var/www/send.findwatt.com/datamanager/lib/python2.7/site-packages/werkzeug/security.pyt   <module>
   s8   4	(	
	'			+	