258 lines
8.3 KiB
Go
258 lines
8.3 KiB
Go
package ipv4
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"time"
|
|
|
|
omd "git.loafle.net/overflow/model/discovery"
|
|
omm "git.loafle.net/overflow/model/meta"
|
|
omu "git.loafle.net/overflow/model/util"
|
|
osm "git.loafle.net/overflow/service_matcher-go"
|
|
cuej "git.loafle.net/overflow/util-go/encoding/json"
|
|
"git.loafle.net/overflow_scanner/probe/matcher"
|
|
)
|
|
|
|
func scanServiceTCP(port *omd.Port, ds *omd.DiscoverService, resultChan chan interface{}, errChan chan error, stopChan chan struct{}) bool {
|
|
hostIP := port.Host.Address
|
|
portNumber, err := cuej.NumberToInt(port.PortNumber)
|
|
if err != nil {
|
|
errChan <- fmt.Errorf("Discovery: Service scan on %s:%s error has occurred %v ", hostIP, port.PortNumber, err)
|
|
return false
|
|
}
|
|
|
|
info := osm.NewMatchInfo(hostIP, portNumber)
|
|
var s *omd.Service
|
|
|
|
scs := []serviceConnector{
|
|
&normalServiceConn{
|
|
metaCryptoType: omm.ToMetaCryptoType(omm.MetaCryptoTypeEnumNONE),
|
|
},
|
|
&tlsServiceConn{
|
|
metaCryptoType: omm.ToMetaCryptoType(omm.MetaCryptoTypeEnumTLS),
|
|
},
|
|
}
|
|
|
|
LOOP:
|
|
for i := 0; i < len(scs); i++ {
|
|
sc := scs[i]
|
|
|
|
conn, err := sc.Dial(hostIP, portNumber)
|
|
if err != nil {
|
|
errChan <- fmt.Errorf("Discovery: Service scan[%s] on %s:%d error has occurred %v ", sc.MetaCryptoType().Key, hostIP, portNumber, err)
|
|
return false
|
|
}
|
|
// olog.Logger().Debug("Discovery: Service scan connected", zap.String("hostIP", hostIP), zap.Int("portNumber", portNumber), zap.String("MetaCryptoType", sc.MetaCryptoType().Key))
|
|
|
|
buf := make([]byte, 1024)
|
|
|
|
if err := conn.SetReadDeadline(time.Now().Add(1 * time.Second)); nil != err {
|
|
// olog.Logger().Debug("Discovery: cannot set readdeadline connected", zap.String("hostIP", hostIP), zap.Int("portNumber", portNumber), zap.String("MetaCryptoType", sc.MetaCryptoType().Key))
|
|
return false
|
|
}
|
|
rn, err := conn.Read(buf)
|
|
if err != nil {
|
|
rn = 0
|
|
}
|
|
if rn != 0 {
|
|
s = hadlePrePacket(info, sc, conn, osm.NewPacket(buf, rn))
|
|
} else {
|
|
conn.Close()
|
|
s = hadlePostPacket(info, sc, nil)
|
|
}
|
|
|
|
if nil != s {
|
|
if s.Key == "HTTP" {
|
|
hsm := matcher.GetHTTPSubMatchers()
|
|
if ss := hadlePostPacket(info, sc, hsm); ss != nil {
|
|
s = ss
|
|
}
|
|
}
|
|
break LOOP
|
|
}
|
|
|
|
select {
|
|
case <-stopChan:
|
|
return false
|
|
default:
|
|
}
|
|
}
|
|
|
|
if nil != s {
|
|
s.Port = port
|
|
resultChan <- s
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func hadlePrePacket(info osm.MatchInfo, sc serviceConnector, conn net.Conn, packet *osm.Packet) *omd.Service {
|
|
defer func() {
|
|
conn.Close()
|
|
}()
|
|
|
|
// olog.Logger().Debugf("Discovery: Service scan pre packet length[%d], buf[%v]", packet.Len, packet.Buffer)
|
|
// olog.Logger().Debug("Discovery: Service scan[%s] on %s:%d pre packet length[%d]", sc.MetaCryptoType().Key, info.IP(), info.Port(), packet.Len)
|
|
|
|
ms := matcher.GetTCPMatchers(true)
|
|
buf := make([]byte, 1024)
|
|
var s *omd.Service
|
|
|
|
LOOP:
|
|
for i := 0; i < len(ms); i++ {
|
|
m := ms[i]
|
|
|
|
if err := m.Match(info, 0, packet); err == nil {
|
|
packetCount := m.PacketCount()
|
|
|
|
if 0 == packetCount {
|
|
s = discoveredService(m, sc)
|
|
break LOOP
|
|
}
|
|
|
|
found := false
|
|
|
|
for j := 0; j < packetCount; j++ {
|
|
tPacket := m.Packet(j)
|
|
// olog.Logger().Debugf("Discovery: Service scan send packet length[%d], buf[%v]", tPacket.Len, tPacket.Buffer)
|
|
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d send packet length[%d]", sc.MetaCryptoType().Key, info.IP(), info.Port(), tPacket.Len)
|
|
|
|
if err := conn.SetWriteDeadline(time.Now().Add(1 * time.Second)); nil != err {
|
|
// olog.Logger().Debugf("Discovery: cannot set writeDeadLine Service scan[%s] on %s:%d send packet length[%d]", sc.MetaCryptoType().Key, info.IP(), info.Port(), tPacket.Len)
|
|
break LOOP
|
|
}
|
|
wn, err := conn.Write(tPacket.Buffer)
|
|
if nil != err {
|
|
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d send packet error %v", sc.MetaCryptoType().Key, info.IP(), info.Port(), err)
|
|
continue LOOP
|
|
}
|
|
if wn != tPacket.Len {
|
|
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d send packet length[%d] not same with %d", sc.MetaCryptoType().Key, info.IP(), info.Port(), wn, tPacket.Len)
|
|
continue LOOP
|
|
}
|
|
|
|
if err := conn.SetReadDeadline(time.Now().Add(1 * time.Second)); nil != err {
|
|
// olog.Logger().Debugf("Discovery: cannot set readDeadLine Service scan[%s] on %s:%d send packet length[%d]", sc.MetaCryptoType().Key, info.IP(), info.Port(), tPacket.Len)
|
|
break LOOP
|
|
}
|
|
rn, err := conn.Read(buf)
|
|
if nil != err {
|
|
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d receive packet error %v", sc.MetaCryptoType().Key, info.IP(), info.Port(), err)
|
|
break LOOP
|
|
}
|
|
|
|
if err := m.Match(info, j+1, osm.NewPacket(buf, rn)); err == nil {
|
|
// olog.Logger().Debugf("Discovery: Service scan receive match length[%d], buf[%v]", rn, buf)
|
|
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d receive match length[%d]", sc.MetaCryptoType().Key, info.IP(), info.Port(), rn)
|
|
found = true
|
|
} else {
|
|
// olog.Logger().Debugf("Discovery: Service scan receive not match length[%d], buf[%v]", rn, buf)
|
|
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d receive not match length[%d]", sc.MetaCryptoType().Key, info.IP(), info.Port(), rn)
|
|
found = false
|
|
continue LOOP
|
|
}
|
|
}
|
|
|
|
if found {
|
|
s = discoveredService(m, sc)
|
|
break LOOP
|
|
}
|
|
}
|
|
}
|
|
|
|
return s
|
|
}
|
|
|
|
func hadlePostPacket(info osm.MatchInfo, sc serviceConnector, limitedMatchers []osm.Matcher) *omd.Service {
|
|
defer func() {
|
|
}()
|
|
|
|
ms := matcher.GetTCPMatchers(false)
|
|
if limitedMatchers != nil {
|
|
ms = limitedMatchers
|
|
}
|
|
|
|
buf := make([]byte, 1024)
|
|
var s *omd.Service
|
|
|
|
LOOP:
|
|
for i := 0; i < len(ms); i++ {
|
|
m := ms[i]
|
|
|
|
conn, err := sc.Dial(info.IP(), info.Port())
|
|
if err != nil {
|
|
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d socket dial error %v", sc.MetaCryptoType().Key, info.IP(), info.Port(), err)
|
|
break LOOP
|
|
}
|
|
|
|
packetCount := m.PacketCount()
|
|
for j := 0; j < packetCount; j++ {
|
|
tPacket := m.Packet(j)
|
|
// olog.Logger().Debugf("Discovery: Service scan send packet length[%d], buf[%v]", tPacket.Len, tPacket.Buffer)
|
|
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d send packet length[%d]", sc.MetaCryptoType().Key, info.IP(), info.Port(), tPacket.Len)
|
|
|
|
if err := conn.SetWriteDeadline(time.Now().Add(1 * time.Second)); nil != err {
|
|
// olog.Logger().Debugf("Discovery: cannot set writeDeadLine Service scan[%s] on %s:%d send packet length[%d]", sc.MetaCryptoType().Key, info.IP(), info.Port(), tPacket.Len)
|
|
break
|
|
}
|
|
wn, err := conn.Write(tPacket.Buffer)
|
|
if nil != err {
|
|
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d send packet error %v", sc.MetaCryptoType().Key, info.IP(), info.Port(), err)
|
|
break
|
|
}
|
|
if wn != tPacket.Len {
|
|
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d send packet length[%d] not same with %d", sc.MetaCryptoType().Key, info.IP(), info.Port(), wn, tPacket.Len)
|
|
break
|
|
}
|
|
|
|
if err := conn.SetReadDeadline(time.Now().Add(1 * time.Second)); nil != err {
|
|
// olog.Logger().Debugf("Discovery: cannot set readDeadLine Service scan[%s] on %s:%d send packet length[%d]", sc.MetaCryptoType().Key, info.IP(), info.Port(), tPacket.Len)
|
|
break
|
|
}
|
|
rn, err := conn.Read(buf)
|
|
if nil != err {
|
|
if !m.HasResponse(j) {
|
|
s = discoveredService(m, sc)
|
|
break
|
|
}
|
|
|
|
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d receive packet error %v", sc.MetaCryptoType().Key, info.IP(), info.Port(), err)
|
|
break
|
|
}
|
|
|
|
if err := m.Match(info, j, osm.NewPacket(buf, rn)); err == nil {
|
|
if packetCount-1 == j {
|
|
s = discoveredService(m, sc)
|
|
break
|
|
}
|
|
|
|
// olog.Logger().Debugf("Discovery: Service scan receive match length[%d], buf[%v]", rn, buf)
|
|
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d receive match length[%d]", sc.MetaCryptoType().Key, info.IP(), info.Port(), rn)
|
|
continue
|
|
} else {
|
|
// olog.Logger().Debugf("Discovery: Service scan receive not match length[%d], buf[%v]", rn, buf)
|
|
// olog.Logger().Debugf("Discovery: Service scan[%s] on %s:%d receive not match length[%d]", sc.MetaCryptoType().Key, info.IP(), info.Port(), rn)
|
|
break
|
|
}
|
|
}
|
|
conn.Close()
|
|
|
|
if nil != s {
|
|
break LOOP
|
|
}
|
|
}
|
|
|
|
return s
|
|
}
|
|
|
|
func discoveredService(m osm.Matcher, sc serviceConnector) *omd.Service {
|
|
return &omd.Service{
|
|
Key: m.Key(),
|
|
MetaCryptoType: sc.MetaCryptoType(),
|
|
DiscoveredDate: omu.NowPtr(),
|
|
Metadata: m.Meta(),
|
|
Name: m.Name(),
|
|
}
|
|
}
|