rmmagent/agent/service_windows.go

122 lines
2.7 KiB
Go

package agent
import (
"encoding/json"
"math/rand"
"strings"
"time"
)
//HelloPost post
type HelloPost struct {
Agentid string `json:"agent_id"`
Hostname string `json:"hostname"`
OS string `json:"operating_system"`
TotalRAM float64 `json:"total_ram"`
Platform string `json:"plat"`
Version string `json:"version"`
BootTime int64 `json:"boot_time"`
SaltVersion string `json:"salt_ver"`
}
//HelloPatch patch
type HelloPatch struct {
Agentid string `json:"agent_id"`
Services []WindowsService `json:"services"`
PublicIP string `json:"public_ip"`
Disks []Disk `json:"disks"`
Username string `json:"logged_in_username"`
Version string `json:"version"`
BootTime int64 `json:"boot_time"`
}
// RunAsService tacticalagent windows nssm service
func (a *WindowsAgent) RunAsService() {
a.Logger.Infoln("Agent service started")
var data map[string]interface{}
var sleep int
url := a.Server + "/api/v2/hello/"
plat, osinfo := OSInfo()
postPayload := HelloPost{
Agentid: a.AgentID,
Hostname: a.Hostname,
OS: osinfo,
TotalRAM: TotalRAM(),
Platform: plat,
Version: a.Version,
BootTime: BootTime(),
SaltVersion: a.GetProgramVersion("salt minion"),
}
request1 := &APIRequest{
URL: url,
Method: "POST",
Payload: postPayload,
Headers: a.Headers,
Timeout: 15,
}
a.Logger.Debugln(request1)
_, err := MakeRequest(request1)
if err != nil {
a.Logger.Debugln(err)
}
time.Sleep(3 * time.Second)
for {
patchPayload := HelloPatch{
Agentid: a.AgentID,
Services: a.GetServices(),
PublicIP: PublicIP(),
Disks: a.GetDisks(),
Username: LoggedOnUser(),
Version: a.Version,
BootTime: BootTime(),
}
request2 := &APIRequest{
URL: url,
Method: "PATCH",
Payload: patchPayload,
Headers: a.Headers,
Timeout: 15,
}
a.Logger.Debugln(request2)
r, err := MakeRequest(request2)
if err != nil {
a.Logger.Debugln(err)
} else {
ret := strings.Trim(r.String(), `"`)
if len(ret) > 0 && ret != "ok" {
if err := json.Unmarshal(r.Body(), &data); err != nil {
a.Logger.Debugln(err)
} else {
if action, ok := data["recovery"].(string); ok {
switch action {
case "salt":
go a.RecoverSalt()
case "mesh":
go a.RecoverMesh()
case "command":
if cmd, ok := data["cmd"].(string); ok {
go a.RecoverCMD(cmd)
}
}
}
}
}
}
sleep = randRange(30, 120)
time.Sleep(time.Duration(sleep) * time.Second)
}
}
func randRange(min, max int) int {
rand.Seed(time.Now().UnixNano())
return rand.Intn(max-min) + min
}