Improve fleet control, Crucible ops, and multi-machine identity.
Use hostname-first agent names so the same forged binary on many machines stays distinct at scale. Add WebSocket RTT latency on the roster and Crucible, fleet delete and uninstall flows, live alert config reload, and non-blocking pool setup. Fix Crucible phantom agents after delete, posture scan targeting, and USB portability (config data_dir, LAUNCH sync).
This commit is contained in:
@@ -450,8 +450,11 @@ func (h *Handler) DownloadUninstall(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "Build not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
uninstallPath := strings.TrimSuffix(build.FilePath, filepath.Base(build.FilePath)) +
|
||||
fmt.Sprintf("uninstall-%s.ps1", sanitizeFileName(build.WorkerName))
|
||||
// Uninstall script lives in buildDir (builds/<id>/), NOT in the platform
|
||||
// sub-directory where the binary lives (builds/<id>/windows-amd64/).
|
||||
// Compute directly from dataDir + buildID to avoid path-stripping mistakes.
|
||||
buildDir := filepath.Join(h.dataDir, "builds", buildID)
|
||||
uninstallPath := filepath.Join(buildDir, fmt.Sprintf("uninstall-%s.ps1", sanitizeFileName(build.WorkerName)))
|
||||
if _, err := os.Stat(uninstallPath); err != nil {
|
||||
http.Error(w, "Uninstall script missing", http.StatusNotFound)
|
||||
return
|
||||
@@ -1069,7 +1072,7 @@ func formatGoBackupPools(pools []BackupPool) string {
|
||||
return "nil"
|
||||
}
|
||||
var sb strings.Builder
|
||||
sb.WriteString("[]config.BackupPool{")
|
||||
sb.WriteString("[]BackupPool{")
|
||||
for i, p := range pools {
|
||||
if i > 0 {
|
||||
sb.WriteString(", ")
|
||||
|
||||
@@ -76,6 +76,15 @@ func generateUninstallScript(buildID string, req *BuildRequest) string {
|
||||
installRel := expandInstallRelativePath(req, buildID)
|
||||
installBase := resolveInstallBasePS(req)
|
||||
|
||||
firewallBool := "$false"
|
||||
if req.FirewallExclusion {
|
||||
firewallBool = "$true"
|
||||
}
|
||||
pauseBool := "$false"
|
||||
if !req.StealthMode {
|
||||
pauseBool = "$true"
|
||||
}
|
||||
|
||||
return fmt.Sprintf(`# AetherForge Miner Uninstaller
|
||||
# Worker: %s
|
||||
# Generated alongside forged installer — run as the same Windows user who installed the miner.
|
||||
@@ -112,25 +121,22 @@ if (Test-Path $ExpectedExe) {
|
||||
|
||||
Write-Host "Removing persistence..."
|
||||
Remove-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run' -Name $PersistenceKey -ErrorAction SilentlyContinue
|
||||
Unregister-ScheduledTask -TaskName $PersistenceKey -Confirm:$false -ErrorAction SilentlyContinue
|
||||
|
||||
if (%t) {
|
||||
if (%s) {
|
||||
Write-Host "Removing Windows Firewall rules..."
|
||||
Remove-NetFirewallRule -DisplayName ('AetherForge ' + $PersistenceKey + ' In') -ErrorAction SilentlyContinue
|
||||
Remove-NetFirewallRule -DisplayName ('AetherForge ' + $PersistenceKey + ' Out') -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
if ($true) {
|
||||
Unregister-ScheduledTask -TaskName $PersistenceKey -Confirm:$false -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
Write-Host "Removing install directory: $InstallDir"
|
||||
if ($InstallDir -and (Test-Path $InstallDir)) {
|
||||
Remove-Item -LiteralPath $InstallDir -Recurse -Force
|
||||
}
|
||||
|
||||
Write-Host "Done. Miner removed."
|
||||
if (%t) { Read-Host 'Press Enter to close' }
|
||||
`, req.WorkerName, processName, persistenceKey, installBase, strings.ReplaceAll(installRel, "'", "''"), req.FirewallExclusion, !req.StealthMode)
|
||||
if (%s) { Read-Host 'Press Enter to close' }
|
||||
`, req.WorkerName, processName, persistenceKey, installBase, strings.ReplaceAll(installRel, "'", "''"), firewallBool, pauseBool)
|
||||
}
|
||||
|
||||
func (h *Handler) writeUninstallScript(buildDir string, buildID string, req *BuildRequest) (fileName, filePath string, err error) {
|
||||
|
||||
Reference in New Issue
Block a user