B
    ?F[                 @   sl   d Z ddlZddlZddlZddlZddlmZmZ G dd dejZ	dd Z
dd	 ZG d
d dejZdS )zCExtensions to allow HTTPS requests with SSL certificate validation.    N)sixhttp_clientc               @   s    e Zd ZdZdd Zdd ZdS )InvalidCertificateExceptionz?Raised when a certificate is provided with an invalid hostname.c             C   s"   t j|  || _|| _|| _dS )zConstructor.

        Args:
          host: The hostname the connection was made to.
          cert: The SSL certificate (as a dictionary) the host returned.
        N)r   HTTPException__init__hostcertreason)selfr   r   r	    r   4lib/python3.7/site-packages/boto/https_connection.pyr   "   s    z$InvalidCertificateException.__init__c             C   s   d| j | j| jf S )Nz0Host %s returned an invalid certificate (%s): %s)r   r	   r   )r
   r   r   r   __str__.   s    z#InvalidCertificateException.__str__N)__name__
__module____qualname____doc__r   r   r   r   r   r   r      s   r   c             C   s0   d| krdd | d D S dd | d D S dS )zReturns a list of valid host globs for an SSL certificate.

    Args:
      cert: A dictionary representing an SSL certificate.
    Returns:
      list: A list of valid host globs.
    ZsubjectAltNamec             S   s$   g | ]}|d    dkr|d qS )r   Zdns   )lower).0xr   r   r   
<listcomp><   s    z(GetValidHostsForCert.<locals>.<listcomp>c             S   s,   g | ]$}|d  d    dkr|d  d qS )r   Z
commonnamer   )r   )r   r   r   r   r   r   >   s    ZsubjectNr   )r   r   r   r   GetValidHostsForCert3   s    r   c             C   sX   t | }tjd|| x:|D ]2}|dddd}td|f |tjrdS qW dS )	a  Validates that a given hostname is valid for an SSL certificate.

    Args:
      cert: A dictionary representing an SSL certificate.
      hostname: The hostname to test.
    Returns:
      bool: Whether or not the hostname is valid for this certificate.
    z@validating server certificate: hostname=%s, certificate hosts=%s.z\.*z[^.]*z^%s$TF)r   botologdebugreplaceresearchI)r   hostnameZhostsr   Zhost_rer   r   r   ValidateCertificateHostnameB   s    	
r"   c               @   s2   e Zd ZdZejZeddddfddZdd ZdS )CertValidatingHTTPSConnectionzDAn HTTPConnection that connects over SSL and validates certificates.Nc             K   s>   t jr||d< tjj| f||d| || _|| _|| _dS )a*  Constructor.

        Args:
          host: The hostname. Can be in 'host:port' form.
          port: The port. Defaults to 443.
          key_file: A file containing the client's private key
          cert_file: A file containing the client's certificates
          ca_certs: A file contianing a set of concatenated certificate authority
              certs for validating the server against.
          strict: When true, causes BadStatusLine to be raised if the status line
              can't be parsed as a valid HTTP/1.0 or 1.1 status line.
        strict)r   portN)r   ZPY2r   HTTPConnectionr   key_file	cert_fileca_certs)r
   r   r%   r'   r(   r)   r$   kwargsr   r   r   r   [   s    z&CertValidatingHTTPSConnection.__init__c             C   s   t | dr"t| j| jf| j}nt| j| jf}d}| jrN|d| j 7 }n|d7 }tj	| t
j|| j| jt
j| jd| _| j }| jddd }t||st||d| d	S )
z(Connect to a host on a given (SSL) port.timeoutzwrapping ssl socket; zCA certificate file=%szusing system provided SSL certs)ZkeyfileZcertfileZ	cert_reqsr)   :r   z/remote hostname "%s" does not match certificateN)hasattrsocketZcreate_connectionr   r%   r+   r)   r   r   r   sslZwrap_socketr'   r(   ZCERT_REQUIREDsockZgetpeercertsplitr"   r   )r
   r0   msgr   r!   r   r   r   connectt   s&    



z%CertValidatingHTTPSConnection.connect)	r   r   r   r   r   Z
HTTPS_PORTZdefault_portr   r3   r   r   r   r   r#   V   s
   r#   )r   r   r.   r/   r   Zboto.compatr   r   r   r   r   r"   r&   r#   r   r   r   r   <module>   s   