service_matcher-go/sqlserver/sqlserver.go

171 lines
3.4 KiB
Go
Raw Normal View History

2018-08-13 07:48:32 +00:00
package sqlserver
import (
"bytes"
"encoding/binary"
2018-08-15 07:17:18 +00:00
osm "git.loafle.net/overflow/service_matcher-go"
2018-08-13 07:48:32 +00:00
)
const (
HEADER_TYPE_PRELOGIN uint8 = 0x12
HEADER_TYPE_RESPONSE uint8 = 0x4
PL_OPTION_TOKEN_VERSION uint8 = 0x00
PL_OPTION_TOKEN_ENCRYPTION uint8 = 0x01
PL_OPTION_TOKEN_TRACEID uint8 = 0x05
PL_OPTION_TOKEN_TERMINATOR uint8 = 0xff
ENCRYPT_OFF string = "Encryption is available but off."
ENCRYPT_ON string = "Encryption is available and on."
ENCRYPT_NOT_SUP string = "Encryption is not available."
ENCRYPT_REQ string = "Encryption is required."
)
type PreloginMsg struct {
VersionToken uint8
VersionOffset uint16
VersionLength uint16
EncryptionToken uint8
EncryptionOffset uint16
EncryptionLength uint16
TraceIdToken uint8
TraceIdOffset uint16
TraceIdLength uint16
Terminator uint8
Options [7]uint8
TraceId [36]uint8
}
type mssql struct {
Type_ uint8
Status uint8
Length uint16
Channel uint16
PacketNum uint8
Window uint8
Prelogin PreloginMsg
}
type PreloginResponse struct {
Msg [256]uint8
}
type mssqlResponse struct {
Type_ uint8
Status uint8
Length uint16
Channel uint16
PacketNum uint8
Window uint8
PreLoginResp PreloginResponse
}
type SQLServerMatcher struct {
2018-08-15 07:17:18 +00:00
osm.Matchers
2018-08-13 07:48:32 +00:00
isSSL bool
}
2018-09-03 13:36:57 +00:00
func (m *SQLServerMatcher) Key() string {
2018-08-13 07:48:32 +00:00
return "SQLSERVER"
}
2018-09-03 13:36:57 +00:00
func (m *SQLServerMatcher) Name(matchCtx *osm.MatchCtx) string {
if m.isSSL {
2018-08-13 07:48:32 +00:00
return "SQL Server (SSL)"
}
return "SQL Server"
}
2018-09-03 13:41:28 +00:00
func (m *SQLServerMatcher) IsPrePacket() bool {
2018-08-13 07:48:32 +00:00
return false
}
2018-09-03 13:36:57 +00:00
func (m *SQLServerMatcher) HasResponse(matchCtx *osm.MatchCtx, index int) bool {
2018-08-13 07:48:32 +00:00
return true
}
2018-09-03 13:36:57 +00:00
func (m *SQLServerMatcher) IsError(matchCtx *osm.MatchCtx, index int, packet *osm.Packet) bool {
2018-08-13 07:48:32 +00:00
return false
}
2018-09-03 13:36:57 +00:00
func (m *SQLServerMatcher) Match(matchCtx *osm.MatchCtx, index int, packet *osm.Packet) error {
2018-08-13 07:48:32 +00:00
if packet == nil {
2018-09-03 06:42:56 +00:00
return osm.NoPacketReceivedError()
2018-08-13 07:48:32 +00:00
}
reader := new(bytes.Buffer)
2018-09-03 07:23:25 +00:00
reader.Write(packet.Buffer)
2018-08-13 07:48:32 +00:00
2018-09-03 13:36:57 +00:00
res := mssqlResponse{}
2018-08-13 07:48:32 +00:00
if err := binary.Read(reader, binary.BigEndian, &m); err != nil {
2018-09-03 06:42:56 +00:00
return osm.NotMatchedError()
2018-08-13 07:48:32 +00:00
}
2018-09-03 13:36:57 +00:00
if res.Type_ != HEADER_TYPE_RESPONSE {
2018-09-03 06:42:56 +00:00
return osm.NotMatchedError()
2018-08-13 07:48:32 +00:00
}
2018-09-03 13:36:57 +00:00
if res.Length != uint16(packet.Len) {
2018-09-03 06:42:56 +00:00
return osm.NotMatchedError()
2018-08-13 07:48:32 +00:00
}
2018-09-03 13:36:57 +00:00
switch res.PreLoginResp.Msg[res.Length-9 : res.Length-8][0] {
2018-08-13 07:48:32 +00:00
case 0:
2018-09-03 06:42:56 +00:00
return nil
2018-08-13 07:48:32 +00:00
case 1:
2018-09-03 13:36:57 +00:00
matchCtx.SetAttribute("isSSL", true)
2018-09-03 06:42:56 +00:00
return nil
2018-08-13 07:48:32 +00:00
case 2:
2018-09-03 06:42:56 +00:00
return nil
2018-08-13 07:48:32 +00:00
case 3:
2018-09-03 13:36:57 +00:00
matchCtx.SetAttribute("isSSL", true)
2018-09-03 06:42:56 +00:00
return nil
2018-08-13 07:48:32 +00:00
default:
2018-09-03 06:42:56 +00:00
return osm.NotMatchedError()
2018-08-13 07:48:32 +00:00
}
2018-09-03 06:42:56 +00:00
return osm.NotMatchedError()
2018-08-13 07:48:32 +00:00
}
2018-08-15 07:17:18 +00:00
func NewMatcher() osm.Matcher {
2018-08-13 07:48:32 +00:00
mm := &SQLServerMatcher{}
tempBuf := new(bytes.Buffer)
binary.Write(tempBuf, binary.BigEndian, mssql{})
m := mssql{
Type_: HEADER_TYPE_PRELOGIN,
Status: 0x01,
Length: uint16(len(tempBuf.Bytes())),
Channel: 0,
PacketNum: 0,
Window: 0,
Prelogin: PreloginMsg{
VersionToken: PL_OPTION_TOKEN_VERSION,
VersionOffset: 0x0010,
VersionLength: 0x0006,
EncryptionToken: PL_OPTION_TOKEN_ENCRYPTION,
EncryptionOffset: 0x0016,
EncryptionLength: 0x0001,
TraceIdToken: PL_OPTION_TOKEN_TRACEID,
TraceIdOffset: 0x0017,
TraceIdLength: 0x0024,
Terminator: PL_OPTION_TOKEN_TERMINATOR,
},
}
writer := new(bytes.Buffer)
binary.Write(writer, binary.BigEndian, m)
2018-08-15 07:17:18 +00:00
mm.AddPacket(osm.NewPacket(writer.Bytes(), writer.Len()))
2018-08-13 07:48:32 +00:00
return mm
}