コード例 #1
0
    def setup(self):
        eof = self._kwargs.get('eof', False)
        self.ok_header = Datum('int<1>', 0xFE if eof is True else 0)
        self.affected_rows = Datum('int<lenenc>', self._kwargs.get('affected_rows', 0))
        self.last_insert_id = Datum('int<lenenc>', 0)
        status = self._kwargs.get('status', 0x0002)
        self.server_status = Datum('int<2>', status)
        # Datum('int<2>', 0)
        self.warning_count = Datum('int<2>', 0)

        self.state_track = None
        state_track = self._kwargs.get('state_track')   # [[key: value]]
        if state_track is not None:
            accum = b''
            status = status | SERVER_STATUS.SERVER_SESSION_STATE_CHANGED
            self.server_status = Datum('int<2>', status)
            self.state_track = b''
            self.state_track += Datum('string<lenenc>', '').toStringPacket()  # 'info' - human readable status information
            for el in state_track:
                # NOTE at this moment just system variables
                name, value = el
                part = Datum('string<lenenc>', name).toStringPacket()
                part += Datum('string<lenenc>', value).toStringPacket()
                accum += struct.pack('i', SESSION_TRACK.SESSION_TRACK_SYSTEM_VARIABLES)[:1] + struct.pack('i', len(part))[:1] + part
                # self.state_track
                # self.state_track.append(Datum('string<lenenc>', '')
            accum = struct.pack('i', len(accum))[:1] + accum
            self.state_track += accum

        self.info = Datum('string<EOF>')
コード例 #2
0
 def setup(self):
     status = 0 if 'status' not in self._kwargs else self._kwargs['status']
     seed = self._kwargs['seed']
     method = self._kwargs['method']
     self.eof_header = Datum('int<1>', int('0xfe', 0))
     self.authentication_plugin_name = Datum('string<NUL>', method)
     self.seed = Datum('string<NUL>', seed)
コード例 #3
0
class CommandPacket(Packet):
    '''
    Implementation based on description:
    https://mariadb.com/kb/en/library/1-connecting-connecting/#initial-handshake-packet
    '''
    def setup(self, length=0, count_header=1, body=''):
        if length == 0:
            return

        # self.salt=self.session.salt

        self._length = length
        self._seq = count_header
        self._body = body

        self.type = Datum('int<1>')
        buffer = body
        buffer = self.type.setFromBuff(buffer)

        if self.type.value == COMMANDS.COM_QUERY:
            self.sql = Datum('str<EOF>')
            self.sql.setFromBuff(buffer)
        else:
            self.data = Datum('str<EOF>')
            self.data.setFromBuff(buffer)

    def __str__(self):
        return str({
            'header': {
                'length': self.length,
                'seq': self.seq
            },
            'type': getConstName(COMMANDS, self.type.value),
            'vars': self.__dict__
        })
コード例 #4
0
ファイル: password_answer.py プロジェクト: yash-1002/mindsdb
    def setup(self, length=0, count_header=1, body=''):
        length = len(body)

        if length == 0:
            return
        self.password = Datum('string<NUL>')
        buffer = body
        buffer = self.password.setFromBuff(buffer)
コード例 #5
0
    def setup(self, length=0, count_header=1, body=''):
        length = len(body)

        if length == 0:
            self.password = b''
            return

        self.enc_password = Datum('string<EOF>') # 0x04
        buffer = body
        buffer = self.enc_password.setFromBuff(buffer)
        self.password = self.enc_password.value
コード例 #6
0
    def setup(self):
        err_code = 0
        if 'err_code' in self._kwargs:
            err_code = self._kwargs['err_code']

        msg = 'ERROR'
        if 'msg' in self._kwargs:
            msg = self._kwargs['msg']

        self.err_header = Datum('int<1>', 255)
        self.err_code = Datum('int<2>', err_code)
        self.msg = Datum('string<EOF>', msg)
コード例 #7
0
ファイル: command_packet.py プロジェクト: mindsdb/mindsdb
    def read_params(self, buffer, num_params):
        if not num_params > 0:
            return

        # read null-map
        null_bytes = math.floor((num_params + 7) / 8)
        nulls = []
        for i in range(null_bytes):
            b, buffer = self._read_byte(buffer)
            for i in range(8):
                nulls.append(((1 << i) & b) != 0)

        # read send-type byte
        b, buffer = self._read_byte(buffer)

        types = []
        if b == 1:
            # read types
            for i in range(num_params):
                t, buffer = self._read_byte(buffer)
                s, buffer = self._read_byte(buffer)
                types.append(dict(type=t, signed=s))

        datumtypes = {
            TYPES.MYSQL_TYPE_VAR_STRING: 'string<lenenc>',
            TYPES.MYSQL_TYPE_STRING: 'string<lenenc>',
            TYPES.MYSQL_TYPE_VARCHAR: 'string<lenenc>',
            TYPES.MYSQL_TYPE_TINY: 'int<1>',
            TYPES.MYSQL_TYPE_SHORT: 'int<2>',
            TYPES.MYSQL_TYPE_LONG: 'int<4>',
            TYPES.MYSQL_TYPE_LONGLONG: 'int<8>',
        }

        for i in range(num_params):
            if nulls[i]:
                self.parameters.append(None)
                continue

            datum_type = datumtypes.get(types[i]['type'])
            if datum_type is not None:
                x = Datum(datum_type)
                buffer = x.setFromBuff(buffer)
                value = x.value
                if isinstance(value, bytes):
                    value = value.decode()

                self.parameters.append(value)
            else:
                # NOTE at this moment all sends as strings and it works
                raise Exception(f"Unsupported type {types[i]['type']}")
コード例 #8
0
 def setup(self):
     data = self._kwargs.get('data', {})
     self.value = []
     for val in data:
         if val is None:
             self.value.append(NULL_VALUE)
         else:
             self.value.append(Datum('string<lenenc>', str(val)))
コード例 #9
0
class SwitchOutResponse(Packet):
    def setup(self, length=0, count_header=1, body=''):
        length = len(body)

        if length == 0:
            return

        self.enc_password = Datum('string<EOF>')  # 0x04
        buffer = body
        buffer = self.enc_password.setFromBuff(buffer)
コード例 #10
0
    def setup(self):
        data = self._kwargs.get('data', {})
        columns = self._kwargs.get('columns', {})

        self.value = [b'\x00']
        nulls = [0]
        for i, el in enumerate(data):
            if i > 0 and (i + 2) % 8 == 0:
                nulls.append(0)
            if el is None:
                if i < 6:
                    nulls[-1] = nulls[-1] + (1 << ((i + 2) % 8))
                else:
                    nulls[-1] = nulls[-1] + (1 << ((i - 6) % 8))
        self.value.append(bytes(nulls))

        for i, col in enumerate(columns):
            # NOTE at this moment all types sends as strings, and it works
            if data[i] is None:
                continue

            enc = ''
            col_type = col['type']
            if col_type == TYPES.MYSQL_TYPE_DOUBLE:
                enc = '<d'
            elif col_type == TYPES.MYSQL_TYPE_LONGLONG:
                enc = '<q'
            elif col_type == TYPES.MYSQL_TYPE_LONG:
                enc = '<l'
            elif col_type == TYPES.MYSQL_TYPE_FLOAT:
                enc = '<f'
            elif col_type == TYPES.MYSQL_TYPE_YEAR:
                enc = '<h'
            elif col_type == TYPES.MYSQL_TYPE_DATE:
                enc = ''
            elif col_type == TYPES.MYSQL_TYPE_TIMESTAMP:
                enc = ''
            elif col_type == TYPES.MYSQL_TYPE_DATETIME:
                enc = ''
            elif col_type == TYPES.MYSQL_TYPE_TIME:
                enc = ''
            elif col_type == TYPES.MYSQL_TYPE_NEWDECIMAL:
                enc = ''
            else:
                enc = 'string'

            if enc == '':
                raise Exception(
                    f'Column with type {col_type} cant be encripted')

            if enc == 'string':
                self.value.append(
                    Datum('string<lenenc>', str(data[i])).toStringPacket())
            else:
                self.value.append(struct.encode(enc, data[i]))[0]
コード例 #11
0
 def setup(self):
     self.status = Datum('int<1>', 0)
     self.stmt_id = Datum('int<4>', self._kwargs.get('stmt_id', 1))
     self.num_columns = Datum('int<2>', self._kwargs.get('num_columns', 0))
     self.num_params = Datum('int<2>', self._kwargs.get('num_params', 0))
     self.filler = Datum('int<1>', 0)
     self.warning_count = Datum('int<2>', 0)
コード例 #12
0
    def setup(self, length=0, count_header=1, body=''):
        if length == 0:
            return

        # self.salt=self.session.salt

        self._length = length
        self._seq = count_header
        self._body = body

        self.type = Datum('int<1>')
        buffer = body
        buffer = self.type.setFromBuff(buffer)

        if self.type.value == COMMANDS.COM_QUERY:
            self.sql = Datum('str<EOF>')
            self.sql.setFromBuff(buffer)
        else:
            self.data = Datum('str<EOF>')
            self.data.setFromBuff(buffer)
コード例 #13
0
ファイル: command_packet.py プロジェクト: mindsdb/mindsdb
    def setup(self, length=0, count_header=1, body=''):
        if length == 0:
            return

        # self.salt=self.session.salt

        self._length = length
        self._seq = count_header
        self._body = body

        self.type = Datum('int<1>')
        buffer = body
        buffer = self.type.setFromBuff(buffer)

        if self.type.value in (COMMANDS.COM_QUERY, COMMANDS.COM_STMT_PREPARE):
            self.sql = Datum('str<EOF>')
            buffer = self.sql.setFromBuff(buffer)
        elif self.type.value == COMMANDS.COM_STMT_EXECUTE:
            # https://mariadb.com/kb/en/com_stmt_execute/
            self.stmt_id = Datum('int<4>')
            buffer = self.stmt_id.setFromBuff(buffer)
            self.flags = Datum('int<1>')
            buffer = self.flags.setFromBuff(buffer)
            self.iteration_count = Datum('int<4>')
            buffer = self.iteration_count.setFromBuff(buffer)

            self.parameters = []

            prepared_stmt = self.session.prepared_stmts[self.stmt_id.value]

            if prepared_stmt['type'] == 'select':
                num_params = len(prepared_stmt['statement'].parameters)

                self.read_params(buffer, num_params)

            elif prepared_stmt['type'] in ['insert', 'delete']:
                # if prepared_stmt['type'] == 'insert':
                #     prepared_stmt['statement'].sql
                #     statement = parse_sql(prepared_stmt['statement'].sql)
                #     num_params = 0
                #     for row in statement.values:
                #         for item in row:
                #             if isinstance(item, Parameter):
                #                 num_params = num_params + 1
                # elif prepared_stmt['type'] == 'delete':
                #     num_params = prepared_stmt['statement'].sql.count('?')

                num_params = len(prepared_stmt['statement'].parameters)
                self.read_params(buffer, num_params)

        elif self.type.value == COMMANDS.COM_STMT_CLOSE:
            self.stmt_id = Datum('int<4>')
            buffer = self.stmt_id.setFromBuff(buffer)
        elif self.type.value == COMMANDS.COM_STMT_FETCH:
            self.stmt_id = Datum('int<4>')
            buffer = self.stmt_id.setFromBuff(buffer)
            self.limit = Datum('int<4>')
            buffer = self.limit.setFromBuff(buffer)
        elif self.type.value == COMMANDS.COM_INIT_DB:
            self.database = Datum('str<EOF>')
            buffer = self.database.setFromBuff(buffer)
        else:
            self.data = Datum('str<EOF>')
            buffer = self.data.setFromBuff(buffer)
コード例 #14
0
ファイル: command_packet.py プロジェクト: mindsdb/mindsdb
class CommandPacket(Packet):
    '''
    Implementation based on description:
    https://mariadb.com/kb/en/library/1-connecting-connecting/#initial-handshake-packet
    '''
    def _read_byte(self, buffer):
        b = buffer[:1]
        buffer = buffer[1:]
        b = struct.unpack('<B', b)[0]
        return b, buffer

    def read_params(self, buffer, num_params):
        if not num_params > 0:
            return

        # read null-map
        null_bytes = math.floor((num_params + 7) / 8)
        nulls = []
        for i in range(null_bytes):
            b, buffer = self._read_byte(buffer)
            for i in range(8):
                nulls.append(((1 << i) & b) != 0)

        # read send-type byte
        b, buffer = self._read_byte(buffer)

        types = []
        if b == 1:
            # read types
            for i in range(num_params):
                t, buffer = self._read_byte(buffer)
                s, buffer = self._read_byte(buffer)
                types.append(dict(type=t, signed=s))

        datumtypes = {
            TYPES.MYSQL_TYPE_VAR_STRING: 'string<lenenc>',
            TYPES.MYSQL_TYPE_STRING: 'string<lenenc>',
            TYPES.MYSQL_TYPE_VARCHAR: 'string<lenenc>',
            TYPES.MYSQL_TYPE_TINY: 'int<1>',
            TYPES.MYSQL_TYPE_SHORT: 'int<2>',
            TYPES.MYSQL_TYPE_LONG: 'int<4>',
            TYPES.MYSQL_TYPE_LONGLONG: 'int<8>',
        }

        for i in range(num_params):
            if nulls[i]:
                self.parameters.append(None)
                continue

            datum_type = datumtypes.get(types[i]['type'])
            if datum_type is not None:
                x = Datum(datum_type)
                buffer = x.setFromBuff(buffer)
                value = x.value
                if isinstance(value, bytes):
                    value = value.decode()

                self.parameters.append(value)
            else:
                # NOTE at this moment all sends as strings and it works
                raise Exception(f"Unsupported type {types[i]['type']}")

    def setup(self, length=0, count_header=1, body=''):
        if length == 0:
            return

        # self.salt=self.session.salt

        self._length = length
        self._seq = count_header
        self._body = body

        self.type = Datum('int<1>')
        buffer = body
        buffer = self.type.setFromBuff(buffer)

        if self.type.value in (COMMANDS.COM_QUERY, COMMANDS.COM_STMT_PREPARE):
            self.sql = Datum('str<EOF>')
            buffer = self.sql.setFromBuff(buffer)
        elif self.type.value == COMMANDS.COM_STMT_EXECUTE:
            # https://mariadb.com/kb/en/com_stmt_execute/
            self.stmt_id = Datum('int<4>')
            buffer = self.stmt_id.setFromBuff(buffer)
            self.flags = Datum('int<1>')
            buffer = self.flags.setFromBuff(buffer)
            self.iteration_count = Datum('int<4>')
            buffer = self.iteration_count.setFromBuff(buffer)

            self.parameters = []

            prepared_stmt = self.session.prepared_stmts[self.stmt_id.value]

            if prepared_stmt['type'] == 'select':
                num_params = len(prepared_stmt['statement'].parameters)

                self.read_params(buffer, num_params)

            elif prepared_stmt['type'] in ['insert', 'delete']:
                # if prepared_stmt['type'] == 'insert':
                #     prepared_stmt['statement'].sql
                #     statement = parse_sql(prepared_stmt['statement'].sql)
                #     num_params = 0
                #     for row in statement.values:
                #         for item in row:
                #             if isinstance(item, Parameter):
                #                 num_params = num_params + 1
                # elif prepared_stmt['type'] == 'delete':
                #     num_params = prepared_stmt['statement'].sql.count('?')

                num_params = len(prepared_stmt['statement'].parameters)
                self.read_params(buffer, num_params)

        elif self.type.value == COMMANDS.COM_STMT_CLOSE:
            self.stmt_id = Datum('int<4>')
            buffer = self.stmt_id.setFromBuff(buffer)
        elif self.type.value == COMMANDS.COM_STMT_FETCH:
            self.stmt_id = Datum('int<4>')
            buffer = self.stmt_id.setFromBuff(buffer)
            self.limit = Datum('int<4>')
            buffer = self.limit.setFromBuff(buffer)
        elif self.type.value == COMMANDS.COM_INIT_DB:
            self.database = Datum('str<EOF>')
            buffer = self.database.setFromBuff(buffer)
        else:
            self.data = Datum('str<EOF>')
            buffer = self.data.setFromBuff(buffer)

    def __str__(self):
        return str({
            'header': {
                'length': self.length,
                'seq': self.seq
            },
            'type': getConstName(COMMANDS, self.type.value),
            'vars': self.__dict__
        })
コード例 #15
0
    def setup(self, length=0, count_header=1, body=''):
        length = len(body)

        if length == 0:
            return

        self.salt = self.proxy.salt

        self._length = length
        self._seq = count_header
        self._body = body

        self.scramble_func = scramble

        self.capabilities = Datum('int<4>')
        self.max_packet_size = Datum('int<4>')
        self.reserved = Datum('string<23>')
        self.username = Datum('string<NUL>')

        self.enc_password = Datum('string<NUL>')
        self.database = Datum('string<NUL>')

        self.charset = Datum('int<1>')

        self.client_auth_plugin = Datum('string<NUL>')

        buffer = body

        if len(body) == 32 and body[9:] == (b'\x00' * 23):
            self.type = 'SSLRequest'
            buffer = self.capabilities.setFromBuff(buffer)
            buffer = self.max_packet_size.setFromBuff(buffer)
            buffer = self.charset.setFromBuff(buffer)
        else:
            self.type = 'HandshakeResponse'
            buffer = self.capabilities.setFromBuff(buffer)
            capabilities = ClentCapabilities(self.capabilities.value)
            buffer = self.max_packet_size.setFromBuff(buffer)
            buffer = self.charset.setFromBuff(buffer)
            buffer = self.reserved.setFromBuff(buffer)
            buffer = self.username.setFromBuff(buffer)

            if server_capabilities.has(CAPABILITIES.CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA) \
                    and capabilities.PLUGIN_AUTH_LENENC_CLIENT_DATA:
                self.enc_password = Datum('string<lenenc>')
                buffer = self.enc_password.setFromBuff(buffer)
            elif server_capabilities.has(CAPABILITIES.CLIENT_SECURE_CONNECTION) \
                    and capabilities.SECURE_CONNECTION:
                self.auth_resp_len = Datum('int<1>')
                buffer = self.auth_resp_len.setFromBuff(buffer)
                self.enc_password = Datum(
                    f'string<{self.auth_resp_len.value}>')
                buffer = self.enc_password.setFromBuff(buffer)
            else:
                pass_byte = Datum('int<1>')
                buffer = pass_byte.setFromBuff(buffer)

            if capabilities.CONNECT_WITH_DB:
                buffer = self.database.setFromBuff(buffer)
            if capabilities.PLUGIN_AUTH:
                buffer = self.client_auth_plugin.setFromBuff(buffer)

            # at the end is CLIENT_CONNECT_ATTRS, but we dont use it and dont parse

        self.session.username = self.username.value
コード例 #16
0
class CommandPacket(Packet):
    '''
    Implementation based on description:
    https://mariadb.com/kb/en/library/1-connecting-connecting/#initial-handshake-packet
    '''
    def _read_byte(self, buffer):
        b = buffer[:1]
        buffer = buffer[1:]
        b = struct.unpack('<B', b)[0]
        return b, buffer

    def setup(self, length=0, count_header=1, body=''):
        if length == 0:
            return

        # self.salt=self.session.salt

        self._length = length
        self._seq = count_header
        self._body = body

        self.type = Datum('int<1>')
        buffer = body
        buffer = self.type.setFromBuff(buffer)

        if self.type.value in (COMMANDS.COM_QUERY, COMMANDS.COM_STMT_PREPARE):
            self.sql = Datum('str<EOF>')
            buffer = self.sql.setFromBuff(buffer)
        elif self.type.value == COMMANDS.COM_STMT_EXECUTE:
            # https://mariadb.com/kb/en/com_stmt_execute/
            self.stmt_id = Datum('int<4>')
            buffer = self.stmt_id.setFromBuff(buffer)
            self.flags = Datum('int<1>')
            buffer = self.flags.setFromBuff(buffer)
            self.iteration_count = Datum('int<4>')
            buffer = self.iteration_count.setFromBuff(buffer)

            self.parameters = []

            statement = self.session.statements[self.stmt_id.value]
            if statement['type'] in ['insert', 'delete']:
                num_params = len(statement['insert']
                                 ) if statement['type'] == 'insert' else 1
                if num_params > 0:
                    # read null-map
                    null_bytes = math.floor((num_params + 7) / 8)
                    nulls = []
                    for i in range(null_bytes):
                        b, buffer = self._read_byte(buffer)
                        for i in range(8):
                            nulls.append(((1 << i) & b) != 0)

                    # read send-type byte
                    b, buffer = self._read_byte(buffer)

                    types = []
                    if b == 1:
                        # read types
                        for i in range(num_params):
                            t, buffer = self._read_byte(buffer)
                            s, buffer = self._read_byte(buffer)
                            types.append(dict(type=t, signed=s))

                    self.parameters = []
                    for i in range(num_params):
                        if nulls[i]:
                            self.parameters.append(None)
                            continue
                        if types[i]['type'] in (TYPES.MYSQL_TYPE_VAR_STRING,
                                                TYPES.MYSQL_TYPE_STRING):
                            x = Datum('string<lenenc>')
                            buffer = x.setFromBuff(buffer)
                            self.parameters.append(x.value.decode())
                        else:
                            # NOTE at this moment all sends as strings and it works
                            raise Exception(
                                f"Unsupported type {types[i]['type']}")

        elif self.type.value == COMMANDS.COM_STMT_CLOSE:
            self.stmt_id = Datum('int<4>')
            buffer = self.stmt_id.setFromBuff(buffer)
        elif self.type.value == COMMANDS.COM_STMT_FETCH:
            self.stmt_id = Datum('int<4>')
            buffer = self.stmt_id.setFromBuff(buffer)
            self.limit = Datum('int<4>')
            buffer = self.limit.setFromBuff(buffer)
        else:
            self.data = Datum('str<EOF>')
            buffer = self.data.setFromBuff(buffer)

    def __str__(self):
        return str({
            'header': {
                'length': self.length,
                'seq': self.seq
            },
            'type': getConstName(COMMANDS, self.type.value),
            'vars': self.__dict__
        })
コード例 #17
0
 def setup(self):
     count = self._kwargs.get('count', 0)
     self.column_count = Datum('int<lenenc>', count)
コード例 #18
0
class HandshakeResponsePacket(Packet):
    '''
    Implementation based on description:
    https://mariadb.com/kb/en/library/1-connecting-connecting/#initial-handshake-packet
    '''
    def setup(self, length=0, count_header=1, body=''):
        length = len(body)

        if length == 0:
            return

        self.salt = self.proxy.salt

        self._length = length
        self._seq = count_header
        self._body = body

        self.scramble_func = scramble

        self.capabilities = Datum('int<4>')
        self.max_packet_size = Datum('int<4>')
        self.reserved = Datum('string<23>')
        self.username = Datum('string<NUL>')

        self.enc_password = Datum('string<NUL>')
        self.database = Datum('string<NUL>')

        self.charset = Datum('int<1>')

        self.client_auth_plugin = Datum('string<NUL>')

        buffer = body

        if len(body) == 32 and body[9:] == (b'\x00' * 23):
            self.type = 'SSLRequest'
            buffer = self.capabilities.setFromBuff(buffer)
            buffer = self.max_packet_size.setFromBuff(buffer)
            buffer = self.charset.setFromBuff(buffer)
        else:
            self.type = 'HandshakeResponse'
            buffer = self.capabilities.setFromBuff(buffer)
            capabilities = ClentCapabilities(self.capabilities.value)
            buffer = self.max_packet_size.setFromBuff(buffer)
            buffer = self.charset.setFromBuff(buffer)
            buffer = self.reserved.setFromBuff(buffer)
            buffer = self.username.setFromBuff(buffer)

            if server_capabilities.has(CAPABILITIES.CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA) \
                    and capabilities.PLUGIN_AUTH_LENENC_CLIENT_DATA:
                self.enc_password = Datum('string<lenenc>')
                buffer = self.enc_password.setFromBuff(buffer)
            elif server_capabilities.has(CAPABILITIES.CLIENT_SECURE_CONNECTION) \
                    and capabilities.SECURE_CONNECTION:
                self.auth_resp_len = Datum('int<1>')
                buffer = self.auth_resp_len.setFromBuff(buffer)
                self.enc_password = Datum(
                    f'string<{self.auth_resp_len.value}>')
                buffer = self.enc_password.setFromBuff(buffer)
            else:
                pass_byte = Datum('int<1>')
                buffer = pass_byte.setFromBuff(buffer)

            if capabilities.CONNECT_WITH_DB:
                buffer = self.database.setFromBuff(buffer)
            if capabilities.PLUGIN_AUTH:
                buffer = self.client_auth_plugin.setFromBuff(buffer)

            # at the end is CLIENT_CONNECT_ATTRS, but we dont use it and dont parse

        self.session.username = self.username.value

    def __str__(self):
        return str({
            'header': {
                'length': self.length,
                'seq': self.seq
            },
            'username': self.username.value,
            'password': self.enc_password.value,
            'database': self.database.value
        })
コード例 #19
0
    def setup(self, length=0, count_header=1, body=''):
        if length == 0:
            return

        # self.salt=self.session.salt

        self._length = length
        self._seq = count_header
        self._body = body

        self.type = Datum('int<1>')
        buffer = body
        buffer = self.type.setFromBuff(buffer)

        if self.type.value in (COMMANDS.COM_QUERY, COMMANDS.COM_STMT_PREPARE):
            self.sql = Datum('str<EOF>')
            buffer = self.sql.setFromBuff(buffer)
        elif self.type.value == COMMANDS.COM_STMT_EXECUTE:
            # https://mariadb.com/kb/en/com_stmt_execute/
            self.stmt_id = Datum('int<4>')
            buffer = self.stmt_id.setFromBuff(buffer)
            self.flags = Datum('int<1>')
            buffer = self.flags.setFromBuff(buffer)
            self.iteration_count = Datum('int<4>')
            buffer = self.iteration_count.setFromBuff(buffer)

            self.parameters = []

            prepared_stmt = self.session.prepared_stmts[self.stmt_id.value]

            if prepared_stmt['type'] in ['insert', 'delete']:
                if prepared_stmt['type'] == 'insert':
                    num_params = prepared_stmt['statement'].struct[
                        'values'].count(SQL_PARAMETER)
                elif prepared_stmt['type'] == 'delete':
                    num_params = prepared_stmt['statement'].sql.count('?')

                if num_params > 0:
                    # read null-map
                    null_bytes = math.floor((num_params + 7) / 8)
                    nulls = []
                    for i in range(null_bytes):
                        b, buffer = self._read_byte(buffer)
                        for i in range(8):
                            nulls.append(((1 << i) & b) != 0)

                    # read send-type byte
                    b, buffer = self._read_byte(buffer)

                    types = []
                    if b == 1:
                        # read types
                        for i in range(num_params):
                            t, buffer = self._read_byte(buffer)
                            s, buffer = self._read_byte(buffer)
                            types.append(dict(type=t, signed=s))

                    self.parameters = []
                    for i in range(num_params):
                        if nulls[i]:
                            self.parameters.append(None)
                            continue
                        if types[i]['type'] in (TYPES.MYSQL_TYPE_VAR_STRING,
                                                TYPES.MYSQL_TYPE_STRING):
                            x = Datum('string<lenenc>')
                            buffer = x.setFromBuff(buffer)
                            self.parameters.append(x.value.decode())
                        else:
                            # NOTE at this moment all sends as strings and it works
                            raise Exception(
                                f"Unsupported type {types[i]['type']}")

        elif self.type.value == COMMANDS.COM_STMT_CLOSE:
            self.stmt_id = Datum('int<4>')
            buffer = self.stmt_id.setFromBuff(buffer)
        elif self.type.value == COMMANDS.COM_STMT_FETCH:
            self.stmt_id = Datum('int<4>')
            buffer = self.stmt_id.setFromBuff(buffer)
            self.limit = Datum('int<4>')
            buffer = self.limit.setFromBuff(buffer)
        else:
            self.data = Datum('str<EOF>')
            buffer = self.data.setFromBuff(buffer)
コード例 #20
0
 def setup(self):
     status = 0 if 'status' not in self._kwargs else self._kwargs['status']
     self.eof_header = Datum('int<1>', int('0xfe', 0))
     self.warning_count = Datum('int<2>', 0)
     self.server_status = Datum('int<2>', status)
コード例 #21
0
 def setup(self):
     capabilities = server_capabilities.value
     self.protocol_version = Datum('int<1>', 10)
     self.server_version = Datum('string<NUL>', '5.7.1-MindsDB-1.0')
     self.connection_id = Datum('int<4>', self.proxy.connection_id)
     self.scramble_1st_part = Datum('string<8>', self.proxy.salt[:8])
     self.reserved_byte = Datum('string<1>', '')
     self.server_capabilities_1st_part = Datum('int<2>', capabilities)
     self.server_default_collation = Datum('int<1>', DEFAULT_COALLITION_ID)
     self.status_flags = Datum('int<2>', SERVER_STATUS_AUTOCOMMIT)
     self.server_capabilities_2nd_part = Datum('int<2>', capabilities >> 16)
     self.wireshark_filler = Datum('int<1>', FILLER_FOR_WIRESHARK_DUMP)
     # self.wireshark_filler = Datum('int<1>', len(self.proxy.salt))
     self.reserved_filler1 = Datum('string<6>', '')
     self.reserved_filler2 = Datum('string<4>', '')
     self.scramble_2nd_part = Datum('string<NUL>', self.proxy.salt[8:])
     self.null_close = Datum('string<NUL>', DEFAULT_AUTH_METHOD)
コード例 #22
0
 def setup(self):
     self.cont = Datum('int<1>', 4)  # 0x04
コード例 #23
0
    def setup(self):
        self.catalog = Datum('string<lenenc>', 'def')
        self.schema = Datum('string<lenenc>', self._kwargs.get('schema', ''))
        self.table_alias = Datum('string<lenenc>',
                                 self._kwargs.get('table_alias', ''))
        self.table_name = Datum('string<lenenc>',
                                self._kwargs.get('table_name', ''))
        self.column_alias = Datum('string<lenenc>',
                                  self._kwargs.get('column_alias', ''))
        self.column_name = Datum('string<lenenc>',
                                 self._kwargs.get('column_name', ''))
        self.fixed_length = Datum('int<lenenc>', 0xC)
        charset = self._kwargs.get('charset',
                                   CHARSET_NUMBERS["utf8_unicode_ci"])
        self.character_set = Datum('int<2>', charset)
        self.column_length = Datum(
            'int<4>', self._kwargs.get('max_length', 0xf)
        )  # may be this? https://books.google.ru/books?id=G2YqBS9CQ0AC&lpg=PP1&hl=ru&pg=PA428#v=onepage&q&f=false
        self.column_type = Datum(
            'int<1>',
            self._kwargs.get(
                'column_type',
                self._kwargs.get('column_type', TYPES.MYSQL_TYPE_VARCHAR)))

        self.flags = Datum('int<2>', self._kwargs.get('flags', 0))
        self.decimals = Datum('int<1>', 0)

        self.unused = Datum('int<2>', 0)