fix(shutdown): Fix shutdown command
This commit is contained in:
@@ -60,25 +60,52 @@ func ExtractAuthFromPacket(data []byte) (string, string, []byte, bool) {
|
||||
return "", "", nil, false
|
||||
}
|
||||
|
||||
// Extract authentication part
|
||||
authEnd := strings.Index(dataStr[len(AuthPrefix):], ":")
|
||||
if authEnd == -1 {
|
||||
// Find the first colon after "AUTH:" (end of username)
|
||||
searchStart := len(AuthPrefix)
|
||||
firstColon := strings.Index(dataStr[searchStart:], ":")
|
||||
if firstColon == -1 {
|
||||
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
|
||||
authPart := dataStr[len(AuthPrefix):authEnd]
|
||||
parts := strings.Split(authPart, ":")
|
||||
if len(parts) != 2 {
|
||||
return "", "", nil, false
|
||||
}
|
||||
|
||||
username := parts[0]
|
||||
password := parts[1]
|
||||
username := dataStr[searchStart:firstColon]
|
||||
password := dataStr[firstColon+1 : secondColon]
|
||||
|
||||
// Extract magic packet part (after "AUTH:username:password:")
|
||||
magicPacketStart := authEnd + 1
|
||||
magicPacketStart := secondColon + 1
|
||||
if magicPacketStart >= len(data) {
|
||||
return "", "", nil, false
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package server
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net"
|
||||
"time"
|
||||
@@ -69,13 +70,30 @@ func (s *UDPServer) Start(done chan bool) {
|
||||
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,
|
||||
"bytes": n,
|
||||
"address": clientAddr,
|
||||
"hex": hexDump,
|
||||
"string_preview": stringPreview,
|
||||
})
|
||||
|
||||
// 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{}{
|
||||
"address": clientAddr,
|
||||
})
|
||||
@@ -94,14 +112,38 @@ func (s *UDPServer) Start(done chan bool) {
|
||||
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
|
||||
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
|
||||
}
|
||||
|
||||
@@ -4,15 +4,33 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os/exec"
|
||||
|
||||
"git.secnex.io/secnex/masterlog"
|
||||
)
|
||||
|
||||
// Shutdown shuts down the system (Unix/Linux/macOS)
|
||||
func Shutdown() {
|
||||
// Try shutdown command first
|
||||
cmd := exec.Command("shutdown", "-h", "now")
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os/exec"
|
||||
|
||||
"git.secnex.io/secnex/masterlog"
|
||||
)
|
||||
|
||||
// Shutdown shuts down the system (Windows)
|
||||
@@ -13,6 +14,12 @@ func Shutdown() {
|
||||
cmd := exec.Command("shutdown", "/s", "/t", "0")
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user