a
    ’éi­9  ã                   @  s®   d Z ddlmZ ddlmZmZmZmZ ddlm	Z	m
Z
mZ ddlmZ ddlmZmZ ddlmZmZmZmZmZmZmZmZ dd	lmZ erœdd
lmZ G dd„ dƒZdS )z5Implementing support for MySQL Authentication Pluginsé    )Úannotations)ÚTYPE_CHECKINGÚAnyÚDictÚOptionalé   )ÚInterfaceErrorÚNotSupportedErrorÚget_exception)Úlogger)ÚMySQLAuthPluginÚget_auth_plugin)ÚAUTH_SWITCH_STATUSÚDEFAULT_CHARSET_IDÚDEFAULT_MAX_ALLOWED_PACKETÚ
ERR_STATUSÚEXCHANGE_FURTHER_STATUSÚ
MFA_STATUSÚ	OK_STATUSÚMySQLProtocol)ÚHandShakeType)ÚMySQLSocketc                   @  sü   e Zd ZdZddœdd„Zeddœdd„ƒZed	dœd
d„ƒZd	ddœdd„Ze	de
fddddddddœdd„Zd,ddddddœdd„Zddddœd d!„Zddddœd"d#„Zd$d$d$d$de	de
dddd%ddfdd&ddddddddddd'dd(d(dd)œd*d+„ZdS )-ÚMySQLAuthenticatorz$Implements the authentication phase.ÚNone)Úreturnc                 C  s(   d| _ i | _i | _d| _d| _d| _dS )zConstructor.Ú FN)Ú	_usernameÚ
_passwordsÚ_plugin_configÚ_ssl_enabledÚ_auth_strategyÚ_auth_plugin_class©Úself© r$   úN/home/Claro/venv/lib/python3.9/site-packages/mysql/connector/authentication.pyÚ__init__8   s    zMySQLAuthenticator.__init__Úboolc                 C  s   | j S )z&Signals whether or not SSL is enabled.)r   r"   r$   r$   r%   Ússl_enabledA   s    zMySQLAuthenticator.ssl_enabledzDict[str, Any]c                 C  s   | j S )a  Custom arguments that are being provided to the authentication plugin when called.

        The parameters defined here will override the ones defined in the
        auth plugin itself.

        The plugin config is a read-only property - the plugin configuration
        provided when invoking `authenticate()` is recorded and can be queried
        by accessing this property.

        Returns:
            dict: The latest plugin configuration provided when invoking
                  `authenticate()`.
        )r   r"   r$   r$   r%   Úplugin_configF   s    z MySQLAuthenticator.plugin_config)Úconfigr   c                 C  s   | j  |¡ dS )z,Update the 'plugin_config' instance variableN)r   Úupdate)r#   r*   r$   r$   r%   Úupdate_plugin_configW   s    z'MySQLAuthenticator.update_plugin_configr   r   ÚstrzOptional[Dict[str, Any]]ÚintÚbytes)ÚsockÚhostÚssl_optionsÚcharsetÚclient_flagsÚmax_allowed_packetr   c           	   
   C  s    |du ri }t j|||d�}| |¡ t d¡ |j| d¡| d¡| d¡| dd¡| d	d¡| d
¡| d¡d�}t d¡ | ||¡ t d¡ d| _|S )aã  Sets up an SSL communication channel.

        Args:
            sock: Pointer to the socket connection.
            host: Server host name.
            ssl_options: SSL and TLS connection options (see
                         `network.MySQLSocket.build_ssl_context`).
            charset: Client charset (see [1]), only the lower 8-bits.
            client_flags: Integer representing client capabilities flags.
            max_allowed_packet: Maximum packet size.

        Returns:
            ssl_request_payload: Payload used to carry out SSL authentication.

        References:
            [1]: https://dev.mysql.com/doc/dev/mysql-server/latest/                page_protocol_basic_character_set.html#a_protocol_character_set
        N)r3   r4   r5   zBuilding SSL contextÚcaÚcertÚkeyZverify_certFZverify_identityÚtls_versionsZtls_ciphersuites)Zssl_caZssl_certZssl_keyZssl_verify_certZssl_verify_identityr9   Ztls_cipher_suiteszSwitching to SSLzSSL has been enabledT)	r   Zmake_auth_sslÚsendr   ÚdebugZbuild_ssl_contextÚgetZswitch_to_sslr   )	r#   r0   r1   r2   r3   r4   r5   Zssl_request_payloadÚssl_contextr$   r$   r%   Ú	setup_ssl[   s.    ý



ù


zMySQLAuthenticator.setup_sslNr   zOptional[str])Únew_strategy_nameÚstrategy_classÚusernameÚpassword_factorr   c                 C  sP   |du r| j }|du r| j}t d|¡ t||d�|| j |d¡| jd�| _dS )a®  Switches the authorization plugin.

        Args:
            new_strategy_name: New authorization plugin name to switch to.
            strategy_class: New authorization plugin class to switch to
                            (has higher precedence than the authorization plugin name).
            username: Username to be used - if not defined, the username
                      provided when `authentication()` was invoked is used.
            password_factor: Up to three levels of authentication (MFA) are allowed,
                             hence you can choose the password corresponding to the 1st,
                             2nd, or 3rd factor - 1st is the default.
        NzSwitching to strategy %s)Zplugin_nameÚauth_plugin_classr   )r(   )	r   r!   r   r;   r   r   r<   r(   r    )r#   r?   r@   rA   rB   r$   r$   r%   Ú_switch_auth_strategy”   s    ÿûz(MySQLAuthenticator._switch_auth_strategyzOptional[bytes])r0   Úpktr   c                 C  sÜ   d}|d t krÎ|| jvr"tdƒ‚t |¡\}}| j||d� t d|| jj	¡ | jj
||fi | j¤Ž}|d tkr–t |¡}| jj||fi | j¤Ž}|d tkr°t d¡ |S |d tkrÄt|ƒ‚|d7 }qt d¡ d	S )
a  Handles MFA (Multi-Factor Authentication) response.

        Up to three levels of authentication (MFA) are allowed.

        Args:
            sock: Pointer to the socket connection.
            pkt: MFA response.

        Returns:
            ok_packet: If last server's response is an OK packet.
            None: If last server's response isn't an OK packet and no ERROR was raised.

        Raises:
            InterfaceError: If got an invalid N factor.
            errors.ErrorTypes: If got an ERROR response.
        é   é   z5Failed Multi Factor Authentication (invalid N factor))rB   zMFA %i factor %szMFA completed succesfullyr   z"MFA terminated with a no ok packetN)r   r   r   r   Zparse_auth_next_factorrD   r   r;   r    ÚnameÚauth_switch_responser   r   Úparse_auth_more_dataÚauth_more_responser   r   r
   Úwarning)r#   r0   rE   Zn_factorr?   Ú	auth_datar$   r$   r%   Ú_mfa_n_factor¶   s:    
ÿÿÿ
ÿÿ


z MySQLAuthenticator._mfa_n_factorc                 C  s
  |d t kr t|ƒdkr tdƒ‚|d t krft d¡ t |¡\}}|  |¡ | jj	||fi | j
¤Ž}|d tkržt d¡ t |¡}| jj||fi | j
¤Ž}|d tkr¾t d| jj¡ |S |d tkrðt d¡ t d| jj¡ |  ||¡S |d tk�rt|ƒ‚d	S )
aý  Handles server's response.

        Args:
            sock: Pointer to the socket connection.
            pkt: Server's response after completing the `HandShakeResponse`.

        Returns:
            ok_packet: If last server's response is an OK packet.
            None: If last server's response isn't an OK packet and no ERROR was raised.

        Raises:
            errors.ErrorTypes: If got an ERROR response.
            NotSupportedError: If got Authentication with old (insecure) passwords.
        rG   é   z‡Authentication with old (insecure) passwords is not supported. For more information, lookup Password Hashing in the latest MySQL manualz+Server's response is an auth switch requestzExchanging further packetsz%s completed succesfullyz$Starting multi-factor authenticationzMFA 1 factor %sN)r   Úlenr	   r   r;   r   Zparse_auth_switch_requestrD   r    rI   r   r   rJ   rK   r   rH   r   rN   r   r
   )r#   r0   rE   r?   rM   r$   r$   r%   Ú_handle_server_responseì   s>    ÿ

ÿÿ

ÿÿ
z*MySQLAuthenticator._handle_server_responser   Fr   zOptional[Dict[str, str]]zOptional[int])r0   Ú	handshakerA   Ú	password1Ú	password2Ú	password3Údatabaser3   r4   r5   Úauth_pluginrC   Ú
conn_attrsÚis_change_user_requestÚread_timeoutÚwrite_timeoutr   c                 C  s¢   || _ |||dœ| _|| _tj||||||	|
||||| j| jd�\}| _|rVdd|fndd|f}|j|g|¢R Ž  t	| 
|¡ƒ}|  ||¡}|du ržtdƒd‚|S )a   Performs the authentication phase.

        During re-authentication you must set `is_change_user_request` to True.

        Args:
            sock: Pointer to the socket connection.
            handshake: Initial handshake.
            username: Account's username.
            password1: Account's password factor 1.
            password2: Account's password factor 2.
            password3: Account's password factor 3.
            database: Initial database name for the connection.
            charset: Client charset (see [1]), only the lower 8-bits.
            client_flags: Integer representing client capabilities flags.
            max_allowed_packet: Maximum packet size.
            auth_plugin: Authorization plugin name.
            auth_plugin_class: Authorization plugin class (has higher precedence
                               than the authorization plugin name).
            conn_attrs: Connection attributes.
            is_change_user_request: Whether is a `change user request` operation or not.
            read_timeout: Timeout in seconds upto which the connector should wait for
                          the server to reply back before raising an ReadTimeoutError.
            write_timeout: Timeout in seconds upto which the connector should spend to
                           send data to the server before raising an WriteTimeoutError.
        Returns:
            ok_packet: OK packet.

        Raises:
            InterfaceError: If OK packet is NULL.
            ReadTimeoutError: If the time taken for the server to reply back exceeds
                              'read_timeout' (if set).
            WriteTimeoutError: If the time taken to send data packets to the server
                               exceeds 'write_timeout' (if set).

        References:
            [1]: https://dev.mysql.com/doc/dev/mysql-server/latest/                page_protocol_basic_character_set.html#a_protocol_character_set
        )r   rF   é   )rR   rA   ÚpasswordrV   r3   r4   r5   rW   rC   rX   rY   r(   r)   r   NzGot a NULL ok_pkt)r   r   r!   r   Z	make_authr(   r)   r    r:   r/   ÚrecvrQ   r   )r#   r0   rR   rA   rS   rT   rU   rV   r3   r4   r5   rW   rC   rX   rY   rZ   r[   Zresponse_payloadZ	send_argsrE   Zok_pktr$   r$   r%   Úauthenticate#  s8    :óÿý
zMySQLAuthenticator.authenticate)NNr   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r&   Úpropertyr(   r)   r,   r   r   r>   rD   rN   rQ   r_   r$   r$   r$   r%   r   5   s@   		ù<   û"6;ïr   N)rc   Ú
__future__r   Útypingr   r   r   r   Úerrorsr   r	   r
   r   Zpluginsr   r   Úprotocolr   r   r   r   r   r   r   r   Útypesr   Únetworkr   r   r$   r$   r$   r%   Ú<module>   s   (
