Exemple #1
0
    def switch_to_ssl(self, ca, cert, key, verify_cert=False):
        """Switch the socket to use SSL"""
        if not self.sock:
            raise errors.InterfaceError(errno=2048)

        if verify_cert:
            cert_reqs = ssl.CERT_REQUIRED
        else:
            cert_reqs = ssl.CERT_NONE

        try:
            self.sock = ssl.wrap_socket(self.sock,
                                        keyfile=key,
                                        certfile=cert,
                                        ca_certs=ca,
                                        cert_reqs=cert_reqs,
                                        do_handshake_on_connect=False,
                                        ssl_version=ssl.PROTOCOL_TLSv1)
            self.sock.do_handshake()
        except NameError:
            raise errors.NotSupportedError(
                "Python installation has no SSL support")
        except (ssl.SSLError, IOError) as err:
            raise errors.InterfaceError(errno=2055,
                                        values=(self.get_address(),
                                                _strioerror(err)))
Exemple #2
0
    def _auth_switch_request(self, username=None, password=None):
        """Handle second part of authentication

        Raises NotSupportedError when we get the old, insecure password
        reply back. Raises any error coming from MySQL.
        """
        packet = yield from self._socket.recv()
        if packet[4] == 254 and len(packet) == 5:
            raise errors.NotSupportedError(
                "Authentication with old (insecure) passwords "
                "is not supported. For more information, lookup "
                "Password Hashing in the latest MySQL manual")
        elif packet[4] == 254:
            # AuthSwitchRequest
            (new_auth_plugin,
             auth_data) = self._protocol.parse_auth_switch_request(packet)
            auth = get_auth_plugin(new_auth_plugin)(
                auth_data, password=password, ssl_enabled=self._ssl_active)
            response = auth.auth_response()
            yield from self._socket.drain()
            if response == b'\x00':
                self._socket.send(b'')
            else:
                self._socket.send(response)
            packet = yield from self._socket.recv()
            if packet[4] != 1:
                return self._handle_ok(packet)
            else:
                auth_data = self._protocol.parse_auth_more_data(packet)
        elif packet[4] == 255:
            raise errors.get_exception(packet)
Exemple #3
0
    def cmd_reset_connection(self):
        """Resets the session state without re-authenticating

        Works only for MySQL server 5.7.3 or later.
        The result is a dictionary with OK packet information.

        Returns a dict()
        """
        if self._server_version < (5, 7, 3):
            raise errors.NotSupportedError("MySQL version 5.7.2 and "
                                           "earlier does not support "
                                           "COM_RESET_CONNECTION.")
        rd = yield from self._send_cmd(ServerCmd.RESET_CONNECTION)
        self._handle_ok(rd)
        self._post_connection()
    def add_connection(self, cnx=None):
        """Add a connection to the pool

        This method instantiates a MySQLConnection using the configuration
        passed when initializing the MySQLConnectionPool instance or using
        the set_config() method.
        If cnx is a MySQLConnection instance, it will be added to the
        queue.

        Raises PoolError when no configuration is set, when no more
        connection can be added (maximum reached) or when the connection
        can not be instantiated.
        """
        with CONNECTION_POOL_LOCK:
            if not self._cnx_config:
                raise errors.PoolError(
                    "Connection configuration not available")

            if self._cnx_queue.full():
                raise errors.PoolError(
                    "Failed adding connection; queue is full")

            if not cnx:
                cnx = AioMySQLConnection(**self._cnx_config)
                try:
                    if (self._reset_session and self._cnx_config['compress']
                            and cnx.get_server_version() < (5, 7, 3)):
                        raise errors.NotSupportedError("Pool reset session is "
                                                       "not supported with "
                                                       "compression for MySQL "
                                                       "server version 5.7.2 "
                                                       "or earlier.")
                except KeyError:
                    pass

                # pylint: disable=W0201,W0212
                cnx._pool_config_version = self._config_version
                # pylint: enable=W0201,W0212
            else:
                if not isinstance(cnx, AioMySQLConnection):
                    raise errors.PoolError(
                        "Connection instance not subclass of AioMySQLConnection.")

            self._queue_connection(cnx)
Exemple #5
0
    def switch_to_ssl(self, ca, cert, key):
        """Switch the socket to use SSL"""
        if not self.sock:
            raise errors.InterfaceError(errno=2048)

        try:
            self.sock = ssl.wrap_socket(self.sock,
                                        keyfile=key,
                                        certfile=cert,
                                        ca_certs=ca,
                                        cert_reqs=ssl.CERT_NONE,
                                        do_handshake_on_connect=False,
                                        ssl_version=ssl.PROTOCOL_TLSv1)
            self.sock.do_handshake()
        except NameError:
            raise errors.NotSupportedError(
                "Python installation has no SSL support")
        except ssl.SSLError, err:
            raise errors.InterfaceError("SSL error: %s" % err)
Exemple #6
0
    def reset_session(self, user_variables=None, session_variables=None):
        """Clears the current active session

        This method resets the session state, if the MySQL server is 5.7.3
        or later active session will be reset without re-authenticating.
        For other server versions session will be reset by re-authenticating.

        It is possible to provide a sequence of variables and their values to
        be set after clearing the session. This is possible for both user
        defined variables and session variables.
        This method takes two arguments user_variables and session_variables
        which are dictionaries.

        Raises OperationalError if not connected, InternalError if there are
        unread results and InterfaceError on errors.
        """
        cn = yield from self.is_connected()
        if not cn:
            raise errors.OperationalError("MySQL Connection not available.")

        try:
            yield from self.cmd_reset_connection()
        except errors.NotSupportedError:
            if self._compress:
                raise errors.NotSupportedError(
                    "Reset session is not supported with compression for "
                    "MySQL server version 5.7.2 or earlier.")
            else:
                yield from self.cmd_change_user(self._user, self._password,
                                     self._database, self._charset_id)

        cur = yield from self.cursor()
        if user_variables:
            for key, value in user_variables.items():
                yield from cur.execute("SET @`{0}` = %s".format(key), (value,))
        if session_variables:
            for key, value in session_variables.items():
                yield from cur.execute("SET SESSION `{0}` = %s".format(key), (value,))
Exemple #7
0
    def cmd_change_user(self, username='', password='', database='',
                        charset=33):
        """Change the current logged in user

        This method allows to change the current logged in user information.
        The result is a dictionary with OK packet information.

        Returns a dict()
        """
        if self.unread_result:
            raise errors.InternalError("Unread result found.")

        if self._compress:
            raise errors.NotSupportedError("Change user is not supported with "
                                           "compression.")

        packet = yield from self._protocol.make_change_user(
            handshake=self._handshake,
            username=username, password=password, database=database,
            charset=charset, client_flags=self._client_flags,
            ssl_enabled=self._ssl_active,
            auth_plugin=self._auth_plugin)
        yield from self._socket.drain()
        self._socket.send(packet, 0)

        ok_packet = yield from self._auth_switch_request(username, password)

        try:
            if not (self._client_flags & ClientFlag.CONNECT_WITH_DB) \
                    and database:
                yield from self.cmd_init_db(database)
        except:
            raise

        self._charset_id = charset
        self._post_connection()

        return ok_packet
    def callproc(self, *args, **kwargs):
        """Calls a stored procedure

        Not supported with MySQLCursorPrepared.
        """
        raise errors.NotSupportedError()