63 Commits

Author SHA1 Message Date
wh1te909
e9fd05bd91 Release 2.4.3 2022-12-04 15:10:28 -08:00
wh1te909
63fe3bcd73 bump versions 2022-12-04 15:09:48 -08:00
wh1te909
524837627f add env for script checks 2022-12-03 02:00:10 -08:00
wh1te909
3cb6b92a80 tidy 2022-12-02 23:34:09 -08:00
wh1te909
ec6ea9aded add local config 2022-12-02 23:22:14 -08:00
wh1te909
de01fa5d80 change logging levels 2022-11-30 17:13:55 -08:00
wh1te909
c71e495184 update deps 2022-11-30 16:28:06 -08:00
wh1te909
8d7dfeef25 fix unix 2022-11-29 19:50:52 +00:00
wh1te909
3ff004afa0 add more nats debug 2022-11-29 11:38:17 -08:00
wh1te909
36e9065474 change logging level 2022-11-28 23:19:58 -08:00
wh1te909
7358907b3c add env 2022-11-28 23:19:12 -08:00
wh1te909
6ac14b6d64 add env to scripts 2022-11-25 00:23:31 -08:00
wh1te909
9565fea27c update deps 2022-11-25 00:22:28 -08:00
wh1te909
79dba2f84c add some debug callbacks 2022-11-24 23:48:27 -08:00
wh1te909
f1db416d56 make checkin intervals configurable and remove extra nats conn 2022-11-24 23:45:59 -08:00
wh1te909
b3e0c3e3f8 Release 2.4.2 2022-11-12 16:50:11 -08:00
wh1te909
9ccb95449e bump version 2022-11-12 16:49:47 -08:00
wh1te909
d3bcb10f93 tidy 2022-11-12 16:17:18 -08:00
wh1te909
bcfae9dc66 update nats 2022-11-12 15:30:39 -08:00
wh1te909
f200862b1a remove unused funcs 2022-11-12 15:28:19 -08:00
wh1te909
7a75d4d5a3 update viper 2022-11-11 17:46:28 -08:00
wh1te909
db5cd5b0e0 dev 2022-11-11 17:46:10 -08:00
wh1te909
44c63d00b6 update ci 2022-11-09 23:47:00 -08:00
wh1te909
bf5258eb78 bump version 2022-11-08 23:02:17 -08:00
wh1te909
93f4de35fe update psutil 2022-11-08 21:37:54 -08:00
wh1te909
337c519b99 update deps 2022-11-07 10:18:12 -08:00
wh1te909
473cfd3ced add more cleanup #25 2022-11-06 22:20:49 -08:00
wh1te909
a057c65a02 moving this somewhere else 2022-11-06 22:18:56 -08:00
wh1te909
e11c38dd49 fix race condition in windows agent update amidaware/tacticalrmm#1250 2022-11-06 21:49:26 -08:00
wh1te909
eddafb873b remove stale inno temp files 2022-10-29 16:02:08 -07:00
wh1te909
f336315312 Release 2.4.1 2022-10-25 14:50:06 -07:00
wh1te909
935d5d8ab8 bump version 2022-10-25 14:47:42 -07:00
wh1te909
552d63ea6e update mesh installpath 2022-10-25 11:34:44 -07:00
wh1te909
16df03678c update reqs 2022-10-24 19:33:38 -07:00
wh1te909
56d2356db2 update reqs 2022-10-19 12:37:47 -07:00
wh1te909
d7560b0706 Release 2.4.0 2022-09-23 19:17:27 -07:00
wh1te909
43d13a78f2 bump version 2022-09-23 19:16:43 -07:00
wh1te909
cd93ec12fa update reqs 2022-09-23 23:30:23 +00:00
wh1te909
852dfee29f mac agent 2022-09-23 16:05:17 -07:00
wh1te909
e0cfb7c90e remove defender exclusions 2022-09-15 18:37:07 -07:00
Dan
89be0e7d99 Merge pull request #19 from redanthrax/MacAgent
added mesh location to agent
2022-09-15 18:28:52 -07:00
wh1te909
caa5cd8362 Release 2.3.1 2022-09-11 23:01:07 -07:00
wh1te909
f746f78c63 bump versions 2022-09-11 22:58:48 -07:00
wh1te909
af040d18ee update deps 2022-09-11 19:57:01 +00:00
wh1te909
e8c743c197 add env to exec 2022-09-11 01:34:04 +00:00
redanthrax
b21929d044 added mesh location to agent 2022-08-23 13:55:25 -07:00
wh1te909
14707d78c9 Release 2.3.0 2022-08-09 13:18:55 -07:00
wh1te909
89d7ec8242 bump versions 2022-08-09 13:17:02 -07:00
wh1te909
7b8d524a81 still need program files 2022-08-09 13:07:25 -07:00
wh1te909
662c41794b better cleanup 2022-08-09 12:41:07 -07:00
wh1te909
607a5283ac add helper func to get env 2022-08-09 12:40:42 -07:00
wh1te909
41597d7d26 standardize windows temp dir fixes amidaware/tacticalrmm#1238 2022-08-09 10:33:30 -07:00
wh1te909
381f9696eb fix agent update when selinux is enforcing fixes amidaware/tacticalrmm#1239 2022-08-08 23:07:34 +00:00
wh1te909
f6ec32a8d6 Release 2.2.1 2022-08-01 15:44:59 -07:00
wh1te909
adee74ffd0 bump version 2022-08-01 15:42:28 -07:00
wh1te909
0c536f13b0 fix wrong token type 2022-08-01 15:42:01 -07:00
wh1te909
1c1fb0af99 Release 2.2.0 2022-08-01 10:14:20 -07:00
wh1te909
5bf3ef5356 bump version 2022-08-01 10:13:58 -07:00
wh1te909
50cebb950d run as user 2022-07-31 15:14:05 -07:00
wh1te909
82ad6be3aa Merge branch 'develop' 2022-07-26 23:22:40 -07:00
wh1te909
ad1ae2a6a1 bump version 2022-07-26 23:20:39 -07:00
wh1te909
eb386a4ee2 update logrus 2022-07-25 21:33:13 -07:00
wh1te909
1fbf2be562 only log the url during debug 2022-07-25 21:31:52 -07:00
19 changed files with 616 additions and 337 deletions

View File

@@ -18,7 +18,7 @@ jobs:
- uses: actions/setup-go@v3
with:
go-version: '1.18.3'
go-version: '1.19.3'
- name: Ensure linux agent compiles
run: |
@@ -40,10 +40,3 @@ jobs:
for i in ${ARCHS}; do
env CGO_ENABLED=0 GOOS=darwin GOARCH=${i} go build -ldflags "-s -w"
done
- name: Ensure freebsd agent compiles
run: |
ARCHS='amd64 386 arm64 arm'
for i in ${ARCHS}; do
env CGO_ENABLED=0 GOOS=freebsd GOARCH=${i} go build -ldflags "-s -w"
done

View File

@@ -40,45 +40,58 @@ import (
// Agent struct
type Agent struct {
Hostname string
Arch string
AgentID string
BaseURL string
ApiURL string
Token string
AgentPK int
Cert string
ProgramDir string
EXE string
SystemDrive string
MeshInstaller string
MeshSystemEXE string
MeshSVC string
PyBin string
Headers map[string]string
Logger *logrus.Logger
Version string
Debug bool
rClient *resty.Client
Proxy string
LogTo string
LogFile *os.File
Platform string
GoArch string
ServiceConfig *service.Config
NatsServer string
NatsProxyPath string
NatsProxyPort string
Hostname string
Arch string
AgentID string
BaseURL string
ApiURL string
Token string
AgentPK int
Cert string
ProgramDir string
EXE string
SystemDrive string
MeshInstaller string
MeshSystemEXE string
MeshSVC string
PyBin string
Headers map[string]string
Logger *logrus.Logger
Version string
Debug bool
rClient *resty.Client
Proxy string
LogTo string
LogFile *os.File
Platform string
GoArch string
ServiceConfig *service.Config
NatsServer string
NatsProxyPath string
NatsProxyPort string
NatsPingInterval int
NatsWSCompression bool
}
const (
progFilesName = "TacticalAgent"
winExeName = "tacticalrmm.exe"
winSvcName = "tacticalrmm"
meshSvcName = "mesh agent"
progFilesName = "TacticalAgent"
winExeName = "tacticalrmm.exe"
winSvcName = "tacticalrmm"
meshSvcName = "mesh agent"
etcConfig = "/etc/tacticalagent"
nixAgentDir = "/opt/tacticalagent"
nixMeshDir = "/opt/tacticalmesh"
nixAgentBin = nixAgentDir + "/tacticalagent"
nixMeshAgentBin = nixMeshDir + "/meshagent"
macPlistPath = "/Library/LaunchDaemons/tacticalagent.plist"
macPlistName = "tacticalagent"
defaultMacMeshSvcDir = "/usr/local/mesh_services"
)
var winTempDir = filepath.Join(os.Getenv("PROGRAMDATA"), "TacticalRMM")
var winMeshDir = filepath.Join(os.Getenv("PROGRAMFILES"), "Mesh Agent")
var natsCheckin = []string{"agent-hello", "agent-agentinfo", "agent-disks", "agent-winsvc", "agent-publicip", "agent-wmi"}
var limitNatsData = []string{"agent-winsvc", "agent-wmi"}
func New(logger *logrus.Logger, version string) *Agent {
host, _ := ps.Host()
@@ -118,14 +131,21 @@ func New(logger *logrus.Logger, version string) *Agent {
}
var MeshSysExe string
if len(ac.CustomMeshDir) > 0 {
MeshSysExe = filepath.Join(ac.CustomMeshDir, "MeshAgent.exe")
} else {
MeshSysExe = filepath.Join(os.Getenv("ProgramFiles"), "Mesh Agent", "MeshAgent.exe")
}
if runtime.GOOS == "linux" {
MeshSysExe = "/opt/tacticalmesh/meshagent"
switch runtime.GOOS {
case "windows":
if len(ac.CustomMeshDir) > 0 {
MeshSysExe = filepath.Join(ac.CustomMeshDir, "MeshAgent.exe")
} else {
MeshSysExe = filepath.Join(os.Getenv("ProgramFiles"), "Mesh Agent", "MeshAgent.exe")
}
case "darwin":
if trmm.FileExists(nixMeshAgentBin) {
MeshSysExe = nixMeshAgentBin
} else {
MeshSysExe = "/usr/local/mesh_services/meshagent/meshagent"
}
default:
MeshSysExe = nixMeshAgentBin
}
svcConf := &service.Config{
@@ -137,7 +157,7 @@ func New(logger *logrus.Logger, version string) *Agent {
Option: service.KeyValue{
"StartType": "automatic",
"OnFailure": "restart",
"OnFailureDelayDuration": "5s",
"OnFailureDelayDuration": "12s",
"OnFailureResetPeriod": 10,
},
}
@@ -153,39 +173,50 @@ func New(logger *logrus.Logger, version string) *Agent {
// check if using nats standard tcp, otherwise use nats websockets by default
var natsServer string
var natsWsCompression bool
if ac.NatsStandardPort != "" {
natsServer = fmt.Sprintf("tls://%s:%s", ac.APIURL, ac.NatsStandardPort)
} else {
natsServer = fmt.Sprintf("wss://%s:%s", ac.APIURL, natsProxyPort)
natsWsCompression = true
}
var natsPingInterval int
if ac.NatsPingInterval == 0 {
natsPingInterval = randRange(35, 45)
} else {
natsPingInterval = ac.NatsPingInterval
}
return &Agent{
Hostname: info.Hostname,
BaseURL: ac.BaseURL,
AgentID: ac.AgentID,
ApiURL: ac.APIURL,
Token: ac.Token,
AgentPK: ac.PK,
Cert: ac.Cert,
ProgramDir: pd,
EXE: exe,
SystemDrive: sd,
MeshInstaller: "meshagent.exe",
MeshSystemEXE: MeshSysExe,
MeshSVC: meshSvcName,
PyBin: pybin,
Headers: headers,
Logger: logger,
Version: version,
Debug: logger.IsLevelEnabled(logrus.DebugLevel),
rClient: restyC,
Proxy: ac.Proxy,
Platform: runtime.GOOS,
GoArch: runtime.GOARCH,
ServiceConfig: svcConf,
NatsServer: natsServer,
NatsProxyPath: natsProxyPath,
NatsProxyPort: natsProxyPort,
Hostname: info.Hostname,
BaseURL: ac.BaseURL,
AgentID: ac.AgentID,
ApiURL: ac.APIURL,
Token: ac.Token,
AgentPK: ac.PK,
Cert: ac.Cert,
ProgramDir: pd,
EXE: exe,
SystemDrive: sd,
MeshInstaller: "meshagent.exe",
MeshSystemEXE: MeshSysExe,
MeshSVC: meshSvcName,
PyBin: pybin,
Headers: headers,
Logger: logger,
Version: version,
Debug: logger.IsLevelEnabled(logrus.DebugLevel),
rClient: restyC,
Proxy: ac.Proxy,
Platform: runtime.GOOS,
GoArch: runtime.GOARCH,
ServiceConfig: svcConf,
NatsServer: natsServer,
NatsProxyPath: natsProxyPath,
NatsProxyPort: natsProxyPort,
NatsPingInterval: natsPingInterval,
NatsWSCompression: natsWsCompression,
}
}
@@ -203,6 +234,7 @@ type CmdOptions struct {
IsScript bool
IsExecutable bool
Detached bool
EnvVars []string
}
func (a *Agent) NewCMDOpts() *CmdOptions {
@@ -226,11 +258,16 @@ func (a *Agent) CmdV2(c *CmdOptions) CmdStatus {
// have a child process that is in a different process group so that
// parent terminating doesn't kill child
if c.Detached {
cmdOptions.BeforeExec = []func(cmd *exec.Cmd){
func(cmd *exec.Cmd) {
cmd.SysProcAttr = SetDetached()
},
}
cmdOptions.BeforeExec = append(cmdOptions.BeforeExec, func(cmd *exec.Cmd) {
cmd.SysProcAttr = SetDetached()
})
}
if len(c.EnvVars) > 0 {
cmdOptions.BeforeExec = append(cmdOptions.BeforeExec, func(cmd *exec.Cmd) {
cmd.Env = os.Environ()
cmd.Env = append(cmd.Env, c.EnvVars...)
})
}
var envCmd *gocmd.Cmd
@@ -375,14 +412,30 @@ func (a *Agent) SyncMeshNodeID() {
}
func (a *Agent) setupNatsOptions() []nats.Option {
reconnectWait := randRange(2, 8)
opts := make([]nats.Option, 0)
opts = append(opts, nats.Name("TacticalRMM"))
opts = append(opts, nats.Name(a.AgentID))
opts = append(opts, nats.UserInfo(a.AgentID, a.Token))
opts = append(opts, nats.ReconnectWait(time.Second*5))
opts = append(opts, nats.ReconnectWait(time.Duration(reconnectWait)*time.Second))
opts = append(opts, nats.RetryOnFailedConnect(true))
opts = append(opts, nats.PingInterval(time.Duration(a.NatsPingInterval)*time.Second))
opts = append(opts, nats.Compression(a.NatsWSCompression))
opts = append(opts, nats.MaxReconnects(-1))
opts = append(opts, nats.ReconnectBufSize(-1))
opts = append(opts, nats.ProxyPath(a.NatsProxyPath))
opts = append(opts, nats.ReconnectJitter(500*time.Millisecond, 4*time.Second))
opts = append(opts, nats.DisconnectErrHandler(func(nc *nats.Conn, err error) {
a.Logger.Debugln("NATS disconnected:", err)
a.Logger.Debugf("%+v\n", nc.Statistics)
}))
opts = append(opts, nats.ReconnectHandler(func(nc *nats.Conn) {
a.Logger.Debugln("NATS reconnected")
a.Logger.Debugf("%+v\n", nc.Statistics)
}))
opts = append(opts, nats.ErrorHandler(func(nc *nats.Conn, sub *nats.Subscription, err error) {
a.Logger.Errorln("NATS error:", err)
a.Logger.Errorf("%+v\n", sub)
}))
return opts
}
@@ -402,54 +455,47 @@ func (a *Agent) GetUninstallExe() string {
}
func (a *Agent) CleanupAgentUpdates() {
cderr := os.Chdir(a.ProgramDir)
if cderr != nil {
a.Logger.Errorln(cderr)
return
}
// TODO remove a.ProgramDir, updates are now in winTempDir
dirs := [3]string{winTempDir, os.Getenv("TMP"), a.ProgramDir}
for _, dir := range dirs {
err := os.Chdir(dir)
if err != nil {
a.Logger.Debugln("CleanupAgentUpdates()", dir, err)
continue
}
// winagent-v* is deprecated
files, err := filepath.Glob("winagent-v*.exe")
if err == nil {
for _, f := range files {
os.Remove(f)
// TODO winagent-v* is deprecated
globs := [3]string{"tacticalagent-v*", "is-*.tmp", "winagent-v*"}
for _, glob := range globs {
files, err := filepath.Glob(glob)
if err == nil {
for _, f := range files {
a.Logger.Debugln("CleanupAgentUpdates() Removing file:", f)
os.Remove(f)
}
}
}
}
agents, err := filepath.Glob("tacticalagent-v*.exe")
err := os.Chdir(os.Getenv("TMP"))
if err == nil {
for _, f := range agents {
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)
dirs, err := filepath.Glob("tacticalrmm*")
if err == nil {
for _, f := range dirs {
os.RemoveAll(f)
}
}
}
}
func (a *Agent) RunPythonCode(code string, timeout int, args []string) (string, error) {
content := []byte(code)
dir, err := ioutil.TempDir("", "tacticalpy")
if err != nil {
a.Logger.Debugln(err)
return "", err
}
defer os.RemoveAll(dir)
tmpfn, _ := ioutil.TempFile(dir, "*.py")
tmpfn, _ := ioutil.TempFile(winTempDir, "*.py")
if _, err := tmpfn.Write(content); err != nil {
a.Logger.Debugln(err)
return "", err
}
defer os.Remove(tmpfn.Name())
if err := tmpfn.Close(); err != nil {
a.Logger.Debugln(err)
return "", err
@@ -489,13 +535,12 @@ func (a *Agent) RunPythonCode(code string, timeout int, args []string) (string,
}
func (a *Agent) CreateTRMMTempDir() {
// create the temp dir for running scripts
dir := filepath.Join(os.TempDir(), "trmm")
if !trmm.FileExists(dir) {
err := os.Mkdir(dir, 0775)
func createWinTempDir() error {
if !trmm.FileExists(winTempDir) {
err := os.Mkdir(winTempDir, 0775)
if err != nil {
a.Logger.Errorln(err)
return err
}
}
return nil
}

View File

@@ -50,7 +50,7 @@ func (a *Agent) GetDisks() []trmm.Disk {
}
for _, p := range partitions {
if strings.Contains(p.Device, "dev/loop") {
if strings.Contains(p.Device, "dev/loop") || strings.Contains(p.Device, "devfs") {
continue
}
usage, err := disk.Usage(p.Mountpoint)
@@ -158,11 +158,12 @@ func NewAgentConfig() *rmm.AgentConfig {
NatsProxyPath: viper.GetString("natsproxypath"),
NatsProxyPort: viper.GetString("natsproxyport"),
NatsStandardPort: viper.GetString("natsstandardport"),
NatsPingInterval: viper.GetInt("natspinginterval"),
}
return ret
}
func (a *Agent) RunScript(code string, shell string, args []string, timeout int) (stdout, stderr string, exitcode int, e error) {
func (a *Agent) RunScript(code string, shell string, args []string, timeout int, runasuser bool, envVars []string) (stdout, stderr string, exitcode int, e error) {
code = removeWinNewLines(code)
content := []byte(code)
@@ -192,6 +193,7 @@ func (a *Agent) RunScript(code string, shell string, args []string, timeout int)
opts.IsScript = true
opts.Shell = f.Name()
opts.Args = args
opts.EnvVars = envVars
opts.Timeout = time.Duration(timeout)
out := a.CmdV2(opts)
retError := ""
@@ -209,6 +211,13 @@ func SetDetached() *syscall.SysProcAttr {
return &syscall.SysProcAttr{Setpgid: true}
}
func (a *Agent) seEnforcing() bool {
opts := a.NewCMDOpts()
opts.Command = "getenforce"
out := a.CmdV2(opts)
return out.Status.Exit == 0 && strings.Contains(out.Stdout, "Enforcing")
}
func (a *Agent) AgentUpdate(url, inno, version string) {
self, err := os.Executable()
@@ -225,7 +234,7 @@ func (a *Agent) AgentUpdate(url, inno, version string) {
defer os.Remove(f.Name())
a.Logger.Infof("Agent updating from %s to %s", a.Version, version)
a.Logger.Infoln("Downloading agent update from", url)
a.Logger.Debugln("Downloading agent update from", url)
rClient := resty.New()
rClient.SetCloseConnection(true)
@@ -276,9 +285,24 @@ func (a *Agent) AgentUpdate(url, inno, version string) {
}
}
if runtime.GOOS == "linux" && a.seEnforcing() {
se := a.NewCMDOpts()
se.Command = fmt.Sprintf("restorecon -rv %s", self)
out := a.CmdV2(se)
a.Logger.Debugln("%+v\n", out)
}
opts := a.NewCMDOpts()
opts.Detached = true
opts.Command = "systemctl restart tacticalagent.service"
switch runtime.GOOS {
case "linux":
opts.Command = "systemctl restart tacticalagent.service"
case "darwin":
opts.Command = "launchctl kickstart -k system/tacticalagent"
default:
return
}
a.CmdV2(opts)
}
@@ -296,7 +320,9 @@ func (a *Agent) AgentUninstall(code string) {
opts := a.NewCMDOpts()
opts.IsScript = true
opts.Shell = f.Name()
opts.Args = []string{"uninstall"}
if runtime.GOOS == "linux" {
opts.Args = []string{"uninstall"}
}
opts.Detached = true
a.CmdV2(opts)
}
@@ -340,7 +366,15 @@ func (a *Agent) getMeshNodeID() (string, error) {
func (a *Agent) RecoverMesh() {
a.Logger.Infoln("Attempting mesh recovery")
opts := a.NewCMDOpts()
opts.Command = "systemctl restart meshagent.service"
def := "systemctl restart meshagent.service"
switch runtime.GOOS {
case "linux":
opts.Command = def
case "darwin":
opts.Command = "launchctl kickstart -k system/meshagent"
default:
opts.Command = def
}
a.CmdV2(opts)
a.SyncMeshNodeID()
}
@@ -399,18 +433,25 @@ func (a *Agent) GetWMIInfo() map[string]interface{} {
wmiInfo["make_model"] = ""
chassis, err := ghw.Chassis(ghw.WithDisableWarnings())
if err != nil {
a.Logger.Errorln("ghw.Chassis()", err)
a.Logger.Debugln("ghw.Chassis()", err)
} else {
if chassis.Vendor != "" || chassis.Version != "" {
wmiInfo["make_model"] = fmt.Sprintf("%s %s", chassis.Vendor, chassis.Version)
}
}
if runtime.GOOS == "darwin" {
opts := a.NewCMDOpts()
opts.Command = "sysctl hw.model"
out := a.CmdV2(opts)
wmiInfo["make_model"] = strings.ReplaceAll(out.Stdout, "hw.model: ", "")
}
// gfx cards
gpu, err := ghw.GPU(ghw.WithDisableWarnings())
if err != nil {
a.Logger.Errorln("ghw.GPU()", err)
a.Logger.Debugln("ghw.GPU()", err)
} else {
for _, i := range gpu.GraphicsCards {
if i.DeviceInfo != nil {
@@ -452,6 +493,9 @@ func (a *Agent) GetWMIInfo() map[string]interface{} {
}
// windows only below TODO add into stub file
func (a *Agent) GetAgentCheckInConfig(ret AgentCheckInConfig) AgentCheckInConfig {
return ret
}
func (a *Agent) PlatVer() (string, error) { return "", nil }
@@ -507,7 +551,7 @@ func (a *Agent) installMesh(meshbin, exe, proxy string) (string, error) {
return "not implemented", nil
}
func CMDShell(shell string, cmdArgs []string, command string, timeout int, detached bool) (output [2]string, e error) {
func CMDShell(shell string, cmdArgs []string, command string, timeout int, detached bool, runasuser bool) (output [2]string, e error) {
return [2]string{"", ""}, nil
}

View File

@@ -30,6 +30,7 @@ import (
rmm "github.com/amidaware/rmmagent/shared"
ps "github.com/elastic/go-sysinfo"
"github.com/fourcorelabs/wintoken"
"github.com/go-ole/go-ole"
"github.com/go-ole/go-ole/oleutil"
"github.com/go-resty/resty/v2"
@@ -64,6 +65,8 @@ func NewAgentConfig() *rmm.AgentConfig {
natsProxyPath, _, _ := k.GetStringValue("NatsProxyPath")
natsProxyPort, _, _ := k.GetStringValue("NatsProxyPort")
natsStandardPort, _, _ := k.GetStringValue("NatsStandardPort")
natsPingInterval, _, _ := k.GetStringValue("NatsPingInterval")
npi, _ := strconv.Atoi(natsPingInterval)
return &rmm.AgentConfig{
BaseURL: baseurl,
@@ -78,16 +81,18 @@ func NewAgentConfig() *rmm.AgentConfig {
NatsProxyPath: natsProxyPath,
NatsProxyPort: natsProxyPort,
NatsStandardPort: natsStandardPort,
NatsPingInterval: npi,
}
}
func (a *Agent) RunScript(code string, shell string, args []string, timeout int) (stdout, stderr string, exitcode int, e error) {
func (a *Agent) RunScript(code string, shell string, args []string, timeout int, runasuser bool, envVars []string) (stdout, stderr string, exitcode int, e error) {
content := []byte(code)
dir := filepath.Join(os.TempDir(), "trmm")
if !trmm.FileExists(dir) {
a.CreateTRMMTempDir()
err := createWinTempDir()
if err != nil {
a.Logger.Errorln(err)
return "", err.Error(), 85, err
}
const defaultExitCode = 1
@@ -109,7 +114,7 @@ func (a *Agent) RunScript(code string, shell string, args []string, timeout int)
ext = "*.bat"
}
tmpfn, err := ioutil.TempFile(dir, ext)
tmpfn, err := ioutil.TempFile(winTempDir, ext)
if err != nil {
a.Logger.Errorln(err)
return "", err.Error(), 85, err
@@ -143,11 +148,24 @@ func (a *Agent) RunScript(code string, shell string, args []string, timeout int)
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second)
defer cancel()
var timedOut bool = false
var timedOut = false
cmd := exec.Command(exe, cmdArgs...)
if runasuser {
token, err := wintoken.GetInteractiveToken(wintoken.TokenImpersonation)
if err != nil {
return "", err.Error(), 66, err
}
defer token.Close()
cmd.SysProcAttr = &syscall.SysProcAttr{Token: syscall.Token(token.Token()), HideWindow: true}
}
cmd.Stdout = &outb
cmd.Stderr = &errb
if len(envVars) > 0 {
cmd.Env = os.Environ()
cmd.Env = append(cmd.Env, envVars...)
}
if cmdErr := cmd.Start(); cmdErr != nil {
a.Logger.Debugln(cmdErr)
return "", cmdErr.Error(), 65, cmdErr
@@ -230,7 +248,7 @@ func CMD(exe string, args []string, timeout int, detached bool) (output [2]strin
return [2]string{CleanString(outb.String()), CleanString(errb.String())}, nil
}
func CMDShell(shell string, cmdArgs []string, command string, timeout int, detached bool) (output [2]string, e error) {
func CMDShell(shell string, cmdArgs []string, command string, timeout int, detached bool, runasuser bool) (output [2]string, e error) {
var (
outb bytes.Buffer
errb bytes.Buffer
@@ -241,6 +259,8 @@ func CMDShell(shell string, cmdArgs []string, command string, timeout int, detac
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeout)*time.Second)
defer cancel()
sysProcAttr := &windows.SysProcAttr{}
if len(cmdArgs) > 0 && command == "" {
switch shell {
case "cmd":
@@ -254,9 +274,7 @@ func CMDShell(shell string, cmdArgs []string, command string, timeout int, detac
switch shell {
case "cmd":
cmd = exec.Command("cmd.exe")
cmd.SysProcAttr = &windows.SysProcAttr{
CmdLine: fmt.Sprintf("cmd.exe /C %s", command),
}
sysProcAttr.CmdLine = fmt.Sprintf("cmd.exe /C %s", command)
case "powershell":
cmd = exec.Command("Powershell", "-NonInteractive", "-NoProfile", command)
}
@@ -264,10 +282,20 @@ func CMDShell(shell string, cmdArgs []string, command string, timeout int, detac
// https://docs.microsoft.com/en-us/windows/win32/procthread/process-creation-flags
if detached {
cmd.SysProcAttr = &windows.SysProcAttr{
CreationFlags: windows.DETACHED_PROCESS | windows.CREATE_NEW_PROCESS_GROUP,
}
sysProcAttr.CreationFlags = windows.DETACHED_PROCESS | windows.CREATE_NEW_PROCESS_GROUP
}
if runasuser {
token, err := wintoken.GetInteractiveToken(wintoken.TokenImpersonation)
if err != nil {
return [2]string{"", CleanString(err.Error())}, err
}
defer token.Close()
sysProcAttr.Token = syscall.Token(token.Token())
sysProcAttr.HideWindow = true
}
cmd.SysProcAttr = sysProcAttr
cmd.Stdout = &outb
cmd.Stderr = &errb
cmd.Start()
@@ -449,7 +477,7 @@ func (a *Agent) PlatVer() (string, error) {
func EnablePing() {
args := make([]string, 0)
cmd := `netsh advfirewall firewall add rule name="ICMP Allow incoming V4 echo request" protocol=icmpv4:8,any dir=in action=allow`
_, err := CMDShell("cmd", args, cmd, 10, false)
_, err := CMDShell("cmd", args, cmd, 10, false, false)
if err != nil {
fmt.Println(err)
}
@@ -470,7 +498,7 @@ func EnableRDP() {
args := make([]string, 0)
cmd := `netsh advfirewall firewall set rule group="remote desktop" new enable=Yes`
_, cerr := CMDShell("cmd", args, cmd, 10, false)
_, cerr := CMDShell("cmd", args, cmd, 10, false, false)
if cerr != nil {
fmt.Println(cerr)
}
@@ -497,15 +525,15 @@ func DisableSleepHibernate() {
wg.Add(1)
go func(c string) {
defer wg.Done()
_, _ = CMDShell("cmd", args, fmt.Sprintf("powercfg /set%svalueindex scheme_current sub_buttons lidaction 0", c), 5, false)
_, _ = CMDShell("cmd", args, fmt.Sprintf("powercfg /x -standby-timeout-%s 0", c), 5, false)
_, _ = CMDShell("cmd", args, fmt.Sprintf("powercfg /x -hibernate-timeout-%s 0", c), 5, false)
_, _ = CMDShell("cmd", args, fmt.Sprintf("powercfg /x -disk-timeout-%s 0", c), 5, false)
_, _ = CMDShell("cmd", args, fmt.Sprintf("powercfg /x -monitor-timeout-%s 0", c), 5, false)
_, _ = CMDShell("cmd", args, fmt.Sprintf("powercfg /set%svalueindex scheme_current sub_buttons lidaction 0", c), 5, false, false)
_, _ = CMDShell("cmd", args, fmt.Sprintf("powercfg /x -standby-timeout-%s 0", c), 5, false, false)
_, _ = CMDShell("cmd", args, fmt.Sprintf("powercfg /x -hibernate-timeout-%s 0", c), 5, false, false)
_, _ = CMDShell("cmd", args, fmt.Sprintf("powercfg /x -disk-timeout-%s 0", c), 5, false, false)
_, _ = CMDShell("cmd", args, fmt.Sprintf("powercfg /x -monitor-timeout-%s 0", c), 5, false, false)
}(i)
}
wg.Wait()
_, _ = CMDShell("cmd", args, "powercfg -S SCHEME_CURRENT", 5, false)
_, _ = CMDShell("cmd", args, "powercfg -S SCHEME_CURRENT", 5, false, false)
}
// NewCOMObject creates a new COM object for the specifed ProgramID.
@@ -557,15 +585,17 @@ func (a *Agent) UninstallCleanup() {
a.PatchMgmnt(false)
a.CleanupAgentUpdates()
CleanupSchedTasks()
os.RemoveAll(winTempDir)
}
func (a *Agent) AgentUpdate(url, inno, version string) {
time.Sleep(time.Duration(randRange(1, 15)) * time.Second)
a.KillHungUpdates()
time.Sleep(1 * time.Second)
a.CleanupAgentUpdates()
updater := filepath.Join(a.ProgramDir, inno)
updater := filepath.Join(winTempDir, inno)
a.Logger.Infof("Agent updating from %s to %s", a.Version, version)
a.Logger.Infoln("Downloading agent update from", url)
a.Logger.Debugln("Downloading agent update from", url)
rClient := resty.New()
rClient.SetCloseConnection(true)
@@ -586,14 +616,7 @@ func (a *Agent) AgentUpdate(url, inno, version string) {
return
}
dir, err := ioutil.TempDir("", "tacticalrmm")
if err != nil {
a.Logger.Errorln("Agentupdate create tempdir:", err)
CMD("net", []string{"start", winSvcName}, 10, false)
return
}
innoLogFile := filepath.Join(dir, "tacticalrmm.txt")
innoLogFile := filepath.Join(winTempDir, fmt.Sprintf("tacticalagent_update_v%s.txt", version))
args := []string{"/C", updater, "/VERYSILENT", fmt.Sprintf("/LOG=%s", innoLogFile)}
cmd := exec.Command("cmd.exe", args...)
@@ -638,19 +661,6 @@ func (a *Agent) AgentUninstall(code string) {
cmd.Start()
}
func (a *Agent) addDefenderExlusions() {
code := `
Add-MpPreference -ExclusionPath 'C:\Program Files\TacticalAgent\*'
Add-MpPreference -ExclusionPath 'C:\Windows\Temp\tacticalagent-v*.exe'
Add-MpPreference -ExclusionPath 'C:\Windows\Temp\trmm\*'
Add-MpPreference -ExclusionPath 'C:\Program Files\Mesh Agent\*'
`
_, _, _, err := a.RunScript(code, "powershell", []string{}, 20)
if err != nil {
a.Logger.Debugln(err)
}
}
// RunMigrations cleans up unused stuff from older agents
func (a *Agent) RunMigrations() {
for _, i := range []string{"nssm.exe", "nssm-x86.exe"} {
@@ -853,6 +863,43 @@ func (a *Agent) InstallService() error {
return service.Control(s, "install")
}
func (a *Agent) GetAgentCheckInConfig(ret AgentCheckInConfig) AgentCheckInConfig {
// if local config present, overwrite
k, err := registry.OpenKey(registry.LOCAL_MACHINE, `SOFTWARE\TacticalRMM`, registry.ALL_ACCESS)
if err == nil {
if checkInHello, _, err := k.GetStringValue("CheckInHello"); err == nil {
ret.Hello = regRangeToInt(checkInHello)
}
if checkInAgentInfo, _, err := k.GetStringValue("CheckInAgentInfo"); err == nil {
ret.AgentInfo = regRangeToInt(checkInAgentInfo)
}
if checkInWinSvc, _, err := k.GetStringValue("CheckInWinSvc"); err == nil {
ret.WinSvc = regRangeToInt(checkInWinSvc)
}
if checkInPubIP, _, err := k.GetStringValue("CheckInPubIP"); err == nil {
ret.PubIP = regRangeToInt(checkInPubIP)
}
if checkInDisks, _, err := k.GetStringValue("CheckInDisks"); err == nil {
ret.Disks = regRangeToInt(checkInDisks)
}
if checkInSW, _, err := k.GetStringValue("CheckInSW"); err == nil {
ret.SW = regRangeToInt(checkInSW)
}
if checkInWMI, _, err := k.GetStringValue("CheckInWMI"); err == nil {
ret.WMI = regRangeToInt(checkInWMI)
}
if checkInSyncMesh, _, err := k.GetStringValue("CheckInSyncMesh"); err == nil {
ret.SyncMesh = regRangeToInt(checkInSyncMesh)
}
if checkInLimitData, _, err := k.GetStringValue("CheckInLimitData"); err == nil {
if checkInLimitData == "true" {
ret.LimitData = true
}
}
}
return ret
}
// TODO add to stub
func (a *Agent) NixMeshNodeID() string {
return "not implemented"

View File

@@ -169,7 +169,7 @@ type ScriptCheckResult struct {
// ScriptCheck runs either bat, powershell or python script
func (a *Agent) ScriptCheck(data rmm.Check, r *resty.Client) {
start := time.Now()
stdout, stderr, retcode, _ := a.RunScript(data.Script.Code, data.Script.Shell, data.ScriptArgs, data.Timeout)
stdout, stderr, retcode, _ := a.RunScript(data.Script.Code, data.Script.Shell, data.ScriptArgs, data.Timeout, data.Script.RunAsUser, data.EnvVars)
payload := ScriptCheckResult{
ID: data.CheckPK,

View File

@@ -42,7 +42,7 @@ func (a *Agent) InstallChoco() {
return
}
_, _, exitcode, err := a.RunScript(string(r.Body()), "powershell", []string{}, 900)
_, _, exitcode, err := a.RunScript(string(r.Body()), "powershell", []string{}, 900, false, []string{})
if err != nil {
a.Logger.Debugln(err)
a.rClient.R().SetBody(result).Post(url)

View File

@@ -140,34 +140,57 @@ func (a *Agent) Install(i *Installer) {
installerMeshSystemEXE = a.MeshSystemEXE
}
var meshNodeID string
var meshNodeID, meshOutput string
if runtime.GOOS == "windows" && !i.NoMesh {
mesh := filepath.Join(a.ProgramDir, a.MeshInstaller)
if i.LocalMesh == "" {
if !i.NoMesh && runtime.GOOS != "linux" {
switch runtime.GOOS {
case "windows":
meshOutput = filepath.Join(a.ProgramDir, a.MeshInstaller)
case "darwin":
tmp, err := createTmpFile()
if err != nil {
a.Logger.Fatalln("Failed to create mesh temp file", err)
}
meshOutput = tmp.Name()
os.Chmod(meshOutput, 0755)
defer os.Remove(meshOutput)
defer os.Remove(meshOutput + ".msh")
}
if runtime.GOOS == "windows" && i.LocalMesh != "" {
err := copyFile(i.LocalMesh, meshOutput)
if err != nil {
a.installerMsg(err.Error(), "error", i.Silent)
}
} else {
a.Logger.Infoln("Downloading mesh agent...")
payload := map[string]string{"goarch": a.GoArch, "plat": a.Platform}
r, err := rClient.R().SetBody(payload).SetOutput(mesh).Post(fmt.Sprintf("%s/api/v3/meshexe/", baseURL))
r, err := rClient.R().SetBody(payload).SetOutput(meshOutput).Post(fmt.Sprintf("%s/api/v3/meshexe/", baseURL))
if err != nil {
a.installerMsg(fmt.Sprintf("Failed to download mesh agent: %s", err.Error()), "error", i.Silent)
}
if r.StatusCode() != 200 {
a.installerMsg(fmt.Sprintf("Unable to download the mesh agent from the RMM. %s", r.String()), "error", i.Silent)
}
} else {
err := copyFile(i.LocalMesh, mesh)
if err != nil {
a.installerMsg(err.Error(), "error", i.Silent)
}
}
a.Logger.Infoln("Installing mesh agent...")
a.Logger.Debugln("Mesh agent:", mesh)
a.Logger.Debugln("Mesh agent:", meshOutput)
time.Sleep(1 * time.Second)
meshNodeID, err = a.installMesh(mesh, installerMeshSystemEXE, i.Proxy)
if err != nil {
a.installerMsg(fmt.Sprintf("Failed to install mesh agent: %s", err.Error()), "error", i.Silent)
if runtime.GOOS == "windows" {
meshNodeID, err = a.installMesh(meshOutput, installerMeshSystemEXE, i.Proxy)
if err != nil {
a.installerMsg(fmt.Sprintf("Failed to install mesh agent: %s", err.Error()), "error", i.Silent)
}
} else {
opts := a.NewCMDOpts()
opts.Command = fmt.Sprintf("%s -install --installPath=%s", meshOutput, nixMeshDir)
out := a.CmdV2(opts)
if out.Status.Exit != 0 {
a.Logger.Fatalln("Error installing mesh agent:", out.Stderr)
}
fmt.Println(out.Stdout)
}
}
@@ -219,18 +242,62 @@ func (a *Agent) Install(i *Installer) {
// check in once
a.DoNatsCheckIn()
if runtime.GOOS == "darwin" {
os.MkdirAll(nixAgentDir, 0755)
self, _ := os.Executable()
copyFile(self, nixAgentBin)
os.Chmod(nixAgentBin, 0755)
svc := fmt.Sprintf(`
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>%s</string>
<key>ServiceDescription</key>
<string>TacticalAgent Service</string>
<key>ProgramArguments</key>
<array>
<string>%s</string>
<string>-m</string>
<string>svc</string>
</array>
<key>WorkingDirectory</key>
<string>%s/</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
`, macPlistName, nixAgentBin, nixAgentDir)
os.WriteFile(macPlistPath, []byte(svc), 0644)
opts := a.NewCMDOpts()
opts.Command = fmt.Sprintf("launchctl bootstrap system %s", macPlistPath)
a.CmdV2(opts)
}
if runtime.GOOS == "windows" {
// send software api
a.SendSoftware()
a.Logger.Debugln("Creating temp dir")
a.CreateTRMMTempDir()
err := createWinTempDir()
if err != nil {
a.Logger.Errorln("Install() createWinTempDir():", err)
}
a.Logger.Debugln("Disabling automatic windows updates")
a.PatchMgmnt(true)
a.Logger.Infoln("Installing service...")
err := a.InstallService()
err = a.InstallService()
if err != nil {
a.installerMsg(err.Error(), "error", i.Silent)
}
@@ -242,9 +309,6 @@ func (a *Agent) Install(i *Installer) {
a.installerMsg(out.ErrorMsg, "error", i.Silent)
}
a.Logger.Infoln("Adding windows defender exclusions")
a.addDefenderExlusions()
if i.Power {
a.Logger.Infoln("Disabling sleep/hibernate...")
DisableSleepHibernate()

View File

@@ -15,17 +15,16 @@ https://license.tacticalrmm.com
package agent
import (
"fmt"
"log"
"os"
"runtime"
"time"
"github.com/spf13/viper"
trmm "github.com/wh1te909/trmm-shared"
)
const (
etcConfig = "/etc/tacticalagent"
)
func (a *Agent) checkExistingAndRemove(silent bool) {}
func (a *Agent) installerMsg(msg, alert string, silent bool) {
if alert == "error" {
a.Logger.Fatalln(msg)
@@ -51,7 +50,31 @@ func createAgentConfig(baseurl, agentid, apiurl, token, agentpk, cert, proxy, me
}
}
func (a *Agent) addDefenderExlusions() {}
func (a *Agent) checkExistingAndRemove(silent bool) {
if runtime.GOOS == "darwin" {
if trmm.FileExists(a.MeshSystemEXE) {
a.Logger.Infoln("Existing meshagent found, attempting to remove...")
uopts := a.NewCMDOpts()
uopts.Command = fmt.Sprintf("%s -fulluninstall", a.MeshSystemEXE)
uout := a.CmdV2(uopts)
fmt.Println(uout.Stdout)
time.Sleep(1 * time.Second)
}
if trmm.FileExists(macPlistPath) {
a.Logger.Infoln("Existing tacticalagent plist found, attempting to remove...")
opts := a.NewCMDOpts()
opts.Command = fmt.Sprintf("launchctl bootout system %s", macPlistPath)
a.CmdV2(opts)
}
os.RemoveAll(defaultMacMeshSvcDir)
os.RemoveAll(nixMeshDir)
os.Remove(etcConfig)
os.RemoveAll(nixAgentDir)
os.Remove(macPlistPath)
}
}
func DisableSleepHibernate() {}

View File

@@ -40,6 +40,8 @@ type NatsMsg struct {
PatchMgmt bool `json:"patch_mgmt"`
ID int `json:"id"`
Code string `json:"code"`
RunAsUser bool `json:"run_as_user"`
EnvVars []string `json:"env_vars"`
}
var (
@@ -50,15 +52,20 @@ var (
func (a *Agent) RunRPC() {
a.Logger.Infoln("Agent service started")
go a.RunAsService()
var wg sync.WaitGroup
wg.Add(1)
opts := a.setupNatsOptions()
nc, err := nats.Connect(a.NatsServer, opts...)
a.Logger.Debugf("%+v\n", nc)
a.Logger.Debugf("%+v\n", nc.Opts)
if err != nil {
a.Logger.Fatalln("RunRPC() nats.Connect()", err)
}
go a.RunAsService(nc)
var wg sync.WaitGroup
wg.Add(1)
nc.Subscribe(a.AgentID, func(msg *nats.Msg) {
var payload *NatsMsg
var mh codec.MsgpackHandle
@@ -177,7 +184,7 @@ func (a *Agent) RunRPC() {
switch runtime.GOOS {
case "windows":
out, _ := CMDShell(p.Data["shell"], []string{}, p.Data["command"], p.Timeout, false)
out, _ := CMDShell(p.Data["shell"], []string{}, p.Data["command"], p.Timeout, false, p.RunAsUser)
a.Logger.Debugln(out)
if out[1] != "" {
ret.Encode(out[1])
@@ -257,7 +264,7 @@ func (a *Agent) RunRPC() {
var resultData rmm.RunScriptResp
ret := codec.NewEncoderBytes(&resp, new(codec.MsgpackHandle))
start := time.Now()
stdout, stderr, retcode, err := a.RunScript(p.Data["code"], p.Data["shell"], p.ScriptArgs, p.Timeout)
stdout, stderr, retcode, err := a.RunScript(p.Data["code"], p.Data["shell"], p.ScriptArgs, p.Timeout, p.RunAsUser, p.EnvVars)
resultData.ExecTime = time.Since(start).Seconds()
resultData.ID = p.ID
@@ -287,7 +294,7 @@ func (a *Agent) RunRPC() {
var retData rmm.RunScriptResp
ret := codec.NewEncoderBytes(&resp, new(codec.MsgpackHandle))
start := time.Now()
stdout, stderr, retcode, err := a.RunScript(p.Data["code"], p.Data["shell"], p.ScriptArgs, p.Timeout)
stdout, stderr, retcode, err := a.RunScript(p.Data["code"], p.Data["shell"], p.ScriptArgs, p.Timeout, p.RunAsUser, p.EnvVars)
retData.ExecTime = time.Since(start).Seconds()
if err != nil {
@@ -478,6 +485,7 @@ func (a *Agent) RunRPC() {
atomic.StoreUint32(&agentUpdateLocker, 0)
nc.Flush()
nc.Close()
a.ControlService(winSvcName, "stop")
os.Exit(0)
}
}(payload)

View File

@@ -12,55 +12,76 @@ https://license.tacticalrmm.com
package agent
import (
"fmt"
"runtime"
"sync"
"time"
nats "github.com/nats-io/nats.go"
)
func (a *Agent) RunAsService() {
func (a *Agent) RunAsService(nc *nats.Conn) {
var wg sync.WaitGroup
wg.Add(1)
go a.AgentSvc()
go a.AgentSvc(nc)
go a.CheckRunner()
wg.Wait()
}
func (a *Agent) AgentSvc() {
go a.GetPython(false)
type AgentCheckInConfig struct {
Hello int `json:"checkin_hello"`
AgentInfo int `json:"checkin_agentinfo"`
WinSvc int `json:"checkin_winsvc"`
PubIP int `json:"checkin_pubip"`
Disks int `json:"checkin_disks"`
SW int `json:"checkin_sw"`
WMI int `json:"checkin_wmi"`
SyncMesh int `json:"checkin_syncmesh"`
LimitData bool `json:"limit_data"`
}
a.CreateTRMMTempDir()
func (a *Agent) AgentSvc(nc *nats.Conn) {
if runtime.GOOS == "windows" {
go a.GetPython(false)
err := createWinTempDir()
if err != nil {
a.Logger.Errorln("AgentSvc() createWinTempDir():", err)
}
}
a.RunMigrations()
sleepDelay := randRange(14, 22)
sleepDelay := randRange(7, 25)
a.Logger.Debugf("AgentSvc() sleeping for %v seconds", sleepDelay)
time.Sleep(time.Duration(sleepDelay) * time.Second)
opts := a.setupNatsOptions()
nc, err := nats.Connect(a.NatsServer, opts...)
if err != nil {
a.Logger.Fatalln("AgentSvc() nats.Connect()", err)
}
conf := a.GetAgentCheckInConfig(a.GetCheckInConfFromAPI())
a.Logger.Debugf("+%v\n", conf)
for _, s := range natsCheckin {
a.NatsMessage(nc, s)
time.Sleep(time.Duration(randRange(100, 400)) * time.Millisecond)
if conf.LimitData && stringInSlice(s, limitNatsData) {
continue
} else {
a.NatsMessage(nc, s)
time.Sleep(time.Duration(randRange(100, 400)) * time.Millisecond)
}
}
go a.SyncMeshNodeID()
time.Sleep(time.Duration(randRange(1, 3)) * time.Second)
a.AgentStartup()
a.SendSoftware()
if runtime.GOOS == "windows" && !conf.LimitData {
a.AgentStartup()
a.SendSoftware()
}
checkInHelloTicker := time.NewTicker(time.Duration(randRange(30, 60)) * time.Second)
checkInAgentInfoTicker := time.NewTicker(time.Duration(randRange(200, 400)) * time.Second)
checkInWinSvcTicker := time.NewTicker(time.Duration(randRange(2400, 3000)) * time.Second)
checkInPubIPTicker := time.NewTicker(time.Duration(randRange(300, 500)) * time.Second)
checkInDisksTicker := time.NewTicker(time.Duration(randRange(1000, 2000)) * time.Second)
checkInSWTicker := time.NewTicker(time.Duration(randRange(2800, 3500)) * time.Second)
checkInWMITicker := time.NewTicker(time.Duration(randRange(3000, 4000)) * time.Second)
syncMeshTicker := time.NewTicker(time.Duration(randRange(800, 1200)) * time.Second)
checkInHelloTicker := time.NewTicker(time.Duration(conf.Hello) * time.Second)
checkInAgentInfoTicker := time.NewTicker(time.Duration(conf.AgentInfo) * time.Second)
checkInWinSvcTicker := time.NewTicker(time.Duration(conf.WinSvc) * time.Second)
checkInPubIPTicker := time.NewTicker(time.Duration(conf.PubIP) * time.Second)
checkInDisksTicker := time.NewTicker(time.Duration(conf.Disks) * time.Second)
checkInSWTicker := time.NewTicker(time.Duration(conf.SW) * time.Second)
checkInWMITicker := time.NewTicker(time.Duration(conf.WMI) * time.Second)
syncMeshTicker := time.NewTicker(time.Duration(conf.SyncMesh) * time.Second)
for {
select {
@@ -92,3 +113,32 @@ func (a *Agent) AgentStartup() {
a.Logger.Debugln("AgentStartup()", err)
}
}
func (a *Agent) GetCheckInConfFromAPI() AgentCheckInConfig {
ret := AgentCheckInConfig{}
url := fmt.Sprintf("/api/v3/%s/config/", a.AgentID)
r, err := a.rClient.R().SetResult(&AgentCheckInConfig{}).Get(url)
if err != nil {
a.Logger.Debugln("GetAgentCheckInConfig()", err)
ret.Hello = randRange(30, 60)
ret.AgentInfo = randRange(200, 400)
ret.WinSvc = randRange(2400, 3000)
ret.PubIP = randRange(300, 500)
ret.Disks = randRange(1000, 2000)
ret.SW = randRange(2800, 3500)
ret.WMI = randRange(3000, 4000)
ret.SyncMesh = randRange(800, 1200)
ret.LimitData = false
} else {
ret.Hello = r.Result().(*AgentCheckInConfig).Hello
ret.AgentInfo = r.Result().(*AgentCheckInConfig).AgentInfo
ret.WinSvc = r.Result().(*AgentCheckInConfig).WinSvc
ret.PubIP = r.Result().(*AgentCheckInConfig).PubIP
ret.Disks = r.Result().(*AgentCheckInConfig).Disks
ret.SW = r.Result().(*AgentCheckInConfig).SW
ret.WMI = r.Result().(*AgentCheckInConfig).WMI
ret.SyncMesh = r.Result().(*AgentCheckInConfig).SyncMesh
ret.LimitData = r.Result().(*AgentCheckInConfig).LimitData
}
return ret
}

View File

@@ -59,7 +59,7 @@ func (a *Agent) RunTask(id int) error {
action_start := time.Now()
if action.ActionType == "script" {
stdout, stderr, retcode, err := a.RunScript(action.Code, action.Shell, action.Args, action.Timeout)
stdout, stderr, retcode, err := a.RunScript(action.Code, action.Shell, action.Args, action.Timeout, action.RunAsUser, action.EnvVars)
if err != nil {
a.Logger.Debugln(err)
@@ -83,7 +83,7 @@ func (a *Agent) RunTask(id int) error {
} else if action.ActionType == "cmd" {
// out[0] == stdout, out[1] == stderr
out, err := CMDShell(action.Shell, []string{}, action.Command, action.Timeout, false)
out, err := CMDShell(action.Shell, []string{}, action.Command, action.Timeout, false, action.RunAsUser)
if err != nil {
a.Logger.Debugln(err)

View File

@@ -23,6 +23,7 @@ import (
"path/filepath"
"runtime"
goDebug "runtime/debug"
"strconv"
"strings"
"time"
@@ -322,3 +323,19 @@ func createTmpFile() (*os.File, error) {
}
return f, nil
}
func stringInSlice(a string, list []string) bool {
for _, b := range list {
if b == a {
return true
}
}
return false
}
func regRangeToInt(s string) int {
split := strings.Split(s, ",")
min, _ := strconv.Atoi(split[0])
max, _ := strconv.Atoi(split[1])
return randRange(min, max)
}

View File

@@ -3,7 +3,7 @@
<assemblyIdentity
type="win32"
name="TacticalRMM"
version="2.1.1.0"
version="2.4.3.0"
processorArchitecture="*"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>

View File

@@ -1,5 +1,5 @@
#define MyAppName "Tactical RMM Agent"
#define MyAppVersion "2.1.1"
#define MyAppVersion "2.4.3"
#define MyAppPublisher "AmidaWare LLC"
#define MyAppURL "https://github.com/amidaware"
#define MyAppExeName "tacticalrmm.exe"

41
go.mod
View File

@@ -1,25 +1,25 @@
module github.com/amidaware/rmmagent
go 1.18
go 1.19
require (
github.com/StackExchange/wmi v1.2.1
github.com/elastic/go-sysinfo v1.8.1
github.com/elastic/go-sysinfo v1.9.0
github.com/go-ole/go-ole v1.2.6
github.com/go-ping/ping v1.1.0
github.com/go-resty/resty/v2 v2.7.0
github.com/gonutz/w32/v2 v2.4.0
github.com/iamacarpet/go-win64api v0.0.0-20220531131246-e84054eb584d
github.com/nats-io/nats-server/v2 v2.8.4 // indirect
github.com/nats-io/nats.go v1.16.0
github.com/nats-io/nats-server/v2 v2.9.8 // indirect
github.com/nats-io/nats.go v1.20.0
github.com/rickb777/date v1.19.1
github.com/shirou/gopsutil/v3 v3.22.6
github.com/sirupsen/logrus v1.8.1
github.com/shirou/gopsutil/v3 v3.22.10
github.com/sirupsen/logrus v1.9.0
github.com/ugorji/go/codec v1.2.7
github.com/wh1te909/go-win64api v0.0.0-20210906074314-ab23795a6ae5
github.com/wh1te909/trmm-shared v0.0.0-20220227075846-f9f757361139
golang.org/x/net v0.0.0-20220706163947-c90051bbdb60 // indirect
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e
golang.org/x/net v0.0.0-20221014081412-f15817d10f9b // indirect
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec
)
require (
@@ -28,14 +28,15 @@ require (
)
require (
github.com/fourcorelabs/wintoken v1.0.0
github.com/jaypipes/ghw v0.9.0
github.com/kardianos/service v1.2.1
github.com/spf13/viper v1.12.0
github.com/kardianos/service v1.2.2
github.com/spf13/viper v1.14.0
)
require (
github.com/elastic/go-windows v1.0.1 // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/ghodss/yaml v1.0.0 // indirect
github.com/google/cabbie v1.0.3 // indirect
github.com/google/glazier v0.0.0-20220520121753-83447cca4ea7 // indirect
@@ -43,7 +44,6 @@ require (
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/jaypipes/pcidb v1.0.0 // indirect
github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 // indirect
github.com/klauspost/compress v1.15.6 // indirect
github.com/lufia/plan9stats v0.0.0-20220517141722-cf486979b281 // indirect
github.com/magiconair/properties v1.8.6 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
@@ -52,27 +52,26 @@ require (
github.com/nats-io/nuid v1.0.1 // indirect
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect
github.com/pelletier/go-toml v1.9.5 // indirect
github.com/pelletier/go-toml/v2 v2.0.1 // indirect
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
github.com/rickb777/plural v1.4.1 // indirect
github.com/rogpeppe/go-internal v1.8.1 // indirect
github.com/scjalliance/comshim v0.0.0-20190308082608-cf06d2532c4e // indirect
github.com/spf13/afero v1.8.2 // indirect
github.com/spf13/afero v1.9.2 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.4.0 // indirect
github.com/subosito/gotenv v1.4.1 // indirect
github.com/tklauser/go-sysconf v0.3.10 // indirect
github.com/tklauser/numcpus v0.5.0 // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/text v0.4.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/ini.v1 v1.66.6 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/toast.v1 v1.0.0-20180812000517-0a84660828b2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect

98
go.sum
View File

@@ -57,8 +57,8 @@ github.com/creachadair/staticfile v0.1.3/go.mod h1:a3qySzCIXEprDGxk6tSxSI+dBBdLz
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/elastic/go-sysinfo v1.8.1 h1:4Yhj+HdV6WjbCRgGdZpPJ8lZQlXZLKDAeIkmQ/VRvi4=
github.com/elastic/go-sysinfo v1.8.1/go.mod h1:JfllUnzoQV/JRYymbH3dO1yggI3mV2oTKSXsDHM+uIM=
github.com/elastic/go-sysinfo v1.9.0 h1:usICqY/Nw4Mpn9f4LdtpFrKxXroJDe81GaxxUlCckIo=
github.com/elastic/go-sysinfo v1.9.0/go.mod h1:eBD1wEGVaRnRLGecc9iG1z8eOv5HnEdz9+nWd8UAxcE=
github.com/elastic/go-windows v1.0.1 h1:AlYZOldA+UJ0/2nBuqWdo90GFCgG9xuyw9SYzGUtJm0=
github.com/elastic/go-windows v1.0.1/go.mod h1:FoVvqWSun28vaDQPbj2Elfc0JahhPB7WQEGa3c814Ss=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
@@ -67,11 +67,13 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fourcorelabs/wintoken v1.0.0 h1:dskUYLAFHNy1cbS5MXsNFXauQzxieTrZlffQZ0Yu19I=
github.com/fourcorelabs/wintoken v1.0.0/go.mod h1:jKyXHt079W09KwEMbUC9g+R2KDs5kVvSKPUiF5p0ejs=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI=
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
github.com/go-cmd/cmd v1.4.1 h1:JUcEIE84v8DSy02XTZpUDeGKExk2oW3DA10hTjbQwmc=
@@ -138,8 +140,9 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/logger v1.1.0/go.mod h1:w7O8nrRr0xufejBlQMI83MXqRusvREoJdaAxV+CoAB4=
github.com/google/logger v1.1.1/go.mod h1:BkeJZ+1FhQ+/d087r4dzojEg1u2ZX+ZqG1jTUrLM+zQ=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
@@ -186,11 +189,10 @@ github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8
github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/kardianos/service v1.2.1 h1:AYndMsehS+ywIS6RB9KOlcXzteWUzxgMgBymJD7+BYk=
github.com/kardianos/service v1.2.1/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM=
github.com/kardianos/service v1.2.2 h1:ZvePhAHfvo0A7Mftk/tEzqEZ7Q4lgnR8sGz4xu1YX60=
github.com/kardianos/service v1.2.2/go.mod h1:CIMRFEJVL+0DS1a3Nx06NaMn4Dz63Ng6O7dl0qH0zVM=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.15.6 h1:6D9PcO8QWu0JyaQ2zUMmu16T1T+zjjEpP91guRsvDfY=
github.com/klauspost/compress v1.15.6/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU=
github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
@@ -209,11 +211,11 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/nats-io/jwt/v2 v2.2.1-0.20220330180145-442af02fd36a h1:lem6QCvxR0Y28gth9P+wV2K/zYUUAkJ+55U8cpS0p5I=
github.com/nats-io/nats-server/v2 v2.8.4 h1:0jQzze1T9mECg8YZEl8+WYUXb9JKluJfCBriPUtluB4=
github.com/nats-io/nats-server/v2 v2.8.4/go.mod h1:8zZa+Al3WsESfmgSs98Fi06dRWLH5Bnq90m5bKD/eT4=
github.com/nats-io/nats.go v1.16.0 h1:zvLE7fGBQYW6MWaFaRdsgm9qT39PJDQoju+DS8KsO1g=
github.com/nats-io/nats.go v1.16.0/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w=
github.com/nats-io/jwt/v2 v2.3.0 h1:z2mA1a7tIf5ShggOFlR1oBPgd6hGqcDYsISxZByUzdI=
github.com/nats-io/nats-server/v2 v2.9.8 h1:jgxZsv+A3Reb3MgwxaINcNq/za8xZInKhDg9Q0cGN1o=
github.com/nats-io/nats-server/v2 v2.9.8/go.mod h1:AB6hAnGZDlYfqb7CTAm66ZKMZy9DpfierY1/PbpvI2g=
github.com/nats-io/nats.go v1.20.0 h1:T8JJnQfVSdh1CzGiwAOv5hEobYCBho/0EupGznYw0oM=
github.com/nats-io/nats.go v1.20.0/go.mod h1:tLqubohF7t4z3du1QDPYJIQQyhb4wl6DhjxEajSI7UA=
github.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8=
github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4=
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
@@ -228,8 +230,8 @@ github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw=
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU=
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg=
github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -241,8 +243,8 @@ github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:Om
github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c h1:NRoLoZvkBTKvR5gQLgA3e0hqjkY9u1wm+iOL45VN/qI=
github.com/power-devops/perfstat v0.0.0-20220216144756-c35f1ee13d7c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
github.com/rickb777/date v1.14.2/go.mod h1:swmf05C+hN+m8/Xh7gEq3uB6QJDNc5pQBWojKdHetOs=
github.com/rickb777/date v1.19.1 h1:IMcFlWY3PagAcc274tJAag84+dh4ihusPxhu4jaHMwY=
github.com/rickb777/date v1.19.1/go.mod h1:NxzFOW9ZWNeOWWE2kUXLDN59GSuGMsu3E4YVVk+GcVU=
@@ -255,12 +257,12 @@ github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XF
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
github.com/scjalliance/comshim v0.0.0-20190308082608-cf06d2532c4e h1:+/AzLkOdIXEPrAQtwAeWOBnPQ0BnYlBW0aCZmSb47u4=
github.com/scjalliance/comshim v0.0.0-20190308082608-cf06d2532c4e/go.mod h1:9Tc1SKnfACJb9N7cw2eyuI6xzy845G7uZONBsi5uPEA=
github.com/shirou/gopsutil/v3 v3.22.6 h1:FnHOFOh+cYAM0C30P+zysPISzlknLC5Z1G4EAElznfQ=
github.com/shirou/gopsutil/v3 v3.22.6/go.mod h1:EdIubSnZhbAvBS1yJ7Xi+AShB/hxwLHOMz4MCYz7yMs=
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo=
github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
github.com/shirou/gopsutil/v3 v3.22.10 h1:4KMHdfBRYXGF9skjDWiL4RA2N+E8dRdodU/bOZpPoVg=
github.com/shirou/gopsutil/v3 v3.22.10/go.mod h1:QNza6r4YQoydyCfo6rH0blGfKahgibh4dQmV5xdFkQk=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/afero v1.9.2 h1:j49Hj62F0n+DaZ1dDCvhABaPNSGNkt32oRFxI33IEMw=
github.com/spf13/afero v1.9.2/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
@@ -269,20 +271,22 @@ github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ=
github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI=
github.com/spf13/viper v1.14.0 h1:Rg7d3Lo706X9tHsJMUjdiwMpHB7W8WnSVOssIY+JElU=
github.com/spf13/viper v1.14.0/go.mod h1:WT//axPky3FdvXHzGw33dNdXXXfFQqmEalje+egj8As=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.5 h1:s5PTfem8p8EbKQOctVV53k6jCJt3UX4IEJzwh+C324Q=
github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs=
github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs=
github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw=
github.com/tklauser/go-sysconf v0.3.10/go.mod h1:C8XykCvCb+Gn0oNCWPIlcb0RuglQTYaQ2hGm7jmxEFk=
github.com/tklauser/numcpus v0.4.0/go.mod h1:1+UI3pD8NW14VMwdgJNJ1ESk2UnwhAnz5hMwiKKqXCQ=
@@ -315,8 +319,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be h1:fmw3UbQh+nxngCAHrDCCztao/kbYFnWjoqop8dHx05A=
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -387,8 +391,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220706163947-c90051bbdb60 h1:8NSylCMxLW4JvserAndSgFL7aPli6A68yf0bYFTcWCM=
golang.org/x/net v0.0.0-20220706163947-c90051bbdb60/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.0.0-20221014081412-f15817d10f9b h1:tvrvnPFcdzp294diPnrdZZZ8XUt2Tyj7svb7X52iDuU=
golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -409,8 +413,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8=
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -426,7 +430,6 @@ golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -452,7 +455,6 @@ golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -464,11 +466,12 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211107104306-e0b2ad06fe42/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e h1:CsOuNlbOuf0mzxJIefr6Q4uAUetRUwZE4qt7VfzP+xo=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec h1:BkDtF2Ih9xZ7le9ndzTA7KJow28VbQW3odyk/8drmuI=
golang.org/x/sys v0.0.0-20220928140112-f11e5e49a4ec/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -477,13 +480,12 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20220411224347-583f2d630306 h1:+gHMid33q6pen7kv9xvT+JRinntgeXO2AeZVd0AWD3w=
golang.org/x/time v0.0.0-20220411224347-583f2d630306/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@@ -623,15 +625,15 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI=
gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/toast.v1 v1.0.0-20180812000517-0a84660828b2 h1:MZF6J7CV6s/h0HBkfqebrYfKCVEo5iN+wzE4QhV3Evo=
gopkg.in/toast.v1 v1.0.0-20180812000517-0a84660828b2/go.mod h1:s1Sn2yZos05Qfs7NKt867Xe18emOmtsO3eAKbDaon0o=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=

27
main.go
View File

@@ -25,7 +25,7 @@ import (
)
var (
version = "2.1.1"
version = "2.4.3"
log = logrus.New()
logFile *os.File
)
@@ -51,9 +51,6 @@ func main() {
meshDir := flag.String("meshdir", "", "Path to custom meshcentral dir")
meshNodeID := flag.String("meshnodeid", "", "Mesh Node ID")
cert := flag.String("cert", "", "Path to domain CA .pem")
updateurl := flag.String("updateurl", "", "Download link to updater")
inno := flag.String("inno", "", "Inno setup file")
updatever := flag.String("updatever", "", "Update version")
silent := flag.Bool("silent", false, "Do not popup any message boxes during installation")
proxy := flag.String("proxy", "", "Use a http proxy")
flag.Parse()
@@ -85,6 +82,8 @@ func main() {
a.Logger.Debugf("%+v\n", a)
switch *mode {
case "getenv":
fmt.Println(os.Getenv(flag.Arg(0)))
case "nixmeshnodeid":
fmt.Print(a.NixMeshNodeID())
case "installsvc":
@@ -125,12 +124,6 @@ func main() {
return
}
a.RunTask(*taskPK)
case "update":
if *updateurl == "" || *inno == "" || *updatever == "" {
updateUsage()
return
}
a.AgentUpdate(*updateurl, *inno, *updatever)
case "install":
if runtime.GOOS != "windows" {
u, err := user.Current()
@@ -143,7 +136,6 @@ func main() {
}
if *api == "" || *clientID == 0 || *siteID == 0 || *token == "" {
installUsage()
return
}
a.Install(&agent.Installer{
@@ -183,20 +175,9 @@ func setupLogging(level, to *string) {
switch runtime.GOOS {
case "windows":
logFile, _ = os.OpenFile(filepath.Join(os.Getenv("ProgramFiles"), "TacticalAgent", "agent.log"), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0664)
case "linux":
default:
logFile, _ = os.OpenFile(filepath.Join("/var/log/", "tacticalagent.log"), os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0664)
}
log.SetOutput(logFile)
}
}
func installUsage() {
exe, _ := os.Executable()
u := fmt.Sprintf(`Usage: %s -m install -api <https://api.example.com> -client-id X -site-id X -auth <TOKEN>`, exe)
fmt.Println(u)
}
func updateUsage() {
u := `Usage: tacticalrmm.exe -m update -updateurl https://example.com/tacticalagent-vX.X.X.exe -inno tacticalagent-vX.X.X.exe -updatever 1.1.1`
fmt.Println(u)
}

View File

@@ -45,6 +45,7 @@ type AgentConfig struct {
NatsProxyPath string
NatsProxyPort string
NatsStandardPort string
NatsPingInterval int
}
type RunScriptResp struct {
@@ -141,8 +142,10 @@ type AssignedTask struct {
}
type Script struct {
Shell string `json:"shell"`
Code string `json:"code"`
Shell string `json:"shell"`
Code string `json:"code"`
RunAsUser bool `json:"run_as_user"`
EnvVars []string `json:"env_vars"`
}
type CheckInfo struct {
@@ -160,6 +163,7 @@ type Check struct {
Disk string `json:"disk"`
IP string `json:"ip"`
ScriptArgs []string `json:"script_args"`
EnvVars []string `json:"env_vars"`
Timeout int `json:"timeout"`
ServiceName string `json:"svc_name"`
PassStartPending bool `json:"pass_if_start_pending"`
@@ -188,6 +192,8 @@ type TaskAction struct {
Code string `json:"code"`
Args []string `json:"script_args"`
Timeout int `json:"timeout"`
RunAsUser bool `json:"run_as_user"`
EnvVars []string `json:"env_vars"`
}
type AutomatedTask struct {

View File

@@ -2,14 +2,14 @@
"FixedFileInfo": {
"FileVersion": {
"Major": 2,
"Minor": 1,
"Patch": 1,
"Minor": 4,
"Patch": 3,
"Build": 0
},
"ProductVersion": {
"Major": 2,
"Minor": 1,
"Patch": 1,
"Minor": 4,
"Patch": 3,
"Build": 0
},
"FileFlagsMask": "3f",
@@ -22,14 +22,14 @@
"Comments": "",
"CompanyName": "AmidaWare LLC",
"FileDescription": "Tactical RMM Agent",
"FileVersion": "v2.1.1.0",
"FileVersion": "v2.4.3.0",
"InternalName": "tacticalrmm.exe",
"LegalCopyright": "Copyright (c) 2022 AmidaWare LLC",
"LegalTrademarks": "",
"OriginalFilename": "tacticalrmm.exe",
"PrivateBuild": "",
"ProductName": "Tactical RMM Agent",
"ProductVersion": "v2.1.1.0",
"ProductVersion": "v2.4.3.0",
"SpecialBuild": ""
},
"VarFileInfo": {