-
Notifications
You must be signed in to change notification settings - Fork 48
/
handshake.go
109 lines (80 loc) · 2.28 KB
/
handshake.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package myreplication
/*
http://dev.mysql.com/doc/internals/en/connection-phase-packets.html#packet-Protocol::HandshakeV10
*/
import ()
type (
pkgHandshake struct {
protocol_version byte
server_version []byte
connection_id uint32
capabilities uint32
character_set byte
status_flags uint16
auth_plugin_data []byte
auth_plugin_name []byte
}
)
func (h *pkgHandshake) readServer(r *pack) (err error) {
r.readByte(&h.protocol_version)
if h.protocol_version != _HANDSHAKE_VERSION_10 {
panic("Support only HandshakeV10")
}
h.server_version, err = r.readNilString()
if err != nil {
return
}
r.readUint32(&h.connection_id)
h.auth_plugin_data = make([]byte, 8)
_, err = r.Buffer.Read(h.auth_plugin_data)
if err != nil {
return
}
//skip one
r.Buffer.ReadByte()
var capOne uint16
r.readUint16(&capOne)
h.capabilities = uint32(capOne)
h.character_set, _ = r.Buffer.ReadByte()
r.readUint16(&h.status_flags)
var capSecond uint16
r.readUint16(&capSecond)
h.capabilities = h.capabilities | (uint32(capSecond) << 8)
lengthAuthPluginData, _ := r.Buffer.ReadByte()
filler := make([]byte, 10)
r.Buffer.Read(filler)
if h.capabilities&_CLIENT_SECURE_CONNECTION == _CLIENT_SECURE_CONNECTION {
if lengthAuthPluginData > 0 && (13 < lengthAuthPluginData-8) {
lengthAuthPluginData -= 8
} else {
lengthAuthPluginData = 13
}
auth_plugin_data_2 := make([]byte, lengthAuthPluginData-1)
_, err = r.Buffer.Read(auth_plugin_data_2)
if err != nil {
return err
}
h.auth_plugin_data = append(h.auth_plugin_data, auth_plugin_data_2...)
}
if h.capabilities&_CLIENT_PLUGIN_AUTH == _CLIENT_PLUGIN_AUTH {
h.auth_plugin_name, err = r.readNilString()
}
return
}
func (h *pkgHandshake) writeServer(username, password string) *pack {
var encPasswd []byte = []byte{}
if h.capabilities&_CLIENT_SECURE_CONNECTION == _CLIENT_SECURE_CONNECTION {
encPasswd = encryptedPasswd(password, h.auth_plugin_data)
}
pack := newPack()
pack.writeUInt32(_CLIENT_ALL_FLAGS)
pack.writeUInt32(_MAX_PACK_SIZE)
pack.WriteByte(h.character_set)
pack.Write(make([]byte, 23, 23))
pack.writeStringNil(username)
if h.capabilities&_CLIENT_SECURE_CONNECTION == _CLIENT_SECURE_CONNECTION {
pack.WriteByte(byte(len(encPasswd)))
pack.Write(encPasswd)
}
return pack
}