a
    ’éi“2  ã                   @  s¼   d Z ddlmZ dg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mZmZmZmZmZmZ ddlmZ d	d
lmZ d	dlmZmZ d	dlmZ erªd	dlmZ G dd„ dƒZdS )z6Implementing support for MySQL Authentication Plugins.é    )ÚannotationsÚMySQLAuthenticator)ÚTYPE_CHECKINGÚAnyÚDictÚOptionalé   )ÚInterfaceErrorÚNotSupportedErrorÚget_exception)ÚAUTH_SWITCH_STATUSÚDEFAULT_CHARSET_IDÚDEFAULT_MAX_ALLOWED_PACKETÚ
ERR_STATUSÚEXCHANGE_FURTHER_STATUSÚ
MFA_STATUSÚ	OK_STATUS)ÚHandShakeTypeé   )Úlogger)ÚMySQLAuthPluginÚget_auth_plugin)ÚMySQLProtocol)Ú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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 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&d'„ZdS ))r   z$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%   úR/home/Claro/venv/lib/python3.9/site-packages/mysql/connector/aio/authentication.pyÚ__init__;   s    zMySQLAuthenticator.__init__Úboolc                 C  s   | j S )z&Signals whether or not SSL is enabled.)r    r#   r%   r%   r&   Ússl_enabledD   s    zMySQLAuthenticator.ssl_enabledzDict[str, Any]c                 C  s   | j S )aö  Custom arguments that are being provided to the authentication plugin.

        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_configI   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_configZ   s    z'MySQLAuthenticator.update_plugin_configNr   ÚstrzOptional[str]Úint)Ú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¬  Switch 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   Údebugr   r   Úgetr)   r!   )r$   r0   r1   r2   r3   r%   r%   r&   Ú_switch_auth_strategy^   s    ÿûz(MySQLAuthenticator._switch_auth_strategyr   ÚbyteszOptional[bytes])ÚsockÚpktr   c                 Ã  sè   d}|d t krÚ|| jvr"tdƒ‚t |¡\}}| j||d� t d|| jj	¡ | jj
||fi | j¤ŽI dH }|d tkr¢t |¡}| jj||fi | j¤ŽI dH }|d tkr¼t d¡ |S |d tkrÐt|ƒ‚|d7 }qt d	¡ dS )
a  Handle 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.
        r   é   z5Failed Multi Factor Authentication (invalid N factor))r3   zMFA %i factor %sNzMFA completed succesfullyr   z"MFA terminated with a no ok packet)r   r   r	   r   Zparse_auth_next_factorr7   r   r5   r!   ÚnameÚauth_switch_responser   r   Úparse_auth_more_dataÚauth_more_responser   r   r   Úwarning)r$   r9   r:   Zn_factorr0   Ú	auth_datar%   r%   r&   Ú_mfa_n_factor€   s:    
ÿÿÿ
ÿÿ


z MySQLAuthenticator._mfa_n_factorc                 Ã  s  |d t kr t|ƒdkr tdƒ‚|d t krlt d¡ t |¡\}}|  |¡ | jj	||fi | j
¤ŽI dH }|d tkrªt d¡ t |¡}| jj||fi | j
¤ŽI dH }|d tkrÊt d| jj¡ |S |d tk�rt d¡ t d	| jj¡ |  ||¡I dH S |d tk�rt|ƒ‚dS )
aü  Handle 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.
        r;   é   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 requestNzExchanging further packetsz%s completed succesfullyz$Starting multi-factor authenticationzMFA 1 factor %s)r   Úlenr
   r   r5   r   Zparse_auth_switch_requestr7   r!   r=   r   r   r>   r?   r   r<   r   rB   r   r   )r$   r9   r:   r0   rA   r%   r%   r&   Ú_handle_server_response¶   s>    ÿ

ÿÿ

ÿÿ
z*MySQLAuthenticator._handle_server_responser   r   Fr   zOptional[Dict[str, str]]zOptional[int])r9   Ú	handshaker2   Ú	password1Ú	password2Ú	password3ÚdatabaseÚcharsetÚclient_flagsr)   Úmax_allowed_packetÚauth_pluginr4   Ú
conn_attrsÚis_change_user_requestÚread_timeoutÚwrite_timeoutr   c                 Ã  sº   || _ |||dœ| _|
| _|| _tj||||||	|||||| j| jd�\}| _|r\dd|fndd|f}|j	|g|¢R Ž I dH  t
| |¡I dH ƒ}|  ||¡I dH }|du r¶tdƒd‚|S )aä  Perform 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.
            ssl_enabled: Boolean indicating whether SSL is enabled,
            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   r   é   )rF   r2   ÚpasswordrJ   rK   rL   rM   rN   r4   rO   rP   r)   r*   r   NzGot a NULL ok_pkt)r   r   r    r"   r   Z	make_authr)   r*   r!   Úwriter8   ÚreadrE   r	   )r$   r9   rF   r2   rG   rH   rI   rJ   rK   rL   r)   rM   rN   r4   rO   rP   rQ   rR   Zresponse_payloadZ	send_argsr:   Zok_pktr%   r%   r&   Úauthenticateí   s:    =óÿý
zMySQLAuthenticator.authenticate)NNr   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r'   Úpropertyr)   r*   r-   r7   rB   rE   r   r   rW   r%   r%   r%   r&   r   8   s:   	   û"6;îN)r[   Ú
__future__r   Ú__all__Útypingr   r   r   r   Úerrorsr	   r
   r   Úprotocolr   r   r   r   r   r   r   Útypesr   r   Zpluginsr   r   r   Únetworkr   r   r%   r%   r%   r&   Ú<module>   s   $	