ó
]'v_c           @@  s“  d  Z  d d l m Z y$ d d l m Z d d l m Z Wn e k
 r[ Z	 e
 e	 ƒ ‚ n Xd d l Z d d l m Z d d l m Z m Z d d l m Z m Z m Z d d l Z d d l Z d	 d
 l m Z d	 d l m Z d d g Z e Z i e j j  e j! 6e j j" e j# 6Z$ e% e d ƒ rQe% e j d ƒ rQe j j& e$ e j' <n  e% e d ƒ rˆe% e j d ƒ rˆe j j( e$ e j) <n  y! e$ j* i e j j+ e j, 6ƒ Wn e- k
 r¼n Xi e j j. e j/ 6e j j0 e j1 6e j j0 e j j2 e j3 6Z4 e j5 j6 Z7 d Z8 e j Z9 e j: Z; d „  Z< d „  Z= d e f d „  ƒ  YZ d „  Z> d e? f d „  ƒ  YZ@ d „  ZA d d d d d d d d „ Z: d S(   s!  SSL with SNI_-support for Python 2. Follow these instructions if you would
like to verify SSL certificates in Python 2. Note, the default libraries do
*not* do certificate checking; you need to do additional work to validate
certificates yourself.

This needs the following packages installed:

* pyOpenSSL (tested with 0.13)
* ndg-httpsclient (tested with 0.3.2)
* pyasn1 (tested with 0.1.6)

You can install them with the following command:

    pip install pyopenssl ndg-httpsclient pyasn1

To activate certificate checking, call
:func:`~urllib3.contrib.pyopenssl.inject_into_urllib3` from your Python code
before you begin making HTTP requests. This can be done in a ``sitecustomize``
module, or at any other time before your application begins using ``urllib3``,
like this::

    try:
        import urllib3.contrib.pyopenssl
        urllib3.contrib.pyopenssl.inject_into_urllib3()
    except ImportError:
        pass

Now you can use :mod:`urllib3` as you normally would, and it will support SNI
when the required modules are installed.

Activating this module also has the positive side effect of disabling SSL/TLS
compression in Python 2 (see `CRIME attack`_).

If you want to configure the default list of supported cipher suites, you can
set the ``urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST`` variable.

Module Variables
----------------

:var DEFAULT_SSL_CIPHER_LIST: The list of supported SSL/TLS cipher suites.

.. _sni: https://en.wikipedia.org/wiki/Server_Name_Indication
.. _crime attack: https://en.wikipedia.org/wiki/CRIME_(security_exploit)

i    (   t   absolute_import(   t   SUBJ_ALT_NAME_SUPPORT(   t   SubjectAltNameN(   t   decoder(   t   univt
   constraint(   t   _fileobjectt   timeoutt   errori   (   t
   connection(   t   utilt   inject_into_urllib3t   extract_from_urllib3t   PROTOCOL_TLSv1_1t   TLSv1_1_METHODt   PROTOCOL_TLSv1_2t   TLSv1_2_METHODi @  c           C@  s   t  t _  t t _ d S(   s7   Monkey-patch urllib3 with PyOpenSSL-backed SSL-support.N(   t   ssl_wrap_socketR	   t   HAS_SNIR
   (    (    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyR   f   s    	c           C@  s   t  t _ t t _ d S(   s4   Undo monkey-patching by :func:`inject_into_urllib3`.N(   t   orig_connection_ssl_wrap_socketR	   R   t   orig_util_HAS_SNIR
   R   (    (    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyR   m   s    	R   c           B@  s*   e  Z d  Z e j j e j d d ƒ Z RS(   s0   ASN.1 implementation for subjectAltNames supporti   i   (   t   __name__t
   __module__t   __doc__R   t
   SequenceOft   sizeSpecR   t   ValueSizeConstraint(    (    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyR   u   s   	c         C@  s  g  } t  s | St ƒ  } xë t |  j ƒ  ƒ D]× } |  j | ƒ } | j ƒ  } | d k r_ q, n  | j ƒ  } t j | d | ƒ} x€ | D]x } t	 | t ƒ s¢ q‡ n  xZ t t
 | ƒ ƒ D]F }	 | j |	 ƒ }
 |
 j ƒ  d k râ qµ n  | j t |
 j ƒ  ƒ ƒ qµ Wq‡ Wq, W| S(   Nt   subjectAltNamet   asn1Spect   dNSName(   R   R   t   ranget   get_extension_countt   get_extensiont   get_short_namet   get_datat   der_decodert   decodet
   isinstancet   lent   getComponentByPositiont   getNamet   appendt   strt   getComponent(   t	   peer_certt   dns_namet   general_namest   it   extt   ext_namet   ext_datt   decoded_datt   namet   entryt	   component(    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyt   get_subj_alt_name€   s*    		%t   WrappedSocketc           B@  sƒ   e  Z d  Z e d „ Z d „  Z d d „ Z d „  Z d „  Z d „  Z	 d „  Z
 d	 „  Z d
 „  Z e d „ Z d „  Z d „  Z RS(   s§   API-compatibility wrapper for Python OpenSSL's Connection-class.

    Note: _makefile_refs, _drop() and _reuse() are needed for the garbage
    collector of pypy.
    c         C@  s(   | |  _  | |  _ | |  _ d |  _ d  S(   Ni    (   R	   t   sockett   suppress_ragged_eofst   _makefile_refs(   t   selfR	   R9   R:   (    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyt   __init__¥   s    			c         C@  s   |  j  j ƒ  S(   N(   R9   t   fileno(   R<   (    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyR>   «   s    iÿÿÿÿc         C@  s%   |  j  d 7_  t |  | | d t ƒS(   Ni   t   close(   R;   R   t   True(   R<   t   modet   bufsize(    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyt   makefile®   s    c         O@  s  y |  j  j | | Ž  } Wnä t j j k
 r\ } |  j rM | j d k rM d St | ƒ ‚ n¨ t j j k
 r” |  j  j	 ƒ  t j j
 k rŽ d S‚  np t j j k
 rÿ t j |  j g g  g  |  j j ƒ  ƒ \ } } } | sì t d ƒ ‚ q|  j | | Ž  Sn X| Sd  S(   Niÿÿÿÿs   Unexpected EOFt    s   The read operation timed out(   iÿÿÿÿs   Unexpected EOF(   R	   t   recvt   OpenSSLt   SSLt   SysCallErrorR:   t   argst   SocketErrort   ZeroReturnErrort   get_shutdownt   RECEIVED_SHUTDOWNt   WantReadErrort   selectR9   t
   gettimeoutR   (   R<   RI   t   kwargst   datat   et   rdt   wdt   ed(    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyRE   ²   s"    *c         C@  s   |  j  j | ƒ S(   N(   R9   t
   settimeout(   R<   R   (    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyRW   É   s    c         C@  s„   x} t  r y |  j j | ƒ SWq t j j k
 r{ t j g  |  j g g  |  j j ƒ  ƒ \ } } } | s t	 ƒ  ‚ q q q Xq Wd  S(   N(
   R@   R	   t   sendRF   RG   t   WantWriteErrorRO   R9   RP   R   (   R<   RR   t   _t   wlist(    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyt   _send_until_doneÌ   s    	c         C@  sG   d } x: | t  | ƒ k  rB |  j | | | t !ƒ } | | 7} q	 Wd  S(   Ni    (   R&   R\   t   SSL_WRITE_BLOCKSIZE(   R<   RR   t
   total_sentt   sent(    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyt   sendall×   s    c         C@  s   |  j  j ƒ  d  S(   N(   R	   t   shutdown(   R<   (    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyRa   Ý   s    c         C@  sQ   |  j  d k  r> y |  j j ƒ  SWqM t j j k
 r: d  SXn |  j  d 8_  d  S(   Ni   (   R;   R	   R?   RF   RG   t   Error(   R<   (    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyR?   á   s    c         C@  s~   |  j  j ƒ  } | s | S| r8 t j j t j j | ƒ Si d | j ƒ  j f f f d 6g  t | ƒ D] } d | f ^ qd d 6S(   Nt
   commonNamet   subjectt   DNSR   (	   R	   t   get_peer_certificateRF   t   cryptot   dump_certificatet   FILETYPE_ASN1t   get_subjectt   CNR7   (   R<   t   binary_formt   x509t   value(    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyt   getpeercertê   s    		c         C@  s   |  j  d 7_  d  S(   Ni   (   R;   (   R<   (    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyt   _reuseÿ   s    c         C@  s/   |  j  d k  r |  j ƒ  n |  j  d 8_  d  S(   Ni   (   R;   R?   (   R<   (    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyt   _drop  s    (   R   R   R   R@   R=   R>   RC   RE   RW   R\   R`   Ra   R?   t   FalseRo   Rp   Rq   (    (    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyR8   ž   s   									c         C@  s
   | d k S(   Ni    (    (   t   cnxRm   t   err_not	   err_deptht   return_code(    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyt   _verify_callback	  s    c         C@  sÏ  t  j j t | ƒ } | r8 | p% | } | j | ƒ n  | rN | j | ƒ n  | t j k rt | j t	 | t
 ƒ n  | s€ | rÉ y | j | | ƒ WqÓ t  j j k
 rÅ }	 t j d | |	 ƒ ‚ qÓ Xn
 | j ƒ  d }
 | j |
 ƒ | j t ƒ t  j j | |  ƒ } | j | ƒ | j ƒ  x  t rÁy | j ƒ  Wn„ t  j j k
 r‘t j |  g g  g  |  j ƒ  ƒ \ } } } | s"t d ƒ ‚ q"q"n, t  j j k
 r¼}	 t j d |	 ƒ ‚ n XPq"Wt | |  ƒ S(   Ns   bad ca_certs: %ri   s   select timed outs   bad handshake: %r(   RF   RG   t   Contextt   _openssl_versionst   use_certificate_filet   use_privatekey_filet   sslt	   CERT_NONEt
   set_verifyt   _openssl_verifyRw   t   load_verify_locationsRb   t   SSLErrort   set_default_verify_pathst   set_optionst   set_cipher_listt   DEFAULT_SSL_CIPHER_LISTt
   Connectiont   set_tlsext_host_namet   set_connect_stateR@   t   do_handshakeRN   RO   RP   R   R8   (   t   sockt   keyfilet   certfilet	   cert_reqst   ca_certst   server_hostnamet   ssl_versiont   ca_cert_dirt   ctxRS   t   OP_NO_COMPRESSIONRs   RT   RZ   (    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyR     s@    

	*(C   R   t
   __future__R    t%   ndg.httpsclient.ssl_peer_verificationR   t   ndg.httpsclient.subj_alt_nameR   t   BaseSubjectAltNamet   SyntaxErrorRS   t   ImportErrort   OpenSSL.SSLRF   t   pyasn1.codec.derR   R#   t   pyasn1.typeR   R   R9   R   R   R   RJ   R|   RO   RD   R	   R
   t   __all__R   RG   t   SSLv23_METHODt   PROTOCOL_SSLv23t   TLSv1_METHODt   PROTOCOL_TLSv1Ry   t   hasattrR   R   R   R   t   updatet   SSLv3_METHODt   PROTOCOL_SSLv3t   AttributeErrort   VERIFY_NONER}   t   VERIFY_PEERt   CERT_OPTIONALt   VERIFY_FAIL_IF_NO_PEER_CERTt   CERT_REQUIREDR   t   ssl_t   DEFAULT_CIPHERSR…   R]   R   R   R   R   R   R7   t   objectR8   Rw   t   None(    (    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyt   <module>-   sX   !!!					k		