U
    ncii                     @   s  d Z ddlmZmZ ddlZddlZddlZddlmZ ddl	Z	ddl
mZmZ ddlZddlmZ ddlmZmZ eeZdZed	Zed
Zdd Zdd ZeG dd dZedddZG dd dejZdd Ze fedddZ G dd deZ!dS )z5Mutual TLS for Google Compute Engine metadata server.    )	dataclassfieldN)Path)urlparse
urlunparse)HTTPAdapter)environment_vars
exceptionsntz#C:/ProgramData/Google/ComputeEnginez/run/google-mds-mtlsc                   C   s   t jtkrtd S td S d S )Nzmds-mtls-root.crtzroot.crtosname_WINDOWS_OS_NAME"_WINDOWS_MTLS_COMPONENTS_BASE_PATH_MTLS_COMPONENTS_BASE_PATH r   r   D/tmp/pip-unpacked-wheel-fpe1mg0e/google/auth/compute_engine/_mtls.py_get_mds_root_crt_path,   s    
r   c                   C   s   t jtkrtd S td S d S )Nzmds-mtls-client.keyz
client.keyr   r   r   r   r   "_get_mds_client_combined_cert_path3   s    
r   c                   @   s2   e Zd ZU eedZeed< eedZ	eed< dS )MdsMtlsConfig)default_factoryca_cert_pathclient_combined_cert_pathN)
__name__
__module____qualname__r   r   r   r   __annotations__r   r   r   r   r   r   r   :   s   
r   mds_mtls_configc                 C   s   t j| jot j| jS )z&Checks if the mTLS certificates exist.)r   pathexistsr   r   r   r   r   r   _certs_existD   s    r!   c                   @   s   e Zd ZdZdZdZdZdS )MdsMtlsModeaG  MDS mTLS mode. Used to configure connection behavior when connecting to MDS.

    STRICT: Always use HTTPS/mTLS.  If certificates are not found locally, an error will be returned.
    NONE: Never use mTLS. Requests will use regular HTTP.
    DEFAULT: Use mTLS if certificates are found locally, otherwise use regular HTTP.
    strictnonedefaultN)r   r   r   __doc__STRICTNONEDEFAULTr   r   r   r   r"   K   s   r"   c                  C   s@   t jtjd } z
t| W S  tk
r:   tdY nX dS )z7Parses the GCE_METADATA_MTLS_MODE environment variable.r%   zXInvalid value for GCE_METADATA_MTLS_MODE. Must be one of 'strict', 'none', or 'default'.N)r   environgetr   ZGCE_METADATA_MTLS_MODElowerr"   
ValueError)Zmode_strr   r   r   _parse_mds_modeX   s     
r.   c                 C   s@   t  }|tjkr&t| s"tddS |tjkr4dS t| S dS )z:Determines if mTLS should be used for the metadata server.z+mTLS certificates not found in strict mode.TFN)r.   r"   r'   r!   r	   ZMutualTLSChannelErrorr(   )r   moder   r   r   should_use_mds_mtlse   s    

r0   c                       sP   e Zd ZdZe fed fddZ fddZ fddZ fd	d
Z  Z	S )MdsMtlsAdapterz7An HTTP adapter that uses mTLS for the metadata server.r   c                    s@   t  | _| jj|jd | jj|jd tt| j	|| d S )N)cafile)certfile)
sslcreate_default_contextssl_contextload_verify_locationsr   load_cert_chainr   superr1   __init__)selfr   argskwargs	__class__r   r   r:   w   s    
zMdsMtlsAdapter.__init__c                    s   | j |d< tt| j||S Nr6   )r6   r9   r1   init_poolmanagerr;   r<   r=   r>   r   r   rA      s    
zMdsMtlsAdapter.init_poolmanagerc                    s   | j |d< tt| j||S r@   )r6   r9   r1   proxy_manager_forrB   r>   r   r   rC      s    
z MdsMtlsAdapter.proxy_manager_forc              
      s   t  tjkr tt| j|f|S z"tt| j|f|}|  |W S  tjt	j
jt	j
jfk
r } zHtd| t|j}t|jdd}||_t }|j|f| W Y S d }~X Y nX d S )NzcmTLS connection to Compute Engine Metadata server failed. Falling back to standard HTTP. Reason: %shttp)scheme)r.   r"   r'   r9   r1   sendraise_for_statusr4   SSLErrorrequestsr	   	HTTPError_LOGGERwarningr   urlr   _replacer   )r;   requestr=   responseeZparsed_original_urlZhttp_fallback_urlZhttp_adapterr>   r   r   rF      s(    
zMdsMtlsAdapter.send)
r   r   r   r&   r   r:   rA   rC   rF   __classcell__r   r   r>   r   r1   t   s   
r1   )"r&   Zdataclassesr   r   enumloggingr   pathlibr   r4   urllib.parser   r   rI   Zrequests.adaptersr   Zgoogle.authr   r	   	getLoggerr   rK   r   r   r   r   r   r   r!   Enumr"   r.   r0   r1   r   r   r   r   <module>   s.   
	