Coverage for mindsdb / api / mysql / mysql_proxy / data_types / mysql_packets / handshake_response_packet.py: 12%
52 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-21 00:36 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-21 00:36 +0000
1"""
2*******************************************************
3 * Copyright (C) 2017 MindsDB Inc. <copyright@mindsdb.com>
4 *
5 * This file is part of MindsDB Server.
6 *
7 * MindsDB Server can not be copied and/or distributed without the express
8 * permission of MindsDB Inc
9 *******************************************************
10"""
12# https://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::HandshakeResponse
14from mindsdb.api.mysql.mysql_proxy.data_types.mysql_packet import Packet
15from mindsdb.api.mysql.mysql_proxy.data_types.mysql_datum import Datum
16from mindsdb.api.mysql.mysql_proxy.classes.client_capabilities import ClentCapabilities
17from mindsdb.api.mysql.mysql_proxy.libs.constants.mysql import CAPABILITIES
18from mindsdb.api.mysql.mysql_proxy.classes.server_capabilities import server_capabilities
21class HandshakeResponsePacket(Packet):
22 '''
23 Implementation based on description:
24 https://mariadb.com/kb/en/library/1-connecting-connecting/#initial-handshake-packet
25 '''
27 def setup(self, length=0, count_header=1, body=''):
28 length = len(body)
30 if length == 0:
31 return
33 self.salt = self.proxy.salt
35 self._length = length
36 self._seq = count_header
37 self._body = body
39 self.capabilities = Datum('int<4>')
40 self.max_packet_size = Datum('int<4>')
41 self.reserved = Datum('string<23>')
42 self.username = Datum('string<NUL>')
44 self.enc_password = Datum('string<NUL>')
45 self.database = Datum('string<NUL>')
47 self.charset = Datum('int<1>')
49 self.client_auth_plugin = Datum('string<NUL>')
51 buffer = body
53 if len(body) == 32 and body[9:] == (b'\x00' * 23):
54 self.type = 'SSLRequest'
55 buffer = self.capabilities.setFromBuff(buffer)
56 buffer = self.max_packet_size.setFromBuff(buffer)
57 buffer = self.charset.setFromBuff(buffer)
58 else:
59 self.type = 'HandshakeResponse'
60 buffer = self.capabilities.setFromBuff(buffer)
61 capabilities = ClentCapabilities(self.capabilities.value)
62 buffer = self.max_packet_size.setFromBuff(buffer)
63 buffer = self.charset.setFromBuff(buffer)
64 buffer = self.reserved.setFromBuff(buffer)
65 buffer = self.username.setFromBuff(buffer)
67 if server_capabilities.has(CAPABILITIES.CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA) \
68 and capabilities.PLUGIN_AUTH_LENENC_CLIENT_DATA:
69 self.enc_password = Datum('string<lenenc>')
70 buffer = self.enc_password.setFromBuff(buffer)
71 elif server_capabilities.has(CAPABILITIES.CLIENT_SECURE_CONNECTION) \
72 and capabilities.SECURE_CONNECTION:
73 self.auth_resp_len = Datum('int<1>')
74 buffer = self.auth_resp_len.setFromBuff(buffer)
75 self.enc_password = Datum(f'string<{self.auth_resp_len.value}>')
76 buffer = self.enc_password.setFromBuff(buffer)
77 else:
78 pass_byte = Datum('int<1>')
79 buffer = pass_byte.setFromBuff(buffer)
81 if capabilities.CONNECT_WITH_DB:
82 buffer = self.database.setFromBuff(buffer)
83 if capabilities.PLUGIN_AUTH:
84 buffer = self.client_auth_plugin.setFromBuff(buffer)
86 # at the end is CLIENT_CONNECT_ATTRS, but we dont use it and dont parse
88 self.session.username = self.username.value
90 def __str__(self):
91 return str({
92 'header': {'length': self.length, 'seq': self.seq},
93 'username': self.username.value,
94 'password': self.enc_password.value,
95 'database': self.database.value
96 })