big refactor
This commit is contained in:
parent
6abf716844
commit
7fbb0fe7e1
25 changed files with 2761 additions and 822 deletions
180
agent/tactical/checks/checks_windows.go
Normal file
180
agent/tactical/checks/checks_windows.go
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
package checks
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"runtime"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/amidaware/rmmagent/agent/system"
|
||||
"github.com/amidaware/rmmagent/agent/utils"
|
||||
rmm "github.com/amidaware/rmmagent/shared"
|
||||
ps "github.com/elastic/go-sysinfo"
|
||||
"github.com/go-resty/resty/v2"
|
||||
)
|
||||
|
||||
func CheckRunner(agentID string) {
|
||||
sleepDelay := utils.RandRange(14, 22)
|
||||
//a.Logger.Debugf("CheckRunner() init sleeping for %v seconds", sleepDelay)
|
||||
time.Sleep(time.Duration(sleepDelay) * time.Second)
|
||||
for {
|
||||
interval, err := GetCheckInterval(agentID)
|
||||
if err == nil && !ChecksRunning() {
|
||||
if runtime.GOOS == "windows" {
|
||||
_, err = system.CMD(system.GetProgramEXE(), []string{"-m", "checkrunner"}, 600, false)
|
||||
if err != nil {
|
||||
//a.Logger.Errorln("Checkrunner RunChecks", err)
|
||||
}
|
||||
} else {
|
||||
RunChecks(agentID, false)
|
||||
}
|
||||
}
|
||||
|
||||
//a.Logger.Debugln("Checkrunner sleeping for", interval)
|
||||
time.Sleep(time.Duration(interval) * time.Second)
|
||||
}
|
||||
}
|
||||
|
||||
func GetCheckInterval(agentID string) (int, error) {
|
||||
r, err := a.rClient.R().SetResult(&rmm.CheckInfo{}).Get(fmt.Sprintf("/api/v3/%s/checkinterval/", a.AgentID))
|
||||
if err != nil {
|
||||
a.Logger.Debugln(err)
|
||||
return 120, err
|
||||
}
|
||||
if r.IsError() {
|
||||
a.Logger.Debugln("Checkinterval response code:", r.StatusCode())
|
||||
return 120, fmt.Errorf("checkinterval response code: %v", r.StatusCode())
|
||||
}
|
||||
interval := r.Result().(*rmm.CheckInfo).Interval
|
||||
return interval, nil
|
||||
}
|
||||
|
||||
// ChecksRunning prevents duplicate checks from running
|
||||
// Have to do it this way, can't use atomic because they can run from both rpc and tacticalagent services
|
||||
func ChecksRunning() bool {
|
||||
running := false
|
||||
procs, err := ps.Processes()
|
||||
if err != nil {
|
||||
return running
|
||||
}
|
||||
Out:
|
||||
for _, process := range procs {
|
||||
p, err := process.Info()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if p.PID == 0 {
|
||||
continue
|
||||
}
|
||||
if p.Exe != system.GetProgramEXE() {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, arg := range p.Args {
|
||||
if arg == "runchecks" || arg == "checkrunner" {
|
||||
running = true
|
||||
break Out
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return running
|
||||
}
|
||||
|
||||
func RunChecks(agentID string, force bool) error {
|
||||
data := rmm.AllChecks{}
|
||||
var url string
|
||||
if force {
|
||||
url = fmt.Sprintf("/api/v3/%s/runchecks/", agentID)
|
||||
} else {
|
||||
url = fmt.Sprintf("/api/v3/%s/checkrunner/", agentID)
|
||||
}
|
||||
|
||||
r, err := a.rClient.R().Get(url)
|
||||
if err != nil {
|
||||
//a.Logger.Debugln(err)
|
||||
return err
|
||||
}
|
||||
|
||||
if r.IsError() {
|
||||
//a.Logger.Debugln("Checkrunner response code:", r.StatusCode())
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(r.Body(), &data); err != nil {
|
||||
//a.Logger.Debugln(err)
|
||||
return err
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
eventLogChecks := make([]rmm.Check, 0)
|
||||
winServiceChecks := make([]rmm.Check, 0)
|
||||
for _, check := range data.Checks {
|
||||
switch check.CheckType {
|
||||
case "diskspace":
|
||||
wg.Add(1)
|
||||
go func(c rmm.Check, wg *sync.WaitGroup, r *resty.Client) {
|
||||
defer wg.Done()
|
||||
utils.RandomCheckDelay()
|
||||
a.SendDiskCheckResult(a.DiskCheck(c), r)
|
||||
}(check, &wg, a.rClient)
|
||||
case "cpuload":
|
||||
wg.Add(1)
|
||||
go func(c rmm.Check, wg *sync.WaitGroup, r *resty.Client) {
|
||||
defer wg.Done()
|
||||
a.CPULoadCheck(c, r)
|
||||
}(check, &wg, a.rClient)
|
||||
case "memory":
|
||||
wg.Add(1)
|
||||
go func(c rmm.Check, wg *sync.WaitGroup, r *resty.Client) {
|
||||
defer wg.Done()
|
||||
randomCheckDelay()
|
||||
a.MemCheck(c, r)
|
||||
}(check, &wg, a.rClient)
|
||||
case "ping":
|
||||
wg.Add(1)
|
||||
go func(c rmm.Check, wg *sync.WaitGroup, r *resty.Client) {
|
||||
defer wg.Done()
|
||||
randomCheckDelay()
|
||||
a.SendPingCheckResult(a.PingCheck(c), r)
|
||||
}(check, &wg, a.rClient)
|
||||
case "script":
|
||||
wg.Add(1)
|
||||
go func(c rmm.Check, wg *sync.WaitGroup, r *resty.Client) {
|
||||
defer wg.Done()
|
||||
randomCheckDelay()
|
||||
a.ScriptCheck(c, r)
|
||||
}(check, &wg, a.rClient)
|
||||
case "winsvc":
|
||||
winServiceChecks = append(winServiceChecks, check)
|
||||
case "eventlog":
|
||||
eventLogChecks = append(eventLogChecks, check)
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if len(winServiceChecks) > 0 {
|
||||
wg.Add(len(winServiceChecks))
|
||||
go func(wg *sync.WaitGroup, r *resty.Client) {
|
||||
for _, winSvcCheck := range winServiceChecks {
|
||||
defer wg.Done()
|
||||
a.SendWinSvcCheckResult(a.WinSvcCheck(winSvcCheck), r)
|
||||
}
|
||||
}(&wg, a.rClient)
|
||||
}
|
||||
|
||||
if len(eventLogChecks) > 0 {
|
||||
wg.Add(len(eventLogChecks))
|
||||
go func(wg *sync.WaitGroup, r *resty.Client) {
|
||||
for _, evtCheck := range eventLogChecks {
|
||||
defer wg.Done()
|
||||
a.EventLogCheck(evtCheck, r)
|
||||
}
|
||||
}(&wg, a.rClient)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
return nil
|
||||
}
|
||||
179
agent/tactical/service/service.go
Normal file
179
agent/tactical/service/service.go
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/amidaware/rmmagent/agent/disk"
|
||||
"github.com/amidaware/rmmagent/agent/services"
|
||||
"github.com/amidaware/rmmagent/agent/system"
|
||||
"github.com/amidaware/rmmagent/agent/tactical"
|
||||
"github.com/amidaware/rmmagent/agent/tactical/checks"
|
||||
"github.com/amidaware/rmmagent/agent/utils"
|
||||
"github.com/amidaware/rmmagent/agent/wmi"
|
||||
"github.com/nats-io/nats.go"
|
||||
"github.com/ugorji/go/codec"
|
||||
trmm "github.com/wh1te909/trmm-shared"
|
||||
)
|
||||
|
||||
var natsCheckin = []string{"agent-hello", "agent-agentinfo", "agent-disks", "agent-winsvc", "agent-publicip", "agent-wmi"}
|
||||
|
||||
func RunAsService(agentID string, version string) {
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go AgentSvc(version)
|
||||
go checks.CheckRunner(agentID)
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func AgentSvc(version string) {
|
||||
config := tactical.NewAgentConfig()
|
||||
go tactical.GetPython(false)
|
||||
utils.CreateTRMMTempDir()
|
||||
tactical.RunMigrations()
|
||||
|
||||
sleepDelay := utils.RandRange(14, 22)
|
||||
//a.Logger.Debugf("AgentSvc() sleeping for %v seconds", sleepDelay)
|
||||
time.Sleep(time.Duration(sleepDelay) * time.Second)
|
||||
|
||||
opts := SetupNatsOptions(config.AgentID, config.Token)
|
||||
server := fmt.Sprintf("tls://%s:4222", config.APIURL)
|
||||
nc, err := nats.Connect(server, opts...)
|
||||
if err != nil {
|
||||
//a.Logger.Fatalln("AgentSvc() nats.Connect()", err)
|
||||
}
|
||||
|
||||
for _, s := range natsCheckin {
|
||||
NatsMessage(config.AgentID, version, nc, s)
|
||||
time.Sleep(time.Duration(utils.RandRange(100, 400)) * time.Millisecond)
|
||||
}
|
||||
|
||||
go tactical.SyncMeshNodeID()
|
||||
|
||||
time.Sleep(time.Duration(utils.RandRange(1, 3)) * time.Second)
|
||||
AgentStartup(config.AgentID)
|
||||
tactical.SendSoftware()
|
||||
|
||||
checkInHelloTicker := time.NewTicker(time.Duration(utils.RandRange(30, 60)) * time.Second)
|
||||
checkInAgentInfoTicker := time.NewTicker(time.Duration(utils.RandRange(200, 400)) * time.Second)
|
||||
checkInWinSvcTicker := time.NewTicker(time.Duration(utils.RandRange(2400, 3000)) * time.Second)
|
||||
checkInPubIPTicker := time.NewTicker(time.Duration(utils.RandRange(300, 500)) * time.Second)
|
||||
checkInDisksTicker := time.NewTicker(time.Duration(utils.RandRange(1000, 2000)) * time.Second)
|
||||
checkInSWTicker := time.NewTicker(time.Duration(utils.RandRange(2800, 3500)) * time.Second)
|
||||
checkInWMITicker := time.NewTicker(time.Duration(utils.RandRange(3000, 4000)) * time.Second)
|
||||
syncMeshTicker := time.NewTicker(time.Duration(utils.RandRange(800, 1200)) * time.Second)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-checkInHelloTicker.C:
|
||||
NatsMessage(config.AgentID, version, nc, "agent-hello")
|
||||
case <-checkInAgentInfoTicker.C:
|
||||
NatsMessage(config.AgentID, version, nc, "agent-agentinfo")
|
||||
case <-checkInWinSvcTicker.C:
|
||||
NatsMessage(config.AgentID, version, nc, "agent-winsvc")
|
||||
case <-checkInPubIPTicker.C:
|
||||
NatsMessage(config.AgentID, version, nc, "agent-publicip")
|
||||
case <-checkInDisksTicker.C:
|
||||
NatsMessage(config.AgentID, version, nc, "agent-disks")
|
||||
case <-checkInSWTicker.C:
|
||||
tactical.SendSoftware()
|
||||
case <-checkInWMITicker.C:
|
||||
NatsMessage(config.AgentID, version, nc, "agent-wmi")
|
||||
case <-syncMeshTicker.C:
|
||||
tactical.SyncMeshNodeID()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func SetupNatsOptions(agentID string, token string) []nats.Option {
|
||||
opts := make([]nats.Option, 0)
|
||||
opts = append(opts, nats.Name("TacticalRMM"))
|
||||
opts = append(opts, nats.UserInfo(agentID, token))
|
||||
opts = append(opts, nats.ReconnectWait(time.Second*5))
|
||||
opts = append(opts, nats.RetryOnFailedConnect(true))
|
||||
opts = append(opts, nats.MaxReconnects(-1))
|
||||
opts = append(opts, nats.ReconnectBufSize(-1))
|
||||
return opts
|
||||
}
|
||||
|
||||
func NatsMessage(agentID string, version string, nc *nats.Conn, mode string) {
|
||||
var resp []byte
|
||||
var payload interface{}
|
||||
ret := codec.NewEncoderBytes(&resp, new(codec.MsgpackHandle))
|
||||
|
||||
switch mode {
|
||||
case "agent-hello":
|
||||
payload = trmm.CheckInNats{
|
||||
Agentid: agentID,
|
||||
Version: version,
|
||||
}
|
||||
case "agent-winsvc":
|
||||
payload = trmm.WinSvcNats{
|
||||
Agentid: agentID,
|
||||
WinSvcs: services.GetServices(),
|
||||
}
|
||||
case "agent-agentinfo":
|
||||
osinfo := system.OsString()
|
||||
reboot, err := system.SystemRebootRequired()
|
||||
if err != nil {
|
||||
reboot = false
|
||||
}
|
||||
payload = trmm.AgentInfoNats{
|
||||
Agentid: agentID,
|
||||
Username: system.LoggedOnUser(),
|
||||
Hostname: system.GetHostname(),
|
||||
OS: osinfo,
|
||||
Platform: runtime.GOOS,
|
||||
TotalRAM: system.TotalRAM(),
|
||||
BootTime: system.BootTime(),
|
||||
RebootNeeded: reboot,
|
||||
GoArch: runtime.GOARCH,
|
||||
}
|
||||
case "agent-wmi":
|
||||
payload = trmm.WinWMINats{
|
||||
Agentid: agentID,
|
||||
WMI: wmi.GetWMIInfo(),
|
||||
}
|
||||
case "agent-disks":
|
||||
payload = trmm.WinDisksNats{
|
||||
Agentid: agentID,
|
||||
Disks: disk.GetDisks(),
|
||||
}
|
||||
case "agent-publicip":
|
||||
payload = trmm.PublicIPNats{
|
||||
Agentid: agentID,
|
||||
PublicIP: a.PublicIP(),
|
||||
}
|
||||
}
|
||||
|
||||
//a.Logger.Debugln(mode, payload)
|
||||
ret.Encode(payload)
|
||||
nc.PublishRequest(a.AgentID, mode, resp)
|
||||
}
|
||||
|
||||
func DoNatsCheckIn() {
|
||||
opts := SetupNatsOptions()
|
||||
server := fmt.Sprintf("tls://%s:4222", a.ApiURL)
|
||||
nc, err := nats.Connect(server, opts...)
|
||||
if err != nil {
|
||||
//a.Logger.Errorln(err)
|
||||
return
|
||||
}
|
||||
|
||||
for _, s := range natsCheckin {
|
||||
time.Sleep(time.Duration(utils.RandRange(100, 400)) * time.Millisecond)
|
||||
NatsMessage(nc, s)
|
||||
}
|
||||
nc.Close()
|
||||
}
|
||||
|
||||
func AgentStartup(agentID string) {
|
||||
url := "/api/v3/checkin/"
|
||||
payload := map[string]interface{}{"agent_id": agentID}
|
||||
_, err := tactical.PostRequest(url, payload, 15)
|
||||
if err != nil {
|
||||
//a.Logger.Debugln("AgentStartup()", err)
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,25 @@ import (
|
|||
"github.com/go-resty/resty/v2"
|
||||
)
|
||||
|
||||
func PostRequest(url string, body interface{}, timeout time.Duration) (resty.Response, error) {
|
||||
agentConfig := NewAgentConfig()
|
||||
client := resty.New()
|
||||
client.SetBaseURL(agentConfig.BaseURL)
|
||||
client.SetTimeout(timeout * time.Second)
|
||||
client.SetCloseConnection(true)
|
||||
if len(agentConfig.Proxy) > 0 {
|
||||
|
||||
}
|
||||
|
||||
if shared.DEBUG {
|
||||
client.SetDebug(true)
|
||||
}
|
||||
|
||||
response, err := client.R().SetBody(body).Post(url)
|
||||
|
||||
return *response, err
|
||||
}
|
||||
|
||||
func SyncMeshNodeID() bool {
|
||||
id, err := GetMeshNodeID()
|
||||
if err != nil {
|
||||
|
|
@ -16,21 +35,12 @@ func SyncMeshNodeID() bool {
|
|||
}
|
||||
|
||||
agentConfig := NewAgentConfig()
|
||||
|
||||
payload := shared.MeshNodeID{
|
||||
Func: "syncmesh",
|
||||
Agentid: agentConfig.AgentID,
|
||||
NodeID: utils.StripAll(id),
|
||||
}
|
||||
|
||||
client := resty.New()
|
||||
client.SetBaseURL(agentConfig.BaseURL)
|
||||
client.SetTimeout(15 * time.Second)
|
||||
client.SetCloseConnection(true)
|
||||
if shared.DEBUG {
|
||||
client.SetDebug(true)
|
||||
}
|
||||
|
||||
_, err = client.R().SetBody(payload).Post("/api/v3/syncmesh/")
|
||||
_, err = PostRequest("/api/v3/syncmesh/", payload, 15)
|
||||
return err == nil
|
||||
}
|
||||
}
|
||||
|
|
@ -181,4 +181,6 @@ func RunTask(id int) error { return nil }
|
|||
|
||||
func installMesh(meshbin, exe, proxy string) (string, error) {
|
||||
return "not implemented", nil
|
||||
}
|
||||
}
|
||||
|
||||
func SendSoftware() {}
|
||||
|
|
@ -1,5 +1,41 @@
|
|||
package tactical
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/amidaware/rmmagent/agent/patching"
|
||||
"github.com/amidaware/rmmagent/agent/services"
|
||||
"github.com/amidaware/rmmagent/agent/software"
|
||||
"github.com/amidaware/rmmagent/agent/system"
|
||||
"github.com/amidaware/rmmagent/agent/utils"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/kardianos/service"
|
||||
trmm "github.com/wh1te909/trmm-shared"
|
||||
"golang.org/x/sys/windows"
|
||||
"golang.org/x/sys/windows/registry"
|
||||
)
|
||||
|
||||
func GetMeshBinary() string {
|
||||
var MeshSysBin string
|
||||
ac := NewAgentConfig()
|
||||
if len(ac.CustomMeshDir) > 0 {
|
||||
MeshSysBin = filepath.Join(ac.CustomMeshDir, "MeshAgent.exe")
|
||||
} else {
|
||||
MeshSysBin = filepath.Join(os.Getenv("ProgramFiles"), "Mesh Agent", "MeshAgent.exe")
|
||||
}
|
||||
|
||||
return MeshSysBin
|
||||
}
|
||||
|
||||
func NewAgentConfig() *rmm.AgentConfig {
|
||||
k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\TacticalRMM`, registry.ALL_ACCESS)
|
||||
|
||||
|
|
@ -28,4 +64,273 @@ func NewAgentConfig() *rmm.AgentConfig {
|
|||
Proxy: proxy,
|
||||
CustomMeshDir: customMeshDir,
|
||||
}
|
||||
}
|
||||
|
||||
func GetMeshNodeID() (string, error) {
|
||||
out, err := system.CMD(GetMeshBinary(), []string{"-nodeid"}, 10, false)
|
||||
if err != nil {
|
||||
//a.Logger.Debugln(err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
stdout := out[0]
|
||||
stderr := out[1]
|
||||
|
||||
if stderr != "" {
|
||||
//a.Logger.Debugln(stderr)
|
||||
return "", err
|
||||
}
|
||||
|
||||
if stdout == "" || strings.Contains(strings.ToLower(utils.StripAll(stdout)), "not defined") {
|
||||
//a.Logger.Debugln("Failed getting mesh node id", stdout)
|
||||
return "", errors.New("failed to get mesh node id")
|
||||
}
|
||||
|
||||
return stdout, nil
|
||||
}
|
||||
|
||||
func SendSoftware() {
|
||||
sw := software.GetInstalledSoftware()
|
||||
//a.Logger.Debugln(sw)
|
||||
|
||||
config := NewAgentConfig()
|
||||
payload := map[string]interface{}{
|
||||
"agent_id": config.AgentID,
|
||||
"software": sw,
|
||||
}
|
||||
|
||||
_, err := PostRequest("/api/v3/software/", payload, 15)
|
||||
if err != nil {
|
||||
//a.Logger.Debugln(err)
|
||||
}
|
||||
}
|
||||
|
||||
func UninstallCleanup() {
|
||||
registry.DeleteKey(registry.LOCAL_MACHINE, `SOFTWARE\TacticalRMM`)
|
||||
patching.PatchMgmnt(false)
|
||||
CleanupAgentUpdates()
|
||||
system.CleanupSchedTasks()
|
||||
}
|
||||
|
||||
func AgentUpdate(url, inno, version string) {
|
||||
time.Sleep(time.Duration(utils.RandRange(1, 15)) * time.Second)
|
||||
system.KillHungUpdates()
|
||||
CleanupAgentUpdates()
|
||||
updater := filepath.Join(system.GetProgramDirectory(), inno)
|
||||
//a.Logger.Infof("Agent updating from %s to %s", a.Version, version)
|
||||
//a.Logger.Infoln("Downloading agent update from", url)
|
||||
|
||||
config := NewAgentConfig()
|
||||
rClient := resty.New()
|
||||
rClient.SetCloseConnection(true)
|
||||
rClient.SetTimeout(15 * time.Minute)
|
||||
rClient.SetDebug(rmm.DEBUG)
|
||||
if len(config.Proxy) > 0 {
|
||||
rClient.SetProxy(config.Proxy)
|
||||
}
|
||||
|
||||
r, err := rClient.R().SetOutput(updater).Get(url)
|
||||
if err != nil {
|
||||
//a.Logger.Errorln(err)
|
||||
system.CMD("net", []string{"start", services.WinSvcName}, 10, false)
|
||||
return
|
||||
}
|
||||
|
||||
if r.IsError() {
|
||||
//a.Logger.Errorln("Download failed with status code", r.StatusCode())
|
||||
system.CMD("net", []string{"start", services.WinSvcName}, 10, false)
|
||||
return
|
||||
}
|
||||
|
||||
dir, err := ioutil.TempDir("", "tacticalrmm")
|
||||
if err != nil {
|
||||
//a.Logger.Errorln("Agentupdate create tempdir:", err)
|
||||
system.CMD("net", []string{"start", services.WinSvcName}, 10, false)
|
||||
return
|
||||
}
|
||||
|
||||
innoLogFile := filepath.Join(dir, "tacticalrmm.txt")
|
||||
args := []string{"/C", updater, "/VERYSILENT", fmt.Sprintf("/LOG=%s", innoLogFile)}
|
||||
cmd := exec.Command("cmd.exe", args...)
|
||||
cmd.SysProcAttr = &windows.SysProcAttr{
|
||||
CreationFlags: windows.DETACHED_PROCESS | windows.CREATE_NEW_PROCESS_GROUP,
|
||||
}
|
||||
|
||||
cmd.Start()
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
|
||||
func CleanupAgentUpdates() {
|
||||
pd := filepath.Join(os.Getenv("ProgramFiles"), system.ProgFilesName)
|
||||
cderr := os.Chdir(pd)
|
||||
if cderr != nil {
|
||||
//a.Logger.Errorln(cderr)
|
||||
return
|
||||
}
|
||||
|
||||
files, err := filepath.Glob("winagent-v*.exe")
|
||||
if err == nil {
|
||||
for _, f := range files {
|
||||
os.Remove(f)
|
||||
}
|
||||
}
|
||||
|
||||
cderr = os.Chdir(os.Getenv("TMP"))
|
||||
if cderr != nil {
|
||||
//a.Logger.Errorln(cderr)
|
||||
return
|
||||
}
|
||||
|
||||
folders, err := filepath.Glob("tacticalrmm*")
|
||||
if err == nil {
|
||||
for _, f := range folders {
|
||||
os.RemoveAll(f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func AgentUninstall(code string) {
|
||||
system.KillHungUpdates()
|
||||
tacUninst := filepath.Join(system.GetProgramDirectory(), GetUninstallExe())
|
||||
args := []string{"/C", tacUninst, "/VERYSILENT"}
|
||||
cmd := exec.Command("cmd.exe", args...)
|
||||
cmd.SysProcAttr = &windows.SysProcAttr{
|
||||
CreationFlags: windows.DETACHED_PROCESS | windows.CREATE_NEW_PROCESS_GROUP,
|
||||
}
|
||||
cmd.Start()
|
||||
}
|
||||
|
||||
func GetUninstallExe() string {
|
||||
cderr := os.Chdir(system.GetProgramDirectory())
|
||||
if cderr == nil {
|
||||
files, err := filepath.Glob("unins*.exe")
|
||||
if err == nil {
|
||||
for _, f := range files {
|
||||
if strings.Contains(f, "001") {
|
||||
return f
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "unins000.exe"
|
||||
}
|
||||
|
||||
// RunMigrations cleans up unused stuff from older agents
|
||||
func RunMigrations() {
|
||||
for _, i := range []string{"nssm.exe", "nssm-x86.exe"} {
|
||||
nssm := filepath.Join(system.GetProgramDirectory(), i)
|
||||
if trmm.FileExists(nssm) {
|
||||
os.Remove(nssm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func installMesh(meshbin, exe, proxy string) (string, error) {
|
||||
var meshNodeID string
|
||||
meshInstallArgs := []string{"-fullinstall"}
|
||||
if len(proxy) > 0 {
|
||||
meshProxy := fmt.Sprintf("--WebProxy=%s", proxy)
|
||||
meshInstallArgs = append(meshInstallArgs, meshProxy)
|
||||
}
|
||||
|
||||
//a.Logger.Debugln("Mesh install args:", meshInstallArgs)
|
||||
meshOut, meshErr := system.CMD(meshbin, meshInstallArgs, int(90), false)
|
||||
if meshErr != nil {
|
||||
fmt.Println(meshOut[0])
|
||||
fmt.Println(meshOut[1])
|
||||
fmt.Println(meshErr)
|
||||
}
|
||||
|
||||
fmt.Println(meshOut)
|
||||
//a.Logger.Debugln("Sleeping for 5")
|
||||
time.Sleep(5 * time.Second)
|
||||
|
||||
meshSuccess := false
|
||||
|
||||
for !meshSuccess {
|
||||
//a.Logger.Debugln("Getting mesh node id")
|
||||
pMesh, pErr := system.CMD(exe, []string{"-nodeid"}, int(30), false)
|
||||
if pErr != nil {
|
||||
//a.Logger.Errorln(pErr)
|
||||
time.Sleep(5 * time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
if pMesh[1] != "" {
|
||||
//a.Logger.Errorln(pMesh[1])
|
||||
time.Sleep(5 * time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
meshNodeID = utils.StripAll(pMesh[0])
|
||||
//a.Logger.Debugln("Node id:", meshNodeID)
|
||||
if strings.Contains(strings.ToLower(meshNodeID), "not defined") {
|
||||
//a.Logger.Errorln(meshNodeID)
|
||||
time.Sleep(5 * time.Second)
|
||||
continue
|
||||
}
|
||||
|
||||
meshSuccess = true
|
||||
}
|
||||
|
||||
return meshNodeID, nil
|
||||
}
|
||||
|
||||
func Start(_ service.Service) error {
|
||||
go rpc.RunRPC()
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetPython(force bool) {
|
||||
if trmm.FileExists(system.GetPythonBin()) && !force {
|
||||
return
|
||||
}
|
||||
|
||||
var archZip string
|
||||
var folder string
|
||||
switch runtime.GOARCH {
|
||||
case "amd64":
|
||||
archZip = "py38-x64.zip"
|
||||
folder = "py38-x64"
|
||||
case "386":
|
||||
archZip = "py38-x32.zip"
|
||||
folder = "py38-x32"
|
||||
}
|
||||
pyFolder := filepath.Join(system.GetProgramDirectory(), folder)
|
||||
pyZip := filepath.Join(system.GetProgramDirectory(), archZip)
|
||||
//a.Logger.Debugln(pyZip)
|
||||
//a.Logger.Debugln(a.PyBin)
|
||||
defer os.Remove(pyZip)
|
||||
|
||||
if force {
|
||||
os.RemoveAll(pyFolder)
|
||||
}
|
||||
|
||||
config := NewAgentConfig()
|
||||
rClient := resty.New()
|
||||
rClient.SetTimeout(20 * time.Minute)
|
||||
rClient.SetRetryCount(10)
|
||||
rClient.SetRetryWaitTime(1 * time.Minute)
|
||||
rClient.SetRetryMaxWaitTime(15 * time.Minute)
|
||||
if len(config.Proxy) > 0 {
|
||||
rClient.SetProxy(config.Proxy)
|
||||
}
|
||||
|
||||
url := fmt.Sprintf("https://github.com/amidaware/rmmagent/releases/download/v2.0.0/%s", archZip)
|
||||
//a.Logger.Debugln(url)
|
||||
r, err := rClient.R().SetOutput(pyZip).Get(url)
|
||||
if err != nil {
|
||||
//a.Logger.Errorln("Unable to download py3.zip from github.", err)
|
||||
return
|
||||
}
|
||||
if r.IsError() {
|
||||
//a.Logger.Errorln("Unable to download py3.zip from github. Status code", r.StatusCode())
|
||||
return
|
||||
}
|
||||
|
||||
err = utils.Unzip(pyZip, system.GetProgramDirectory())
|
||||
if err != nil {
|
||||
//a.Logger.Errorln(err)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue