ó
gP¾[c           @   sÕ  d  Z  d d l m Z d d l m Z d d l Z d d l m Z	 d d l
 m Z d d l Z d d l m Z d d	 l m Z d d
 l m Z d d g Z e Z y: i e j j e j 6e j j e j 6e j j e j 6Z Wn7 e k
 ri e j j e j 6e j j e j 6Z n Xi e j j e j 6e j j e j  6e j j e j j! e j" 6Z# e j Z$ e j% Z& d „  Z' d „  Z( d „  Z) d e f d „  ƒ  YZ* d e+ f d „  ƒ  YZ, d „  Z- d d d d d d d „ Z% d S(   sŒ  SSL with SNI-support for Python 2.

This needs the following packages installed:

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

To activate it call :func:`~urllib3.contrib.pyopenssl.inject_into_urllib3`.
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.
iÿÿÿÿ(   t   SUBJ_ALT_NAME_SUPPORT(   t   SubjectAltNameN(   t   decoder(   t   _fileobject(   t   StringIOi   (   t   connectionpool(   t   utilt   inject_into_urllib3t   extract_from_urllib3c           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   ?   s    	c           C   s   t  t _ t t _ d S(   s4   Undo monkey-patching by :func:`inject_into_urllib3`.N(   t#   orig_connectionpool_ssl_wrap_socketR   R	   t   orig_util_HAS_SNIR   R
   (    (    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyR   F   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_nameN   s*    		%t
   fileobjectc           B   s    e  Z d  d „ Z d  d „ Z RS(   iÿÿÿÿc   	      C   sî  t  |  j |  j ƒ } |  j } | j d d ƒ | d k  r§ t ƒ  |  _ xT t rœ y |  j j | ƒ } Wn t	 j
 j k
 r qI n X| sŒ Pn  | j | ƒ qI W| j ƒ  S| j ƒ  } | | k r| j d ƒ | j | ƒ } t ƒ  |  _ |  j j | j ƒ  ƒ | St ƒ  |  _ xÐ t rß| | } y |  j j | ƒ } Wn t	 j
 j k
 rRqn X| s]Pn  t | ƒ } | | k r€| r€| S| | k r | j | ƒ ~ Pn  | | k sÂt d | | f ƒ ‚ | j | ƒ | | 7} ~ qW| j ƒ  Sd  S(   Ni    i   s   recv(%d) returned %d bytes(   t   maxt	   _rbufsizet   default_bufsizet   _rbuft   seekR   t   Truet   _sockt   recvt   OpenSSLt   SSLt   WantReadErrort   writet   getvaluet   tellt   readR   t   AssertionError(	   t   selft   sizet   rbufsizet   buft   datat   buf_lent   rvt   leftt   n(    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyR9   n   sT    		
	
"
c         C   sÛ  |  j  } | j d d ƒ | j ƒ  d k r” | j d ƒ | j | ƒ } | j d ƒ sh t | ƒ | k rŽ t ƒ  |  _  |  j  j | j ƒ  ƒ | S~ n  | d k  r,|  j	 d k r[| j d ƒ | j ƒ  g } t ƒ  |  _  d  } |  j j } xb t rMy: x3 | d k r*| d ƒ } | sPn  | j | ƒ qø WWn t j j k
 rHqì n XPqì Wd j | ƒ S| j d d ƒ t ƒ  |  _  x¨ t r!y |  j j |  j	 ƒ } Wn t j j k
 rµqzn X| sÀPn  | j d ƒ } | d k r| d 7} | j | |  ƒ |  j  j | | ƒ ~ Pn  | j | ƒ qzW| j ƒ  S| j d d ƒ | j ƒ  } | | k r–| j d ƒ | j | ƒ }	 t ƒ  |  _  |  j  j | j ƒ  ƒ |	 St ƒ  |  _  x(t rÌy |  j j |  j	 ƒ } Wn t j j k
 ràq¥n X| sëPn  | | }
 | j d d |
 ƒ } | d k rZ| d 7} |  j  j | | ƒ | rO| j | |  ƒ PqZ| |  Sn  t | ƒ } | | k r}| r}| S| |
 k r²| j | |
  ƒ |  j  j | |
 ƒ Pn  | j | ƒ | | 7} q¥W| j ƒ  Sd  S(   Ni    i   s   
i   t    (   R.   R/   R8   t   readlinet   endswithR   R   R6   R9   R,   t   NoneR1   R2   R0   R   R3   R4   R5   t   joint   findR7   (   R;   R<   R>   t   blinet   buffersR?   R2   t   nlR@   RA   RB   RC   (    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyRE   °   s¢    	!		

	

(   t   __name__t
   __module__R9   RE   (    (    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyR*   l   s   Bt   WrappedSocketc           B   sS   e  Z d  Z d „  Z d „  Z d d „ Z d „  Z d „  Z d „  Z e	 d „ Z
 RS(	   s@   API-compatibility wrapper for Python OpenSSL's Connection-class.c         C   s   | |  _  | |  _ d  S(   N(   t
   connectiont   socket(   R;   RP   RQ   (    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyt   __init__  s    	c         C   s   |  j  j ƒ  S(   N(   RQ   t   fileno(   R;   (    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyRS     s    iÿÿÿÿc         C   s   t  |  j | | ƒ S(   N(   R*   RP   (   R;   t   modet   bufsize(    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyt   makefile  s    c         C   s   |  j  j | ƒ S(   N(   RQ   t
   settimeout(   R;   t   timeout(    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyRW     s    c         C   s   |  j  j | ƒ S(   N(   RP   t   sendall(   R;   R?   (    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyRY   "  s    c         C   s   |  j  j ƒ  S(   N(   RP   t   shutdown(   R;   (    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyt   close%  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   (	   RP   t   get_peer_certificateR3   t   cryptot   dump_certificatet   FILETYPE_ASN1t   get_subjectt   CNR)   (   R;   t   binary_formt   x509t   value(    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyt   getpeercert(  s    		(   RM   RN   t   __doc__RR   RS   RV   RW   RY   R[   t   FalseRh   (    (    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyRO     s   					c         C   s
   | d k S(   Ni    (    (   t   cnxRf   t   err_not	   err_deptht   return_code(    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyt   _verify_callback>  s    c   
      C   sS  t  j j t | ƒ } | r, | j | ƒ n  | rB | j | ƒ n  | t j k rh | j t	 | t
 ƒ n  | r· y | j | d  ƒ Wq· t  j j k
 r³ } t j d | | ƒ ‚ q· Xn  t  j j | |  ƒ }	 |	 j | ƒ |	 j ƒ  x` t rEy |	 j ƒ  WnD t  j j k
 rqæ n+ t  j j k
 r@} t j d | ƒ ‚ n XPqæ Wt |	 |  ƒ S(   Ns   bad ca_certs: %rs   bad handshake(   R3   R4   t   Contextt   _openssl_versionst   use_certificate_filet   use_privatekey_filet   sslt	   CERT_NONEt
   set_verifyt   _openssl_verifyRo   t   load_verify_locationsRG   t   Errort   SSLErrort
   Connectiont   set_tlsext_host_namet   set_connect_stateR0   t   do_handshakeR5   RO   (
   t   sockt   keyfilet   certfilet	   cert_reqst   ca_certst   server_hostnamet   ssl_versiont   ctxt   eRk   (    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyR	   B  s0    
	(/   Ri   t%   ndg.httpsclient.ssl_peer_verificationR    t   ndg.httpsclient.subj_alt_nameR   t   OpenSSL.SSLR3   t   pyasn1.codec.derR   R   RQ   R   Rt   t	   cStringIOR   RD   R   R   t   __all__R
   R4   t   SSLv23_METHODt   PROTOCOL_SSLv23t   SSLv3_METHODt   PROTOCOL_SSLv3t   TLSv1_METHODt   PROTOCOL_TLSv1Rq   t   AttributeErrort   VERIFY_NONERu   t   VERIFY_PEERt   CERT_OPTIONALt   VERIFY_FAIL_IF_NO_PEER_CERTt   CERT_REQUIREDRw   R   R	   R   R   R   R)   R*   t   objectRO   Ro   RG   (    (    (    s=   /usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.pyt   <module>   sH   						¦,		