a
    lJh9                     @  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rd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$   P/var/www/shaz/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rt|}| jj||fi | j}|d tkrtd |S |d tkrt||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rtd t|}| jj||fi | j
}|d tkrtd| jj |S |d tkrt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      zAuthentication 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 rt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   pluginsr   r   protocolr   r   r   r   r   r   r   r   typesr   networkr   r   r$   r$   r$   r%   <module>   s   (
