a
    lJh$                     @   s,  d Z ddlZddlZddlmZ ddlmZ ddlmZm	Z	m
Z
mZ ddlmZ ddlmZ erldd	lmZ z8dd
lmZ ddlmZmZ ddlmZ ddlmZ W n ey   eddY n0 zddlmZmZ W n ey   eddY n0 ddlmZ dZ dZ!dZ"dZ#dZ$G dd deZ%dS )zOCI Authentication Plugin.    N)	b64encode)Path)TYPE_CHECKINGAnyDictOptional   )errors)logger)MySQLSocket)UnsupportedAlgorithm)hashesserialization)padding)PRIVATE_KEY_TYPESz'Package 'cryptography' is not installed)config
exceptionszGPackage 'oci' (Oracle Cloud Infrastructure Python SDK) is not installed   )MySQLAuthPluginMySQLOCIAuthPlugini (  z0Ephemeral security token is too large (10KB max)zGEphemeral security token file ('security_token_file') could not be readzKOCI configuration file does not contain a 'fingerprint' or 'key_file' entryc                   @   s   e Zd ZU dZdZeed< dZeed< e	j
Zeed< eeeeef eddd	Zeeed
ddZeeef dddZeedddZeedddZeeee dddZdeeedddZdS )r   z2Implement the MySQL OCI IAM authentication plugin.NcontextDEFAULToci_config_profileoci_config_file)	signature
oci_configreturnc              
   C   s   t | }|d | d}|drz8t|d }| jtkrJtt	|j
dd|d< W n4 ttfy } ztt|W Y d}~n
d}~0 0 tj|dd	S )
a=  Prepare client's authentication response

        Prepares client's authentication response in JSON format
        Args:
            signature (bytes):  server's nonce to be signed by client.
            oci_config (dict): OCI configuration object.

        Returns:
            str: JSON string with the following format:
                 {"fingerprint": str, "signature": str, "token": base64.base64.base64}

        Raises:
            ProgrammingError: If the ephemeral security token file can't be open or the
                              token is too large.
        fingerprint)r   r   security_token_filezutf-8)encodingtokenN),:)
separators)r   decodegetr   statst_sizeOCI_SECURITY_TOKEN_MAX_SIZEr	   ProgrammingErrorOCI_SECURITY_TOKEN_TOO_LARGE	read_textOSErrorUnicodeError%OCI_SECURITY_TOKEN_FILE_NOT_AVAILABLEjsondumps)r   r   Zsignature_64auth_responser   err r3   c/var/www/shaz/venv/lib/python3.9/site-packages/mysql/connector/plugins/authentication_oci_client.py_prepare_auth_responseQ   s"    	

z)MySQLOCIAuthPlugin._prepare_auth_response)key_pathr   c                 C   s   zHt tj| d"}tj| dd}W d   n1 s<0    Y  W nB ttt	t
fy } z"td|  d| W Y d}~n
d}~0 0 |S )z+Get the private_key form the given locationrbN)passwordz2An error occurred while reading the API_KEY from "z": )openospath
expanduserr   Zload_pem_private_keyread	TypeErrorr,   
ValueErrorr   r	   r)   )r6   key_fileprivate_keyr2   r3   r3   r4   _get_private_keyy   s    (z#MySQLOCIAuthPlugin._get_private_key)r   c                 C   s   g }dd dd d}i }z~t | jp*t j| jp2d}| D ]V\}}z*|| rn||| sn|d| d W q> ty   |d|  Y q>0 q>W nF tj	tj
tjtjtjfy } z|t| W Y d	}~n
d	}~0 0 |rtd
| j d| |S )z=Get a valid OCI config from the given configuration file pathc                 S   s   t | dkS )N    )lenxr3   r3   r4   <lambda>       z:MySQLOCIAuthPlugin._get_valid_oci_config.<locals>.<lambda>c                 S   s   t jt j| S )N)r:   r;   existsr<   rE   r3   r3   r4   rG      rH   )r   r@   r   zParameter "z" is invalidzDoes not contain parameter NzInvalid oci-config-file: z. Errors found: )r   	from_filer   DEFAULT_LOCATIONr   itemsappendKeyErrorr   ZConfigFileNotFoundZInvalidConfigZInvalidKeyFilePathZInvalidPrivateKeyZProfileNotFoundstrr	   r)   )selfZ
error_listZreq_keysr   Zreq_keyZ	req_valuer2   r3   r3   r4   _get_valid_oci_config   s>    
$
z(MySQLOCIAuthPlugin._get_valid_oci_configc                 C   s   dS )zPlugin official name.Zauthentication_oci_clientr3   rP   r3   r3   r4   name   s    zMySQLOCIAuthPlugin.namec                 C   s   dS )z'Signals whether or not SSL is required.Fr3   rR   r3   r3   r4   requires_ssl   s    zMySQLOCIAuthPlugin.requires_ssl)	auth_datakwargsr   c                 K   s^   t d|t| |  }| |d }||t t	 }| 
||}t d| | S )z-Prepare authentication string for the server.zserver nonce: %s, len %dr@   zauthentication response: %s)r
   debugrD   rQ   rB   signr   ZPKCS1v15r   SHA256r5   encode)rP   rU   rV   r   rA   r   r1   r3   r3   r4   r1      s    z MySQLOCIAuthPlugin.auth_responser   )sockrU   rV   r   c                 K   s   | dd| _| dtj| _td| j | j|fi |}|du rPt	dtd|t
| || | }td| t|S )	aS  Handles server's `auth switch request` response.

        Args:
            sock: Pointer to the socket connection.
            auth_data: Plugin provided data (extracted from a packet
                       representing an `auth switch request` response).
            kwargs: Custom configuration to be passed to the auth plugin
                    when invoked. The parameters defined here will override the ones
                    defined in the auth plugin itself.

        Returns:
            packet: Last server's response after back-and-forth
                    communication.
        r   r   r   z!# oci configuration file path: %sNzGot a NULL auth responsez# request: %s size: %sz# server response packet: %s)r%   r   r   rK   r   r
   rW   r1   r	   ZInterfaceErrorrD   sendrecvbytes)rP   r[   rU   rV   responsepacketr3   r3   r4   auth_switch_response   s    

z'MySQLOCIAuthPlugin.auth_switch_response)__name__
__module____qualname____doc__r   r   __annotations__r   rO   r   rK   r   staticmethodr^   r   r5   r   rB   rQ   propertyrS   boolrT   r   r1   ra   r3   r3   r3   r4   r   J   s"   
'()&re   r/   r:   base64r   pathlibr   typingr   r   r   r    r	   r
   networkr   Zcryptography.exceptionsr   Zcryptography.hazmat.primitivesr   r   Z)cryptography.hazmat.primitives.asymmetricr   Z/cryptography.hazmat.primitives.asymmetric.typesr   ImportErrorr)   Zocir   r   r   ZAUTHENTICATION_PLUGIN_CLASSr(   r*   r.   ZOCI_PROFILE_MISSING_PROPERTIESr   r3   r3   r3   r4   <module>   sB   