Documentation ¶
Index ¶
- Constants
- Variables
- func CheckPacketLength(expected int, packet []byte) error
- func GetLenEncodedIntegerSize(firstByte byte) byte
- func GetPacketHeader(r *bytes.Reader) (s []byte, e error)
- func GetPacketType(packet []byte) byte
- func InjectCredentials(clientHandshake *HandshakeResponse41, salt []byte, username string, ...) (err error)
- func NativePassword(password []byte, salt []byte) (nativePassword []byte, err error)
- func PackHandshakeResponse41(clientHandshake *HandshakeResponse41) (packet []byte, err error)
- func ProcessHandshake(client net.Conn, mysql net.Conn) (*HandshakeV10, *HandshakeResponse41, error)
- func ProxyPacket(src, dst net.Conn) ([]byte, error)
- func ReadEOFLengthString(data []byte) string
- func ReadErrMessage(errPacket []byte) string
- func ReadLenEncodedInteger(r *bytes.Reader) (value uint64, err error)
- func ReadLenEncodedString(r *bytes.Reader) (string, uint64, error)
- func ReadNullTerminatedBytes(r *bytes.Reader) (str []byte)
- func ReadNullTerminatedString(r *bytes.Reader) string
- func ReadPacket(conn net.Conn) ([]byte, error)
- func ReadPrepareResponse(conn net.Conn) ([]byte, byte, error)
- func ReadResponse(conn net.Conn, deprecateEOF bool) ([]byte, byte, error)
- func ReadShowFieldsResponse(conn net.Conn) ([]byte, byte, error)
- func ReadUint24(b []byte) (uint32, error)
- func RemoveSSLFromHandshakeV10(packet []byte) ([]byte, error)
- func UnpackErrResponse(data []byte) error
- func UpdateHeaderPayloadLength(origHeader []byte, diff int32) (header []byte, err error)
- func WritePacket(pkt []byte, conn net.Conn) (int, error)
- func WriteUint24(u uint32) (b []byte)
- type ConnSettings
- type Error
- type ErrorContainer
- type HandshakeResponse41
- type HandshakeV10
- type MessageBuffer
- func (message *MessageBuffer) Bytes() []byte
- func (message *MessageBuffer) ReadByte() (byte, error)
- func (message *MessageBuffer) ReadInt32() (value int32, err error)
- func (message *MessageBuffer) ReadString() (string, error)
- func (message *MessageBuffer) ResetLength(offset int)
- func (message *MessageBuffer) WriteByte(value byte) error
- func (message *MessageBuffer) WriteInt32(value int32) (err error)
- func (message *MessageBuffer) WriteString(value string) (int, error)
- type OkResponse
Constants ¶
const ( ComQuery byte ComFieldList ComStmtPrepare ComStmtExecute ComStmtClose )
Protocol commands
const ( ClientLongPassword uint32 = 1 << iota ClientFoundRows ClientLongFlag ClientConnectWithDB ClientNoSchema ClientCompress ClientODBC ClientLocalFiles ClientIgnoreSpace ClientProtocol41 ClientInteractive ClientSSL ClientIgnoreSIGPIPE ClientTransactions ClientReserved ClientSecureConnection ClientMultiStatements ClientMultiResults ClientPSMultiResults ClientPluginAuth ClientConnectAttrs ClientPluginAuthLenEncClientData ClientCanHandleExpiredPasswords ClientSessionTrack ClientDeprecateEOF )
Capability flags
const ( CRUnknownError = 2000 // CRSSLConnectionError is CR_SSL_CONNECTION_ERROR CRSSLConnectionError = 2026 )
MySQL Error Codes
const (
// ErrorCodeInternalError indicates an unspecified internal error.
ErrorCodeInternalError = "HY000"
)
const (
ResponseErr = 0xff
)
Random constants
Variables ¶
var ErrFieldTypeNotImplementedYet = errors.New("Protocol: Required field type not implemented yet")
ErrFieldTypeNotImplementedYet is for field types that are not yet implemented
var ErrInvalidPacketLength = errors.New("Protocol: Invalid packet length")
ErrInvalidPacketLength is for invalid packet lengths
var ErrInvalidPacketType = errors.New("Protocol: Invalid packet type")
ErrInvalidPacketType is for invalid packet types
var ErrNoTLS = Error{ Code: CRSSLConnectionError, SQLState: ErrorCodeInternalError, Message: "SSL connection error: SSL is required but the server doesn't support it", }
ErrNoTLS is a MySQL protocol error raised when SSL is required but the server doesn't support it.
Functions ¶
func CheckPacketLength ¶
CheckPacketLength checks if packet length meets expected value
func GetLenEncodedIntegerSize ¶
GetLenEncodedIntegerSize returns bytes count for length encoded integer determined by it's 1st byte
func GetPacketHeader ¶
GetPacketHeader rewinds reader to packet payload
func GetPacketType ¶
GetPacketType extracts the PacketType byte Part of basic packet structure shown below.
int<3> PacketLength int<1> PacketNumber int<1> PacketType (0xFF) ... more ...
func InjectCredentials ¶
func InjectCredentials(clientHandshake *HandshakeResponse41, salt []byte, username string, password string) (err error)
InjectCredentials takes in a HandshakeResponse41 from the client, the salt from the server, and a username / password, and uses the salt from the server handshake to inject the username / password credentials into the client handshake response
func NativePassword ¶
NativePassword calculates native password expected by server in HandshakeResponse41 https://dev.mysql.com/doc/internals/en/secure-password-authentication.html#packet-Authentication::Native41 SHA1( password ) XOR SHA1( "20-bytes random data from server" <concat> SHA1( SHA1( password ) ) )
func PackHandshakeResponse41 ¶
func PackHandshakeResponse41(clientHandshake *HandshakeResponse41) (packet []byte, err error)
PackHandshakeResponse41 takes in a HandshakeResponse41 object and returns a handshake response packet
func ProcessHandshake ¶
func ProcessHandshake(client net.Conn, mysql net.Conn) (*HandshakeV10, *HandshakeResponse41, error)
ProcessHandshake handles handshake between server and client. Returns server and client handshake responses
func ReadEOFLengthString ¶
ReadEOFLengthString returns parsed EOF-length string. EOF-length strings are those strings whose length will be calculated by the packet remaining length. See https://mariadb.com/kb/en/mariadb/protocol-data-types/#end-of-file-length-strings
func ReadErrMessage ¶
ReadErrMessage reads the message in an error packet
func ReadLenEncodedInteger ¶
ReadLenEncodedInteger returns parsed length-encoded integer and it's offset. See https://mariadb.com/kb/en/mariadb/protocol-data-types/#length-encoded-integers
func ReadLenEncodedString ¶
ReadLenEncodedString returns parsed length-encoded string and it's length. Length-encoded strings are prefixed by a length-encoded integer which describes the length of the string, followed by the string value. See https://mariadb.com/kb/en/mariadb/protocol-data-types/#length-encoded-strings
func ReadNullTerminatedBytes ¶
ReadNullTerminatedBytes reads bytes from reader until 0x00 byte
func ReadNullTerminatedString ¶
ReadNullTerminatedString reads bytes from reader until 0x00 byte See https://mariadb.com/kb/en/mariadb/protocol-data-types/#null-terminated-strings
func ReadPrepareResponse ¶
ReadPrepareResponse reads response from MySQL server for COM_STMT_PREPARE query issued by client. ...
func ReadResponse ¶
ReadResponse reads the response
func ReadShowFieldsResponse ¶
ReadShowFieldsResponse reads the response with deprecateEof set to true
func ReadUint24 ¶
ReadUint24 takes in a byte slice and returns a uint32
func RemoveSSLFromHandshakeV10 ¶
RemoveSSLFromHandshakeV10 removes Client SSL Capability from Server Handshake Packet. Secretless needs to do this to force the client to communicate with Secretless without using SSL. That half of the connection is insecure by design. Secretless then (usually) adds SSL for the other half of the communication -- between Secretless and the MySQL server.
func UnpackErrResponse ¶
UnpackErrResponse decodes ERR_Packet from server. Part of basic packet structure shown below.
int<3> PacketLength int<1> PacketNumber int<1> PacketType (0xFF) int<2> ErrorCode if clientCapabilities & clientProtocol41
{ string<1> SqlStateMarker (#) string<5> SqlState }
string<EOF> Error
func UpdateHeaderPayloadLength ¶
UpdateHeaderPayloadLength takes in a 4 byte header and a difference in length, and returns a new header
func WriteUint24 ¶
WriteUint24 takes in a uint32 and returns a byte slice
Types ¶
type ConnSettings ¶
ConnSettings contains the connection settings
func (*ConnSettings) DeprecateEOFSet ¶
func (h *ConnSettings) DeprecateEOFSet() bool
DeprecateEOFSet checks whether ClientDeprecateEOF is set on the client or server
type Error ¶
Error is a MySQL processing error.
func NewGenericError ¶
NewGenericError returns a MySQL protocol specific error, to handle cases that don't fit neatly into the MySQL code categories. This makes sense, since a Go error, eg, is not a true "protocol" error but instead something resulting from Secretless's role as a proxy, which MySQL is unaware of.
That said, we should try to use MySQL specific error codes wherever we can, so that client error messages will be more meaningful.
TODO: Replace instances of generic error with specific MySQL error codes.
func (Error) GetPacket ¶
GetPacket formats an Error into a protocol message. https://dev.mysql.com/doc/internals/en/packet-ERR_Packet.html
type ErrorContainer ¶
type ErrorContainer interface {
GetPacket() []byte
}
ErrorContainer interface makes it possible to have Go errors that can contain rich protocol specific information and have the smarts to encode themselves into a MYSQL error packet
type HandshakeResponse41 ¶
type HandshakeResponse41 struct { Header []byte CapabilityFlags uint32 MaxPacketSize uint32 ClientCharset uint8 Username string AuthLength int64 AuthPluginName string AuthResponse []byte Database string PacketTail []byte }
HandshakeResponse41 represents handshake response packet sent by 4.1+ clients supporting clientProtocol41 capability, if the server announced it in its initial handshake packet. See http://imysql.com/mysql-internal-manual/connection-phase-packets.html#packet-Protocol::HandshakeResponse41
The format of the header is also described here:
https://dev.mysql.com/doc/internals/en/mysql-packet.html +-------------+----------------+---------------------------------------------+ | Type | Name | Description | +-------------+----------------+---------------------------------------------+ | int<3> | payload_length | Length of the payload. The number of bytes | | | | in the packet beyond the initial 4 bytes | | | | that make up the packet header. | | int<1> | sequence_id | Sequence ID | | string<var> | payload | [len=payload_length] payload of the packet | +-------------+----------------+---------------------------------------------+
func UnpackHandshakeResponse41 ¶
func UnpackHandshakeResponse41(packet []byte) (*HandshakeResponse41, error)
UnpackHandshakeResponse41 decodes handshake response packet send by client. TODO: Add packet struct comment TODO: Add packet length check
type HandshakeV10 ¶
type HandshakeV10 struct { ProtocolVersion byte ServerVersion string ConnectionID uint32 ServerCapabilities uint32 AuthPlugin string Salt []byte }
HandshakeV10 represents sever's initial handshake packet See https://mariadb.com/kb/en/mariadb/1-connecting-connecting/#initial-handshake-packet
func UnpackHandshakeV10 ¶
func UnpackHandshakeV10(packet []byte) (*HandshakeV10, error)
UnpackHandshakeV10 decodes initial handshake request from server. Basic packet structure shown below. See http://imysql.com/mysql-internal-manual/connection-phase-packets.html#packet-Protocol::HandshakeV10
int<3> PacketLength int<1> PacketNumber int<1> ProtocolVersion string<NUL> ServerVersion int<4> ConnectionID string<8> AuthPluginDataPart1 (authentication seed) string<1> Reserved (always 0x00) int<2> ServerCapabilities (1st part) int<1> ServerDefaultCollation int<2> StatusFlags int<2> ServerCapabilities (2nd part) if capabilities & clientPluginAuth
{ int<1> AuthPluginDataLength }
else
{ int<1> 0x00 }
string<10> Reserved (all 0x00) if capabilities & clientSecureConnection
{ string[$len] AuthPluginDataPart2 ($len=MAX(13, AuthPluginDataLength - 8)) }
if capabilities & clientPluginAuth
{ string[NUL] AuthPluginName }
type MessageBuffer ¶
type MessageBuffer struct {
// contains filtered or unexported fields
}
MessageBuffer is a variable-sized byte buffer used to read and write msgs
A separate instance of a MessageBuffer should be use for reading and writing.
func NewMessageBuffer ¶
func NewMessageBuffer(message []byte) *MessageBuffer
NewMessageBuffer creates and intializes a new MessageBuffer using message as its initial contents.
func (*MessageBuffer) Bytes ¶
func (message *MessageBuffer) Bytes() []byte
Bytes gets the contents of the message buffer. This function is only useful after 'Write' operations as the underlying implementation will return the 'unread' portion of the buffer.
func (*MessageBuffer) ReadByte ¶
func (message *MessageBuffer) ReadByte() (byte, error)
ReadByte reads a byte from the message buffer.
This function will read and return the next available byte from the message buffer.
func (*MessageBuffer) ReadInt32 ¶
func (message *MessageBuffer) ReadInt32() (value int32, err error)
ReadInt32 reads an int32 from the message buffer.
This function will read the next 4 available bytes from the message buffer and return them as an int32.
panic on error.
func (*MessageBuffer) ReadString ¶
func (message *MessageBuffer) ReadString() (string, error)
ReadString reads a string from the message buffer.
This function will read and return the next Null terminated string from the message buffer.
func (*MessageBuffer) ResetLength ¶
func (message *MessageBuffer) ResetLength(offset int)
ResetLength will reset the message length for the message.
func (*MessageBuffer) WriteByte ¶
func (message *MessageBuffer) WriteByte(value byte) error
WriteByte will write the specified byte to the message buffer.
func (*MessageBuffer) WriteInt32 ¶
func (message *MessageBuffer) WriteInt32(value int32) (err error)
WriteInt32 will write a 4 byte int32 to the message buffer.
func (*MessageBuffer) WriteString ¶
func (message *MessageBuffer) WriteString(value string) (int, error)
WriteString will write a NULL terminated string to the buffer. It is assumed that the incoming string has *NOT* been NULL terminated.
type OkResponse ¶
type OkResponse struct { PacketType byte AffectedRows uint64 LastInsertID uint64 StatusFlags uint16 Warnings uint16 }
OkResponse represents packet sent from the server to the client to signal successful completion of a command https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_basic_ok_packet.html
func UnpackOkResponse ¶
func UnpackOkResponse(packet []byte) (*OkResponse, error)
UnpackOkResponse decodes OK_Packet from server. Part of basic packet structure shown below.
int<3> PacketLength int<1> PacketNumber int<1> PacketType (0x00 or 0xFE) int<lenenc> AffectedRows int<lenenc> LastInsertID ... more ...