
 Tc           @   s  d  Z  y$ d d l m Z d d l m Z Wn e k
 rK 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 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  y! e  j! i e
 j j" e j# 6 Wn e$ k
 r8n Xi e
 j j% e j& 6e
 j j' e j( 6e
 j j' e
 j j) e j* 6Z+ d d d Z, e j Z- e j. Z/ d   Z0 d   Z1 d e f d     YZ d   Z2 d e3 f d     YZ4 d   Z5 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.
    Default: ``ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:
    ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS``

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

i(   t   SUBJ_ALT_NAME_SUPPORT(   t   SubjectAltNameN(   t   decoder(   t   univt
   constraint(   t   _fileobjectt   timeouti   (   t
   connection(   t   utilt   inject_into_urllib3t   extract_from_urllib3s,   ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:sA   ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:s   !aNULL:!MD5:!DSSc           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/site-packages/urllib3/contrib/pyopenssl.pyR	   n   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/site-packages/urllib3/contrib/pyopenssl.pyR
   u   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/site-packages/urllib3/contrib/pyopenssl.pyR   }   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/site-packages/urllib3/contrib/pyopenssl.pyt   get_subj_alt_name   s*    		%t   WrappedSocketc           B   sz   e  Z d  Z e d  Z d   Z d 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   R3   R4   (    (    s=   /usr/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.pyt   __init__   s    			c         C   s   |  j  j   S(   N(   R3   t   fileno(   R6   (    (    s=   /usr/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.pyR8      s    ic         C   s%   |  j  d 7_  t |  | | d t S(   Ni   t   close(   R5   R   t   True(   R6   t   modet   bufsize(    (    s=   /usr/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.pyt   makefile   s    c         O   s  y |  j  j | |   } Wn t j j k
 rS } |  j rM | j d k rM d S  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(   Nis   Unexpected EOFt    s   The read operation timed out(   is   Unexpected EOF(   R   t   recvt   OpenSSLt   SSLt   SysCallErrorR4   t   argst   ZeroReturnErrort   get_shutdownt   RECEIVED_SHUTDOWNt   WantReadErrort   selectR3   t
   gettimeoutR   (   R6   RC   t   kwargst   datat   et   rdt   wdt   ed(    (    s=   /usr/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.pyR?      s"    *c         C   s   |  j  j |  S(   N(   R3   t
   settimeout(   R6   R   (    (    s=   /usr/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.pyRP      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   sendR@   RA   t   WantWriteErrorRH   R3   RI   R   (   R6   RK   t   _t   wlist(    (    s=   /usr/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.pyt   _send_until_done   s    	c         C   s0   x) t  |  r+ |  j |  } | | } q Wd  S(   N(   R    RU   (   R6   RK   t   sent(    (    s=   /usr/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.pyt   sendall   s    c         C   s/   |  j  d k  r |  j j   S|  j  d 8_  d  S(   Ni   (   R5   R   t   shutdown(   R6   (    (    s=   /usr/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.pyR9      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_certificateR@   t   cryptot   dump_certificatet   FILETYPE_ASN1t   get_subjectt   CNR1   (   R6   t   binary_formt   x509t   value(    (    s=   /usr/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.pyt   getpeercert   s    		c         C   s   |  j  d 7_  d  S(   Ni   (   R5   (   R6   (    (    s=   /usr/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.pyt   _reuse   s    c         C   s/   |  j  d k  r |  j   n |  j  d 8_  d  S(   Ni   (   R5   R9   (   R6   (    (    s=   /usr/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.pyt   _drop  s    (   R   R   R   R:   R7   R8   R=   R?   RP   RU   RW   R9   t   FalseRe   Rf   Rg   (    (    (    s=   /usr/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.pyR2      s   							c         C   s
   | d k S(   Ni    (    (   t   cnxRc   t   err_not	   err_deptht   return_code(    (    s=   /usr/lib/python2.7/site-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  | r y | j | d   Wq t  j j k
 r } t j d | |   q Xn
 | j   d }	 | j |	  | j t  t  j j | |   }
 |
 j |  |
 j   xv t ry |
 j   WnZ t  j j k
 rbt j |  g g  g   qn+ t  j j k
 r} t j d |   n XPqWt |
 |   S(   Ns   bad ca_certs: %ri   s   bad handshake(   R@   RA   t   Contextt   _openssl_versionst   use_certificate_filet   use_privatekey_filet   sslt	   CERT_NONEt
   set_verifyt   _openssl_verifyRm   t   load_verify_locationst   Nonet   Errort   SSLErrort   set_default_verify_pathst   set_optionst   set_cipher_listt   DEFAULT_SSL_CIPHER_LISTt
   Connectiont   set_tlsext_host_namet   set_connect_stateR:   t   do_handshakeRG   RH   R2   (   t   sockt   keyfilet   certfilet	   cert_reqst   ca_certst   server_hostnamet   ssl_versiont   ctxRL   t   OP_NO_COMPRESSIONRi   (    (    s=   /usr/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.pyR     s<    

	(7   R   t%   ndg.httpsclient.ssl_peer_verificationR    t   ndg.httpsclient.subj_alt_nameR   t   BaseSubjectAltNamet   SyntaxErrorRL   t   ImportErrort   OpenSSL.SSLR@   t   pyasn1.codec.derR   R   t   pyasn1.typeR   R   R3   R   R   Rr   RH   R>   R   R   t   __all__R   RA   t   SSLv23_METHODt   PROTOCOL_SSLv23t   TLSv1_METHODt   PROTOCOL_TLSv1Ro   t   updatet   SSLv3_METHODt   PROTOCOL_SSLv3t   AttributeErrort   VERIFY_NONERs   t   VERIFY_PEERt   CERT_OPTIONALt   VERIFY_FAIL_IF_NO_PEER_CERTt   CERT_REQUIREDRu   R}   R   R   R   R	   R
   R1   t   objectR2   Rm   Rw   (    (    (    s=   /usr/lib/python2.7/site-packages/urllib3/contrib/pyopenssl.pyt   <module>/   sP   !						c		