fix(shutdown): Fix shutdown command

This commit is contained in:
Björn Benouarets
2025-11-11 20:38:49 +01:00
parent 8ed56f7ba0
commit b8964d7763
4 changed files with 115 additions and 21 deletions

View File

@@ -60,25 +60,52 @@ func ExtractAuthFromPacket(data []byte) (string, string, []byte, bool) {
return "", "", nil, false return "", "", nil, false
} }
// Extract authentication part // Find the first colon after "AUTH:" (end of username)
authEnd := strings.Index(dataStr[len(AuthPrefix):], ":") searchStart := len(AuthPrefix)
if authEnd == -1 { firstColon := strings.Index(dataStr[searchStart:], ":")
if firstColon == -1 {
return "", "", nil, false return "", "", nil, false
} }
authEnd += len(AuthPrefix) firstColon += searchStart
// Find the second colon after the first one (end of password)
secondColon := strings.Index(dataStr[firstColon+1:], ":")
if secondColon == -1 {
// If no second colon, the password might be followed directly by binary data
// In this case, we need to find where the magic packet starts (6 bytes of 0xFF)
// Look for the magic packet header starting after the password
passwordEnd := len(dataStr)
for i := firstColon + 1; i < len(data) && i < firstColon+100; i++ {
// Check if we found the magic packet header (6 consecutive 0xFF bytes)
if i+5 < len(data) {
allFF := true
for j := 0; j < 6; j++ {
if data[i+j] != 0xFF {
allFF = false
break
}
}
if allFF {
passwordEnd = i
break
}
}
}
username := dataStr[searchStart:firstColon]
password := dataStr[firstColon+1 : passwordEnd]
magicPacketData := data[passwordEnd:]
return username, password, magicPacketData, true
}
secondColon += firstColon + 1
// Extract username and password // Extract username and password
authPart := dataStr[len(AuthPrefix):authEnd] username := dataStr[searchStart:firstColon]
parts := strings.Split(authPart, ":") password := dataStr[firstColon+1 : secondColon]
if len(parts) != 2 {
return "", "", nil, false
}
username := parts[0]
password := parts[1]
// Extract magic packet part (after "AUTH:username:password:") // Extract magic packet part (after "AUTH:username:password:")
magicPacketStart := authEnd + 1 magicPacketStart := secondColon + 1
if magicPacketStart >= len(data) { if magicPacketStart >= len(data) {
return "", "", nil, false return "", "", nil, false
} }

View File

@@ -1,6 +1,7 @@
package server package server
import ( import (
"encoding/hex"
"fmt" "fmt"
"net" "net"
"time" "time"
@@ -69,13 +70,30 @@ func (s *UDPServer) Start(done chan bool) {
continue 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{}{ masterlog.Info("Received UDP packet", map[string]interface{}{
"bytes": n, "bytes": n,
"address": clientAddr, "address": clientAddr,
"hex": hexDump,
"string_preview": stringPreview,
}) })
// Check authentication and magic packet // Check authentication and magic packet
if s.isValidAuthenticatedMagicPacket(buffer[:n]) { if s.isValidAuthenticatedMagicPacket(packetData) {
masterlog.Info("Authenticated Magic Packet detected! Shutting down system...", map[string]interface{}{ masterlog.Info("Authenticated Magic Packet detected! Shutting down system...", map[string]interface{}{
"address": clientAddr, "address": clientAddr,
}) })
@@ -94,14 +112,38 @@ func (s *UDPServer) Start(done chan bool) {
func (s *UDPServer) isValidAuthenticatedMagicPacket(data []byte) bool { func (s *UDPServer) isValidAuthenticatedMagicPacket(data []byte) bool {
username, password, magicPacketData, ok := magicpacket.ExtractAuthFromPacket(data) username, password, magicPacketData, ok := magicpacket.ExtractAuthFromPacket(data)
if !ok { if !ok {
masterlog.Info("Packet does not contain valid auth format", map[string]interface{}{
"packet_size": len(data),
})
return false return false
} }
masterlog.Info("Extracted authentication from packet", map[string]interface{}{
"username": username,
"password_length": len(password),
"magic_packet_size": len(magicPacketData),
})
// Verify authentication // Verify authentication
if !s.authenticator.Verify(username, password) { if !s.authenticator.Verify(username, password) {
masterlog.Info("Authentication failed", map[string]interface{}{
"username": username,
})
return false return false
} }
masterlog.Info("Authentication successful", map[string]interface{}{
"username": username,
})
// Check if it's a valid magic packet // Check if it's a valid magic packet
return magicpacket.IsMagicPacket(magicPacketData) 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
} }

View File

@@ -4,15 +4,33 @@
package system package system
import ( import (
"log"
"os/exec" "os/exec"
"git.secnex.io/secnex/masterlog"
) )
// Shutdown shuts down the system (Unix/Linux/macOS) // Shutdown shuts down the system (Unix/Linux/macOS)
func Shutdown() { func Shutdown() {
// Try shutdown command first
cmd := exec.Command("shutdown", "-h", "now") cmd := exec.Command("shutdown", "-h", "now")
if err := cmd.Run(); err != nil { if err := cmd.Run(); err != nil {
log.Fatalf("Failed to shutdown system: %v", err) masterlog.Error("Failed to shutdown system (trying with sudo)", map[string]interface{}{
"error": err,
})
// Try with sudo if the first attempt failed
cmd = exec.Command("sudo", "shutdown", "-h", "now")
if err := cmd.Run(); err != nil {
masterlog.Error("Failed to shutdown system even with sudo", map[string]interface{}{
"error": err,
"note": "The application may need to be run with sudo privileges",
})
// Don't use log.Fatalf here, just log the error
// The system might still shutdown or the user can manually shutdown
return
}
} }
masterlog.Info("Shutdown command executed successfully")
} }

View File

@@ -4,8 +4,9 @@
package system package system
import ( import (
"log"
"os/exec" "os/exec"
"git.secnex.io/secnex/masterlog"
) )
// Shutdown shuts down the system (Windows) // Shutdown shuts down the system (Windows)
@@ -13,6 +14,12 @@ func Shutdown() {
cmd := exec.Command("shutdown", "/s", "/t", "0") cmd := exec.Command("shutdown", "/s", "/t", "0")
if err := cmd.Run(); err != nil { if err := cmd.Run(); err != nil {
log.Fatalf("Failed to shutdown system: %v", err) masterlog.Error("Failed to shutdown system", map[string]interface{}{
"error": err,
"note": "The application may need administrator privileges",
})
return
} }
masterlog.Info("Shutdown command executed successfully")
} }