3
b2                 @   s   d dl mZ d dlZejdkr,ddlmZ nddlmZ d dlZd dlm	Z	 d dl
mZ d dlmZ yd d	lmZ W n  ek
r   d d	lmZ Y nX dd
lmZ ddlmZmZ ddlmZ dgZG dd deZG dd deZdS )    )absolute_importN      )httplib)debug)	Semaphore)time)urlparse)Config)ParameterErrorS3SSLCertificateError)getBucketFromHostnameConnManc               @   sj   e Zd ZdZdZedd Zedd Zedd Zed	d
 Z	dd Z
dd ZedddZdd ZdS )http_connectionNFc             C   sN   t  }d }ytj| d}W n tk
r.   Y nX |rJ|j rJd|_td |S )N)cafileFz+Disabling SSL certificate hostname checking)r
   sslcreate_default_contextAttributeErrorcheck_ssl_hostnamecheck_hostnamer   )r   cfgcontext r   J/oak/stanford/groups/akundaje/marinovg/programs/s3cmd-master/S3/ConnMan.py_ssl_verified_context(   s    z%http_connection._ssl_verified_contextc             C   s:   t d d }ytj| tjd}W n tk
r4   Y nX |S )Nz"Disabling SSL certificate checking)r   	cert_reqs)r   r   _create_unverified_context	CERT_NONEr   )r   r   r   r   r   _ssl_unverified_context6   s    z'http_connection._ssl_unverified_contextc             C   sD   d }y&|rt jnt j}t j||| |d}W n tk
r>   Y nX |S )N)r   keyfilecertfiler   )r   CERT_REQUIREDr   r   r   )r    r   Zcheck_server_certr   r   r   r   r   r   _ssl_client_auth_contextA   s    z(http_connection._ssl_client_auth_contextc              C   s   t jrt jS t } | j}|dkr$d }| jp,d }| jp6d }td| td| td| |d k	rrt j||| j	|}n| j	rt j
|}n
t j|}|t _dt _|S )N zUsing ca_certs_file %szUsing ssl_client_cert_file %szUsing ssl_client_key_file %sT)r   context_setr   r
   ca_certs_filessl_client_cert_filessl_client_key_filer   r"   check_ssl_certificater   r   )r   r   r    r   r   r   r   r   _ssl_contextN   s&    





zhttp_connection._ssl_contextc             C   s   t d |jdf }|j }tdtj j}x|D ]\}}|dkr2|j }|jdrh|jdrh|jds||jdr|jdrdS ||d	tj	j d
 kr2|j|dtj	j d
 r2dS q2W dS )a  
        Wildcard matching for *.s3.amazonaws.com and similar per region.

        Per http://docs.aws.amazon.com/AmazonS3/latest/dev/BucketRestrictions.html:
        "We recommend that all bucket names comply with DNS naming conventions."

        Per http://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html:
        "When using virtual hosted-style buckets with SSL, the SSL
        wild card certificate only matches buckets that do not contain
        periods. To work around this, use HTTP or write your own
        certificate verification logic."

        Therefore, we need a custom validation routine that allows
        mybucket.example.com.s3.amazonaws.com to be considered a valid
        hostname for the *.s3.amazonaws.com wildcard cert, and for the
        region-specific *.s3-[region].amazonaws.com wildcard cert.

        We also forgive non-S3 wildcard certificates should the
        hostname match, to allow compatibility with other S3
        API-compatible storage providers.
        z6checking SSL subjectAltName as forgiving wildcard certsubjectAltNamezhttps://DNSz*.s3z.amazonaws.comz.amazonaws.com.cnT*)bucketlocationr#   F)
r   getlowerr	   r
   host_buckethostname
startswithendswithbucket_location)selfcertr2   sanZcleaned_host_bucket_configkeyvaluer   r   r   forgive_wildcard_certi   s"    
z%http_connection.forgive_wildcard_certc             C   s|   | j jj }ytj|| j W nX tk
r2   d S  tk
rD   d S  tk
rv } z| j	|| jsf|W Y d d }~X nX d S )N)
csockgetpeercertr   match_hostnamer2   r   
ValueErrorZS3CertificateErrorr;   )r6   r7   er   r   r   r?      s    zhttp_connection.match_hostnamec             C   s   yft j }t| \}}|r:d|kr:td d}|rJd|_n|rF|j}nd}tj| |||d}td W nZ tk
r   ytj| ||d}td W n( tk
r   tj| |}td	 Y nX Y nX |S )
N.zHBucket name contains "." character, disabling initial SSL hostname checkFT)r   r   z=httplib.HTTPSConnection() has both context and check_hostname)r   z*httplib.HTTPSConnection() has only contextz@httplib.HTTPSConnection() has neither context nor check_hostname)r   r)   r   r   r   r   HTTPSConnection	TypeError)r2   portr   bucket_namesuccessr   connr   r   r   _https_connection   s*    z!http_connection._https_connectionc             C   s8  || _ || _d| _td| }|j| _|j| _|jrZ|jdkrZ|jjd| _td| j nd | _|j	s|rt
j| j| j| _td| j| j n"tj| j| j| _td| j| j nz|r
t
j|j	|j| _td|j	|j | jr| jpd}| jj| j| td	| j| n"tj|j	|j| _td
|j	|j t | _d S )Nr   zhttps:///zendpoint path set to %sz#non-proxied HTTPSConnection(%s, %s)z"non-proxied HTTPConnection(%s, %s)zproxied HTTPSConnection(%s, %s)i  ztunnel to %s, %szproxied HTTPConnection(%s, %s))r   idcounterr	   r2   rE   pathrstripr   
proxy_hostr   rI   r<   r   HTTPConnection
proxy_port
set_tunnelr   last_used_time)r6   rK   r2   r   r   Zparsed_hostnamerE   r   r   r   __init__   s2    zhttp_connection.__init__)N)__name__
__module____qualname__r   r$   staticmethodr   r   r"   r)   r;   r?   rI   rT   r   r   r   r   r   $   s   ($r   c               @   sL   e Zd ZejZejZe Zi ZdZ	e
d	ddZe
dd Ze
dd ZdS )
r   i   Nc             C   sL  t  }|d kr|j}d }|jdkrJ|r8tjdk r8tdd|j|jf }nd|rTdpVd| f }tjj	  |tj
kr|g tj
|< xhtj
| rtj
| j }t }||j|j k r||jkrtd|j|jf  P td tj| d }q~W tjj  |s:td	|  t|| ||}|jj  |jr:|jr:|jr:|j  | jd
7  _|S )Nr#   i  z6use_https=True can't be used with proxy on Python <2.7zproxy://%s:%szhttp%s://%ssz)ConnMan.get(): re-using connection: %s#%dz)ConnMan.get(): closing expired connectionz*ConnMan.get(): creating new connection: %sr   )r
   	use_httpsrO   sys
hexversionr   rQ   r   conn_pool_semacquire	conn_poolpopr   rS   connection_max_ager   rK   rL   closereleaser   r<   connectr   r(   r   r?   )r2   r   r   rH   Zconn_idZcur_timer   r   r   r/      s@    







zConnMan.getc             C   s   | j jdr"tj|  td d S | jtjkrDtj|  td d S t }|jsftj|  td d S t	 | _
tjj  tj| j  j|  tjj  td| j | jf  d S )Nzproxy://zFConnMan.put(): closing proxy connection (keep-alive not yet supported)z+ConnMan.put(): closing over-used connectionz?ConnMan.put(): closing connection (connection pooling disabled)z2ConnMan.put(): connection put back to pool (%s#%d))rK   r3   r   rb   r   rL   conn_max_counterr
   connection_poolingr   rS   r]   r^   r_   appendrc   )rH   r   r   r   r   put"  s&    




zConnMan.putc             C   s   | r| j j  d S )N)r<   rb   )rH   r   r   r   rb   >  s    zConnMan.close)N)rU   rV   rW   r   _CS_REQ_SENTCONTINUEr   r]   r_   re   rX   r/   rh   rb   r   r   r   r   r      s   %)r   r   )
__future__r   r[   version_infoZCustom_httplib3xr   ZCustom_httplib27r   loggingr   	threadingr   r   r	   ImportErrorurllib.parser
   
Exceptionsr   r   Utilsr   __all__objectr   r   r   r   r   r   <module>	   s&   
 R