Release 2.4.3
This commit is contained in:
commit
e9fd05bd91
150
agent/agent.go
150
agent/agent.go
@ -40,35 +40,37 @@ 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 (
|
||||
@ -89,6 +91,7 @@ const (
|
||||
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()
|
||||
@ -170,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,
|
||||
}
|
||||
}
|
||||
|
||||
@ -220,7 +234,7 @@ type CmdOptions struct {
|
||||
IsScript bool
|
||||
IsExecutable bool
|
||||
Detached bool
|
||||
Env []string
|
||||
EnvVars []string
|
||||
}
|
||||
|
||||
func (a *Agent) NewCMDOpts() *CmdOptions {
|
||||
@ -249,10 +263,10 @@ func (a *Agent) CmdV2(c *CmdOptions) CmdStatus {
|
||||
})
|
||||
}
|
||||
|
||||
if len(c.Env) > 0 {
|
||||
if len(c.EnvVars) > 0 {
|
||||
cmdOptions.BeforeExec = append(cmdOptions.BeforeExec, func(cmd *exec.Cmd) {
|
||||
cmd.Env = os.Environ()
|
||||
cmd.Env = append(cmd.Env, c.Env...)
|
||||
cmd.Env = append(cmd.Env, c.EnvVars...)
|
||||
})
|
||||
}
|
||||
|
||||
@ -398,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
|
||||
}
|
||||
|
||||
|
@ -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, runasuser bool) (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 := ""
|
||||
@ -491,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 }
|
||||
|
||||
|
@ -65,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,
|
||||
@ -79,10 +81,11 @@ func NewAgentConfig() *rmm.AgentConfig {
|
||||
NatsProxyPath: natsProxyPath,
|
||||
NatsProxyPort: natsProxyPort,
|
||||
NatsStandardPort: natsStandardPort,
|
||||
NatsPingInterval: npi,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Agent) RunScript(code string, shell string, args []string, timeout int, runasuser bool) (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)
|
||||
|
||||
@ -158,6 +161,11 @@ func (a *Agent) RunScript(code string, shell string, args []string, timeout int,
|
||||
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
|
||||
@ -855,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"
|
||||
|
@ -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, data.Script.RunAsUser)
|
||||
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,
|
||||
|
@ -42,7 +42,7 @@ func (a *Agent) InstallChoco() {
|
||||
return
|
||||
}
|
||||
|
||||
_, _, exitcode, err := a.RunScript(string(r.Body()), "powershell", []string{}, 900, false)
|
||||
_, _, 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)
|
||||
|
16
agent/rpc.go
16
agent/rpc.go
@ -41,6 +41,7 @@ type NatsMsg struct {
|
||||
ID int `json:"id"`
|
||||
Code string `json:"code"`
|
||||
RunAsUser bool `json:"run_as_user"`
|
||||
EnvVars []string `json:"env_vars"`
|
||||
}
|
||||
|
||||
var (
|
||||
@ -51,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
|
||||
@ -258,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, p.RunAsUser)
|
||||
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
|
||||
|
||||
@ -288,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, p.RunAsUser)
|
||||
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 {
|
||||
|
84
agent/svc.go
84
agent/svc.go
@ -12,6 +12,7 @@ https://license.tacticalrmm.com
|
||||
package agent
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"sync"
|
||||
"time"
|
||||
@ -19,15 +20,27 @@ import (
|
||||
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() {
|
||||
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"`
|
||||
}
|
||||
|
||||
func (a *Agent) AgentSvc(nc *nats.Conn) {
|
||||
if runtime.GOOS == "windows" {
|
||||
go a.GetPython(false)
|
||||
|
||||
@ -38,37 +51,37 @@ func (a *Agent) AgentSvc() {
|
||||
}
|
||||
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)
|
||||
if runtime.GOOS == "windows" {
|
||||
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 {
|
||||
@ -100,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
|
||||
}
|
||||
|
@ -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, action.RunAsUser)
|
||||
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)
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
<assemblyIdentity
|
||||
type="win32"
|
||||
name="TacticalRMM"
|
||||
version="2.4.2.0"
|
||||
version="2.4.3.0"
|
||||
processorArchitecture="*"/>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<security>
|
||||
|
@ -1,5 +1,5 @@
|
||||
#define MyAppName "Tactical RMM Agent"
|
||||
#define MyAppVersion "2.4.2"
|
||||
#define MyAppVersion "2.4.3"
|
||||
#define MyAppPublisher "AmidaWare LLC"
|
||||
#define MyAppURL "https://github.com/amidaware"
|
||||
#define MyAppExeName "tacticalrmm.exe"
|
||||
|
6
go.mod
6
go.mod
@ -4,13 +4,13 @@ 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.9.6 // indirect
|
||||
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.10
|
||||
@ -55,7 +55,7 @@ require (
|
||||
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
|
||||
|
13
go.sum
13
go.sum
@ -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=
|
||||
@ -212,8 +212,8 @@ github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrk
|
||||
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.3.0 h1:z2mA1a7tIf5ShggOFlR1oBPgd6hGqcDYsISxZByUzdI=
|
||||
github.com/nats-io/nats-server/v2 v2.9.6 h1:RTtK+rv/4CcliOuqGsy58g7MuWkBaWmF5TUNwuUo9Uw=
|
||||
github.com/nats-io/nats-server/v2 v2.9.6/go.mod h1:AB6hAnGZDlYfqb7CTAm66ZKMZy9DpfierY1/PbpvI2g=
|
||||
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=
|
||||
@ -243,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=
|
||||
@ -455,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=
|
||||
|
2
main.go
2
main.go
@ -25,7 +25,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
version = "2.4.2"
|
||||
version = "2.4.3"
|
||||
log = logrus.New()
|
||||
logFile *os.File
|
||||
)
|
||||
|
@ -45,6 +45,7 @@ type AgentConfig struct {
|
||||
NatsProxyPath string
|
||||
NatsProxyPort string
|
||||
NatsStandardPort string
|
||||
NatsPingInterval int
|
||||
}
|
||||
|
||||
type RunScriptResp struct {
|
||||
@ -141,9 +142,10 @@ type AssignedTask struct {
|
||||
}
|
||||
|
||||
type Script struct {
|
||||
Shell string `json:"shell"`
|
||||
Code string `json:"code"`
|
||||
RunAsUser bool `json:"run_as_user"`
|
||||
Shell string `json:"shell"`
|
||||
Code string `json:"code"`
|
||||
RunAsUser bool `json:"run_as_user"`
|
||||
EnvVars []string `json:"env_vars"`
|
||||
}
|
||||
|
||||
type CheckInfo struct {
|
||||
@ -161,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"`
|
||||
@ -190,6 +193,7 @@ type TaskAction struct {
|
||||
Args []string `json:"script_args"`
|
||||
Timeout int `json:"timeout"`
|
||||
RunAsUser bool `json:"run_as_user"`
|
||||
EnvVars []string `json:"env_vars"`
|
||||
}
|
||||
|
||||
type AutomatedTask struct {
|
||||
|
@ -3,13 +3,13 @@
|
||||
"FileVersion": {
|
||||
"Major": 2,
|
||||
"Minor": 4,
|
||||
"Patch": 2,
|
||||
"Patch": 3,
|
||||
"Build": 0
|
||||
},
|
||||
"ProductVersion": {
|
||||
"Major": 2,
|
||||
"Minor": 4,
|
||||
"Patch": 2,
|
||||
"Patch": 3,
|
||||
"Build": 0
|
||||
},
|
||||
"FileFlagsMask": "3f",
|
||||
@ -22,14 +22,14 @@
|
||||
"Comments": "",
|
||||
"CompanyName": "AmidaWare LLC",
|
||||
"FileDescription": "Tactical RMM Agent",
|
||||
"FileVersion": "v2.4.2.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.4.2.0",
|
||||
"ProductVersion": "v2.4.3.0",
|
||||
"SpecialBuild": ""
|
||||
},
|
||||
"VarFileInfo": {
|
||||
|
Loading…
Reference in New Issue
Block a user