3
Šãde3  ã               @   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
 ddlmZ ddlmZ y8dd	lmZ dd
lmZmZ ddlmZ ddlmZ W n  ek
r°   ejdƒd‚Y nX yddlmZmZ W n  ek
ræ   ejdƒd‚Y nX 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)ÚAnyÚDictÚOptionalé   )Úerrors)Úlogger)ÚUnsupportedAlgorithm)ÚhashesÚserialization)Úpadding)ÚPRIVATE_KEY_TYPESz'Package 'cryptography' is not installed)ÚconfigÚ
exceptionszGPackage 'oci' (Oracle Cloud Infrastructure Python SDK) is not installedé   )ÚBaseAuthPluginÚMySQLOCIAuthPluginé
   i   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dZedZe	dZ
e
ejZe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dee edœdd„ZdS )r   z2Implement the MySQL OCI IAM authentication plugin.Zauthentication_oci_clientFNÚDEFAULT)Ú	signatureÚ
oci_configÚreturnc             C   sž   t | ƒ}|d |jƒ dœ}|jdƒr�y8t|d ƒ}|jƒ jtkrJtjt	ƒ‚|j
dd�|d< W n2 ttfk
rŽ } ztjtƒ|‚W Y dd}~X nX 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   r   )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© r/   úh/var/www/agendate/envp3/lib/python3.6/site-packages/mysql/connector/plugins/authentication_oci_client.pyÚ_prepare_auth_responseP   s    

z)MySQLOCIAuthPlugin._prepare_auth_response)Úkey_pathr   c             C   sz   y4t tjj| ƒdƒ�}tj|jƒ dd�}W dQ R X W n@ ttt	t
fk
rt } ztjd| › d|› �ƒ‚W Y dd}~X nX |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%   )r2   Úkey_fileÚprivate_keyr.   r/   r/   r0   Ú_get_private_keyx   s    $z#MySQLOCIAuthPlugin._get_private_key)r   c             C   s  g }dd„ dd„ dœ}i }y†t j| jp*t j| jp2dƒ}xf|jƒ D ]Z\}}y,|| rr||| ƒ rr|jd|› d�ƒ W q@ tk
r˜   |jd|› �ƒ Y q@X q@W W nD tj	tj
tjtjtjfk
rä } z|jt|ƒƒ W Y d	d	}~X nX |�rtjd
| j› d|› �ƒ‚|S )z=Get a valid OCI config from the given configuration file pathc             S   s   t | ƒdkS )Né    )Úlen)Úxr/   r/   r0   Ú<lambda>�   s    z:MySQLOCIAuthPlugin._get_valid_oci_config.<locals>.<lambda>c             S   s   t jjt jj| ƒƒS )N)r6   r7   Úexistsr8   )rA   r/   r/   r0   rB   Ž   s    )r   r<   r   zParameter "z" is invalidzDoes not contain parameter NzInvalid oci-config-file: z. Errors found: )r   Ú	from_fileÚoci_config_fileÚDEFAULT_LOCATIONÚoci_config_profileÚitemsÚappendÚKeyErrorr   ZConfigFileNotFoundZInvalidConfigZInvalidKeyFilePathZInvalidPrivateKeyZProfileNotFoundÚstrr   r%   )ÚselfZ
error_listZreq_keysr   Zreq_keyZ	req_valuer.   r/   r/   r0   Ú_get_valid_oci_config‰   s2    
 z(MySQLOCIAuthPlugin._get_valid_oci_config)Ú	auth_datar   c             C   sd   t jd| jt| jƒƒ | jƒ }| j|d ƒ}|j| jtjƒ t	j
ƒ ƒ}| j||ƒ}t jd|ƒ |jƒ S )z-Prepare authentication string for the server.zserver nonce: %s, len %dr<   zauthentication response: %s)r	   ÚdebugZ
_auth_datar@   rM   r>   Úsignr   ZPKCS1v15r   ÚSHA256r1   Úencode)rL   rN   r   r=   r   r-   r/   r/   r0   r-   ±   s    z MySQLOCIAuthPlugin.auth_response)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Zplugin_namerK   Zrequires_sslÚboolÚcontextr   rG   r   rF   rE   ÚstaticmethodÚbytesr   r1   r   r>   rM   r   r-   r/   r/   r/   r0   r   G   s   

'(i (  )#rV   r+   r6   Úbase64r   Úpathlibr   Útypingr   r   r   Ú r   r	   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   r/   r/   r/   r0   Ú<module>   s6   
