prudpv1: Add signature calculator functions settings

This commit is contained in:
Daniel López Guimaraes 2024-02-24 11:22:50 +00:00
parent cdcc2bbb9d
commit 3f3d8da0ba
No known key found for this signature in database
GPG key ID: 6AC74DE3DEF050E0
2 changed files with 58 additions and 44 deletions

View file

@ -309,51 +309,11 @@ func (p *PRUDPPacketV1) encodeOptions() []byte {
}
func (p *PRUDPPacketV1) calculateConnectionSignature(addr net.Addr) ([]byte, error) {
var ip net.IP
var port int
switch v := addr.(type) {
case *net.UDPAddr:
ip = v.IP.To4()
port = v.Port
default:
return nil, fmt.Errorf("Unsupported network type: %T", addr)
}
portBytes := make([]byte, 2)
binary.BigEndian.PutUint16(portBytes, uint16(port))
data := append(ip, portBytes...)
hash := hmac.New(md5.New, p.server.PRUDPv1ConnectionSignatureKey)
hash.Write(data)
return hash.Sum(nil), nil
return p.server.PRUDPV1Settings.ConnectionSignatureCalculator(p, addr)
}
func (p *PRUDPPacketV1) calculateSignature(sessionKey, connectionSignature []byte) []byte {
accessKeyBytes := []byte(p.server.AccessKey)
options := p.encodeOptions()
header := p.encodeHeader()
accessKeySum := sum[byte, uint32](accessKeyBytes)
accessKeySumBytes := make([]byte, 4)
binary.LittleEndian.PutUint32(accessKeySumBytes, accessKeySum)
key := md5.Sum(accessKeyBytes)
mac := hmac.New(md5.New, key[:])
if p.packetType == ConnectPacket && p.server.PRUDPV1Settings.LegacyConnectionSignature {
connectionSignature = make([]byte, 0)
}
mac.Write(header[4:])
mac.Write(sessionKey)
mac.Write(accessKeySumBytes)
mac.Write(connectionSignature)
mac.Write(options)
mac.Write(p.payload)
return mac.Sum(nil)
return p.server.PRUDPV1Settings.SignatureCalculator(p, sessionKey, connectionSignature)
}
// NewPRUDPPacketV1 creates and returns a new PacketV1 using the provided Client and stream
@ -393,3 +353,51 @@ func NewPRUDPPacketsV1(server *PRUDPServer, connection *PRUDPConnection, readStr
return packets, nil
}
func defaultPRUDPv1ConnectionSignature(packet *PRUDPPacketV1, addr net.Addr) ([]byte, error) {
var ip net.IP
var port int
switch v := addr.(type) {
case *net.UDPAddr:
ip = v.IP.To4()
port = v.Port
default:
return nil, fmt.Errorf("Unsupported network type: %T", addr)
}
portBytes := make([]byte, 2)
binary.BigEndian.PutUint16(portBytes, uint16(port))
data := append(ip, portBytes...)
hash := hmac.New(md5.New, packet.server.PRUDPv1ConnectionSignatureKey)
hash.Write(data)
return hash.Sum(nil), nil
}
func defaultPRUDPv1CalculateSignature(packet *PRUDPPacketV1, sessionKey, connectionSignature []byte) []byte {
accessKeyBytes := []byte(packet.server.AccessKey)
options := packet.encodeOptions()
header := packet.encodeHeader()
accessKeySum := sum[byte, uint32](accessKeyBytes)
accessKeySumBytes := make([]byte, 4)
binary.LittleEndian.PutUint32(accessKeySumBytes, accessKeySum)
key := md5.Sum(accessKeyBytes)
mac := hmac.New(md5.New, key[:])
if packet.packetType == ConnectPacket && packet.server.PRUDPV1Settings.LegacyConnectionSignature {
connectionSignature = make([]byte, 0)
}
mac.Write(header[4:])
mac.Write(sessionKey)
mac.Write(accessKeySumBytes)
mac.Write(connectionSignature)
mac.Write(options)
mac.Write(packet.payload)
return mac.Sum(nil)
}

View file

@ -1,15 +1,21 @@
package nex
import "net"
// TODO - We can also breakout the decoding/encoding functions here too, but that would require getters and setters for all packet fields
// PRUDPV1Settings defines settings for how to handle aspects of PRUDPv1 packets
type PRUDPV1Settings struct {
LegacyConnectionSignature bool
LegacyConnectionSignature bool
ConnectionSignatureCalculator func(packet *PRUDPPacketV1, addr net.Addr) ([]byte, error)
SignatureCalculator func(packet *PRUDPPacketV1, sessionKey, connectionSignature []byte) []byte
}
// NewPRUDPV1Settings returns a new PRUDPV1Settings
func NewPRUDPV1Settings() *PRUDPV1Settings {
return &PRUDPV1Settings{
LegacyConnectionSignature: false,
LegacyConnectionSignature: false,
ConnectionSignatureCalculator: defaultPRUDPv1ConnectionSignature,
SignatureCalculator: defaultPRUDPv1CalculateSignature,
}
}