freematics-traccar-encrypted/server/server.go

120 lines
2.9 KiB
Go

package main
import (
"encoding/hex"
"flag"
"fmt"
"github.com/sirupsen/logrus"
"gopkg.in/yaml.v2"
"net"
"os"
"server/encryption"
"server/logging"
)
type Config struct {
Destinations map[string]Destination `yaml:"destinations"`
ChachaKey string `yaml:"chacha_key"`
}
type Destination struct {
Address string `yaml:"address"`
Port int `yaml:"port"`
}
func main() {
configFile := flag.String("config", "", "Path to the configuration file")
flag.Parse()
logging.InitLogger(logrus.InfoLevel)
logger := logging.GetLogger()
if *configFile == "" {
logger.Fatalln("Please provide a configuration file")
}
data, err := os.ReadFile(*configFile)
if err != nil {
logger.Fatalln("Error reading the configuration file:", err)
}
var config Config
err = yaml.Unmarshal(data, &config)
if err != nil {
logger.Fatalln("Error parsing the configuration file:", err)
}
// Validate chacha key
if len(config.ChachaKey) != 64 {
logger.Fatalln("Invalid chacha_key. Should be 64 characters long")
}
// Validate destinations
for port, dest := range config.Destinations {
if dest.Address == "" || dest.Port == 0 {
logger.Fatalln("Invalid destination for port %s\n", port)
}
}
key, _ := hex.DecodeString(config.ChachaKey)
for port, dest := range config.Destinations {
go func(port string, dest Destination) {
addr, err := net.ResolveUDPAddr("udp", ":"+port)
if err != nil {
logger.Fatalln("Error resolving address:", err)
return
}
conn, err := net.ListenUDP("udp", addr)
if err != nil {
logger.Fatalln("Error listening on UDP:", err)
return
}
defer conn.Close()
// Address to forward the decrypted messages
forwardAddr, err := net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", dest.Address, dest.Port))
if err != nil {
logger.Fatalln("Error resolving forward address:", err)
return
}
forwardConn, err := net.DialUDP("udp", nil, forwardAddr)
if err != nil {
logger.Errorln("Error dialing to forward address:", err)
return
}
defer forwardConn.Close()
logger.Infof("Listening on 0.0.0.0:%s\n", port)
for {
buf := make([]byte, 1500) // 1500 is the standard internet MTU
n, addr, err := conn.ReadFromUDP(buf)
if err != nil {
logger.Errorln("Error reading from UDP:", err)
return
}
// Forward the decrypted message
go func(addr *net.UDPAddr, buf []byte, n int) {
plaintext, err := encryption.Decrypt(key, buf[:n]) // Use only the part of the buffer that has data
if err != nil {
fmt.Println("Error decrypting message:", err)
return
}
_, err = forwardConn.Write(plaintext)
if err != nil {
fmt.Println("Error forwarding message:", err)
return
}
logger.Infof("%s -> %s:%d -- %s\n", addr.IP, dest.Address, dest.Port, string(plaintext))
}(addr, buf, n)
}
}(port, dest)
}
select {}
}