package server import ( "encoding/hex" "fmt" "net" "time" "wolsol-agent/auth" "wolsol-agent/magicpacket" "wolsol-agent/system" "git.secnex.io/secnex/masterlog" ) // UDPServer handles UDP connections for Magic Packets type UDPServer struct { port int authenticator *auth.Authenticator } // NewUDPServer creates a new UDP server func NewUDPServer(port int, authenticator *auth.Authenticator) *UDPServer { return &UDPServer{ port: port, authenticator: authenticator, } } // Start starts the UDP server func (s *UDPServer) Start(done chan bool) { addr, err := net.ResolveUDPAddr("udp", fmt.Sprintf(":%d", s.port)) if err != nil { masterlog.Error("Failed to resolve UDP address", map[string]interface{}{ "error": err, }) return } conn, err := net.ListenUDP("udp", addr) if err != nil { masterlog.Error("Failed to listen on UDP port", map[string]interface{}{ "error": err, "port": s.port, }) return } defer conn.Close() masterlog.Info("UDP server listening on port", map[string]interface{}{ "port": s.port, }) buffer := make([]byte, 2048) for { select { case <-done: return default: conn.SetReadDeadline(time.Now().Add(1 * time.Second)) n, clientAddr, err := conn.ReadFromUDP(buffer) if err != nil { if netErr, ok := err.(net.Error); ok && netErr.Timeout() { continue } masterlog.Error("Error reading UDP packet", map[string]interface{}{ "error": err, }) continue } packetData := buffer[:n] // Debug: Display packet content hexDump := hex.EncodeToString(packetData) // Also try to show as string (for auth part) stringPreview := "" if len(packetData) > 0 && packetData[0] < 128 { // Only show string preview if it looks like printable ASCII maxLen := len(packetData) if maxLen > 100 { maxLen = 100 } stringPreview = string(packetData[:maxLen]) } masterlog.Info("Received UDP packet", map[string]interface{}{ "bytes": n, "address": clientAddr, "hex": hexDump, "string_preview": stringPreview, }) // Check authentication and magic packet if s.isValidAuthenticatedMagicPacket(packetData) { masterlog.Info("Authenticated Magic Packet detected! Shutting down system...", map[string]interface{}{ "address": clientAddr, }) system.Shutdown() return } masterlog.Error("Invalid or unauthenticated packet", map[string]interface{}{ "address": clientAddr, }) } } } // isValidAuthenticatedMagicPacket checks if the packet contains valid authentication // followed by a valid Magic Packet func (s *UDPServer) isValidAuthenticatedMagicPacket(data []byte) bool { username, password, magicPacketData, ok := magicpacket.ExtractAuthFromPacket(data) if !ok { masterlog.Info("Packet does not contain valid auth format", map[string]interface{}{ "packet_size": len(data), }) return false } masterlog.Info("Extracted authentication from packet", map[string]interface{}{ "username": username, "password_length": len(password), "magic_packet_size": len(magicPacketData), }) // Verify authentication if !s.authenticator.Verify(username, password) { masterlog.Info("Authentication failed", map[string]interface{}{ "username": username, }) return false } masterlog.Info("Authentication successful", map[string]interface{}{ "username": username, }) // Check if it's a valid magic packet isValid := magicpacket.IsMagicPacket(magicPacketData) if !isValid { masterlog.Info("Magic packet validation failed", map[string]interface{}{ "magic_packet_size": len(magicPacketData), "magic_packet_hex": hex.EncodeToString(magicPacketData), }) } return isValid }