a
    ’éi�$  ã                   @   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¡r’z8t|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   úa/home/Claro/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 |rüt 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   ÿþÿÿ