首次推送

This commit is contained in:
sansen
2026-07-20 19:01:03 +08:00
parent ea01b9cf99
commit ef1bf61f9f
4484 changed files with 937163 additions and 1 deletions
@@ -0,0 +1,126 @@
package handshake
import (
"crypto/rand"
"encoding/base64"
"encoding/binary"
"math"
"time"
"github.com/honeybbq/teamspeak-go/commands"
"github.com/honeybbq/teamspeak-go/crypto"
)
const InitVersion = 1566914096 // 3.5.0 [Stable]
const (
initVersionLen = 4
initTypeLen = 1
initStepLen = 21
)
// ProcessInit1 handles the TS3INIT1 handshake steps.
func ProcessInit1(tc *crypto.Crypt, data []byte) []byte {
if data == nil || (len(data) >= 1 && data[0] == 0x7F) {
return buildInit1StartPacket()
}
switch data[0] {
case 0:
return buildInit1Step1Packet(data)
case 1:
return buildInit1Step2Packet(data)
case 2:
return buildInit1Step3Packet(data)
case 3:
return buildInit1Step4Packet(tc, data)
default:
return nil
}
}
func buildInit1StartPacket() []byte {
sendData := make([]byte, initVersionLen+initTypeLen+4+4+8)
binary.BigEndian.PutUint32(sendData[0:4], InitVersion)
sendData[4] = 0x00
nowUnix := time.Now().Unix()
nowUnix = max(nowUnix, 0)
nowUnix = min(nowUnix, int64(math.MaxUint32))
binary.BigEndian.PutUint32(sendData[5:9], uint32(nowUnix))
_, err := rand.Read(sendData[9:13])
if err != nil {
return nil
}
return sendData
}
func buildInit1Step1Packet(data []byte) []byte {
if len(data) != initStepLen {
return nil
}
sendData := make([]byte, initTypeLen+16+4)
sendData[0] = 0x01
tsRand := binary.LittleEndian.Uint32(data[initVersionLen+initTypeLen+4 : initVersionLen+initTypeLen+8])
binary.BigEndian.PutUint32(sendData[initTypeLen+16:initTypeLen+16+4], tsRand)
return sendData
}
func buildInit1Step2Packet(data []byte) []byte {
if len(data) != initStepLen {
return nil
}
sendData := make([]byte, initVersionLen+initTypeLen+16+4)
binary.BigEndian.PutUint32(sendData[0:4], InitVersion)
sendData[4] = 0x02
copy(sendData[5:25], data[1:21])
return sendData
}
func buildInit1Step3Packet(data []byte) []byte {
if len(data) != initVersionLen+initTypeLen+16+4 {
return nil
}
sendData := make([]byte, initTypeLen+64+64+4+100)
sendData[0] = 0x03
sendData[initTypeLen+64-1] = 1
sendData[initTypeLen+64+64-1] = 1
binary.BigEndian.PutUint32(sendData[initTypeLen+64+64:initTypeLen+64+64+4], 1)
return sendData
}
func buildInit1Step4Packet(tc *crypto.Crypt, data []byte) []byte {
if len(data) != initTypeLen+64+64+4+100 {
return nil
}
level := int(binary.BigEndian.Uint32(data[1+128 : 1+128+4]))
y, err := tc.SolveRsaChallenge(data, 1, level)
if err != nil {
return nil
}
tc.AlphaTmp = make([]byte, 10)
_, err = rand.Read(tc.AlphaTmp)
if err != nil {
return nil
}
cmd := commands.BuildCommandOrdered("clientinitiv", [][2]string{
{"alpha", base64.StdEncoding.EncodeToString(tc.AlphaTmp)},
{"omega", tc.Identity.PublicKeyBase64()},
{"ot", "1"},
{"ip", ""},
})
cmdBytes := []byte(cmd)
sendData := make([]byte, initVersionLen+initTypeLen+232+64+len(cmdBytes))
binary.BigEndian.PutUint32(sendData[0:4], InitVersion)
sendData[4] = 0x04
copy(sendData[5:5+232], data[1:1+232])
copy(sendData[5+232:5+232+64], y)
copy(sendData[5+232+64:], cmdBytes)
return sendData
}