2026-04-06 00:20:51 -05:00

841 lines
22 KiB
Go

package axscript
import (
"AdaptixServer/core/utils/logs"
"encoding/base64"
"encoding/json"
"fmt"
"os"
"path/filepath"
"strings"
"sync"
"github.com/dop251/goja"
)
type TeamserverBridge interface {
TsAgentCommand(agentName string, agentId string, clientName string, hookId string, handlerId string, cmdline string, ui bool, args map[string]any) error
TsAgentConsoleOutput(agentId string, messageType int, message string, clearText string, store bool)
TsAgentConsoleErrorCommand(agentId string, client string, cmdline string, message string, HookId string, HandlerId string)
AxGetAgentContext(agentId string) (agentName string, listenerRegName string, osType int, err error)
AxGetAgents() map[string]interface{}
AxGetAgentInfo(agentId string, property string) interface{}
AxGetAgentIds() []string
AxGetCredentials() []interface{}
AxGetTargets() []interface{}
AxCredentialsAdd(creds []map[string]interface{}) error
AxTargetsAdd(targets []map[string]interface{}) error
AxAgentRemove(agentIds []string) error
AxAgentSetTag(agentIds []string, tag string) error
AxAgentSetMark(agentIds []string, mark string) error
AxAgentSetColor(agentIds []string, background string, foreground string, reset bool) error
AxAgentUpdateData(agentId string, updateData map[string]interface{}) error
AxGetDownloads() []interface{}
AxGetScreenshots() []interface{}
AxGetTunnels() []interface{}
AxGetInterfaces() []string
AxGetAgentMark(agentId string) string
AxUnloadAxScript(name string) error
}
type ScriptManager struct {
mu sync.RWMutex
teamserver TeamserverBridge
CommandStore *CommandStore
HookStore *HookStore
agentEngines map[string]*ScriptEngine
userEngines map[string]*ScriptEngine
axscriptEngines map[string]*ScriptEngine
scriptInfos []ScriptInfo
globalAllowedRoots []string
}
func NewScriptManager(ts TeamserverBridge) *ScriptManager {
return &ScriptManager{
teamserver: ts,
CommandStore: NewCommandStore(),
HookStore: NewHookStore(),
agentEngines: make(map[string]*ScriptEngine),
userEngines: make(map[string]*ScriptEngine),
axscriptEngines: make(map[string]*ScriptEngine),
}
}
/// LOAD SCRIPTS
func (sm *ScriptManager) LoadAgentScript(agentName string, axScript string, listeners []string) error {
engine := NewScriptEngine("agent:"+agentName, sm)
registerFormStubs(engine)
registerMenuStubs(engine)
registerEventStubs(engine)
registerAxBridge(engine)
err := engine.Execute(axScript)
if err != nil {
return fmt.Errorf("failed to execute agent script for '%s': %w", agentName, err)
}
sm.mu.Lock()
sm.agentEngines[agentName] = engine
sm.scriptInfos = append(sm.scriptInfos, ScriptInfo{
Name: agentName,
ScriptType: "agent",
AgentName: agentName,
})
sm.mu.Unlock()
for _, listenerType := range listeners {
sm.executeRegisterCommands(engine, agentName, listenerType)
}
if len(listeners) == 0 {
sm.executeRegisterCommands(engine, agentName, "")
}
return nil
}
func (sm *ScriptManager) LoadAxScript(scriptPath string) error {
abs, err := filepath.Abs(scriptPath)
if err != nil {
return fmt.Errorf("invalid script path '%s': %w", scriptPath, err)
}
_, err = os.Stat(abs)
if err != nil {
return fmt.Errorf("script file not found: %s", abs)
}
content, err := os.ReadFile(abs)
if err != nil {
return fmt.Errorf("failed to read script '%s': %w", abs, err)
}
engine, err := NewScriptEngineFromPath(abs, sm)
if err != nil {
return fmt.Errorf("failed to create engine for '%s': %w", abs, err)
}
registerFormStubs(engine)
registerMenuStubs(engine)
registerEventStubs(engine)
registerAxBridge(engine)
err = engine.Execute(string(content))
if err != nil {
return fmt.Errorf("failed to execute script '%s': %w", abs, err)
}
if engine.GetMetadataNoSave() {
logs.Success("", "Executed axscript '%s' (nosave)", scriptPath)
return nil
}
scriptName := engine.GetMetadataName()
if scriptName == "" {
scriptName = filepath.Base(abs)
}
sm.mu.Lock()
sm.axscriptEngines[abs] = engine
sm.scriptInfos = append(sm.scriptInfos, ScriptInfo{
Name: scriptName,
ScriptType: "axscript",
Path: abs,
})
sm.mu.Unlock()
logs.Success("", "Loaded axscript '%s'", scriptPath)
return nil
}
func (sm *ScriptManager) LoadAxScriptChild(parentEngine *ScriptEngine, scriptPath string) error {
abs, err := filepath.Abs(scriptPath)
if err != nil {
return fmt.Errorf("invalid script path '%s': %w", scriptPath, err)
}
if _, err := os.Stat(abs); err != nil {
return fmt.Errorf("script file not found: %s", abs)
}
content, err := os.ReadFile(abs)
if err != nil {
return fmt.Errorf("failed to read script '%s': %w", abs, err)
}
engine, err := NewScriptEngineFromPath(abs, sm)
if err != nil {
return fmt.Errorf("failed to create engine for '%s': %w", abs, err)
}
for _, root := range parentEngine.allowedRoots {
found := false
for _, r := range engine.allowedRoots {
if r == root {
found = true
break
}
}
if !found {
engine.allowedRoots = append(engine.allowedRoots, root)
}
}
registerFormStubs(engine)
registerMenuStubs(engine)
registerEventStubs(engine)
registerAxBridge(engine)
err = engine.Execute(string(content))
if err != nil {
return fmt.Errorf("failed to execute script '%s': %w", abs, err)
}
if engine.GetMetadataNoSave() {
logs.Success("", "Executed axscript '%s' (nosave)", abs)
return nil
}
scriptName := engine.GetMetadataName()
if scriptName == "" {
scriptName = filepath.Base(abs)
}
sm.mu.Lock()
sm.axscriptEngines[abs] = engine
sm.scriptInfos = append(sm.scriptInfos, ScriptInfo{
Name: scriptName,
ScriptType: "axscript",
Path: abs,
})
sm.mu.Unlock()
logs.Success("", "Loaded axscript '%s'", abs)
return nil
}
func (sm *ScriptManager) ImportAxScript(engine *ScriptEngine, scriptPath string) (string, error) {
abs, err := filepath.Abs(scriptPath)
if err != nil {
return "", fmt.Errorf("invalid script path '%s': %w", scriptPath, err)
}
_, err = engine.ValidatePath(abs)
if err != nil {
return "", err
}
content, err := os.ReadFile(abs)
if err != nil {
return "", fmt.Errorf("failed to read script '%s': %w", abs, err)
}
_, execErr := engine.runtime.RunString(string(content))
if execErr != nil {
return "", fmt.Errorf("failed to import script '%s': %w", abs, execErr)
}
return abs, nil
}
///
func (sm *ScriptManager) executeRegisterCommands(engine *ScriptEngine, agentName string, listenerType string) {
engine.mu.Lock()
rt := engine.runtime
fn := rt.Get("RegisterCommands")
if fn == nil || goja.IsUndefined(fn) {
engine.mu.Unlock()
logs.Warn("", "No RegisterCommands function found in script for '%s'", agentName)
return
}
registerFn, ok := goja.AssertFunction(fn)
if !ok {
engine.mu.Unlock()
logs.Error("", "RegisterCommands is not a function in script for '%s'", agentName)
return
}
result, err := registerFn(goja.Undefined(), rt.ToValue(listenerType))
engine.mu.Unlock()
if err != nil {
logs.Error("", "Error calling RegisterCommands for '%s': %v", agentName, err)
return
}
if result == nil || goja.IsUndefined(result) || goja.IsNull(result) {
logs.Warn("", "RegisterCommands returned nil for '%s'", agentName)
return
}
obj := result.ToObject(rt)
sm.extractCommandsFromResult(engine, agentName, listenerType, obj, "commands_windows", OsWindows)
sm.extractCommandsFromResult(engine, agentName, listenerType, obj, "commands_linux", OsLinux)
sm.extractCommandsFromResult(engine, agentName, listenerType, obj, "commands_macos", OsMac)
}
func (sm *ScriptManager) extractCommandsFromResult(engine *ScriptEngine, agentName string, listenerType string, obj *goja.Object, propName string, osType int) {
prop := obj.Get(propName)
if prop == nil || goja.IsUndefined(prop) || goja.IsNull(prop) {
return
}
var groupBuilder *jsCommandGroupBuilder
exported := prop.Export()
if gb, ok := exported.(*jsCommandGroupBuilder); ok {
groupBuilder = gb
}
if groupBuilder == nil {
if m, ok := exported.(map[string]interface{}); ok {
if gv, exists := m["__group"]; exists {
if gb, ok2 := gv.(*jsCommandGroupBuilder); ok2 {
groupBuilder = gb
}
}
}
}
if groupBuilder == nil {
propObj := prop.ToObject(engine.runtime)
groupVal := propObj.Get("__group")
if groupVal != nil && !goja.IsUndefined(groupVal) && !goja.IsNull(groupVal) {
if gb, ok := groupVal.Export().(*jsCommandGroupBuilder); ok {
groupBuilder = gb
}
}
}
if groupBuilder == nil {
logs.Warn("", "Property '%s' for agent '%s' is not a CommandGroup", propName, agentName)
return
}
group := groupBuilder.ToCommandGroup(agentName)
group.Source = "agent"
sm.CommandStore.RegisterGroups(SourceAgent, agentName, listenerType, osType, []CommandGroup{group}, engine)
}
////////////////////
// /---
func (sm *ScriptManager) LoadUserScript(name string, script string) error {
engine := NewScriptEngine("user:"+name, sm)
registerFormStubs(engine)
registerMenuStubs(engine)
registerEventStubs(engine)
registerAxBridge(engine)
err := engine.Execute(script)
if err != nil {
return fmt.Errorf("failed to execute user script '%s': %w", name, err)
}
sm.mu.Lock()
sm.userEngines[name] = engine
sm.scriptInfos = append(sm.scriptInfos, ScriptInfo{
Name: name,
ScriptType: "user",
})
sm.mu.Unlock()
return nil
}
// /---
func (sm *ScriptManager) UnloadUserScript(name string) error {
sm.mu.Lock()
defer sm.mu.Unlock()
if _, ok := sm.userEngines[name]; !ok {
return fmt.Errorf("user script '%s' not found", name)
}
delete(sm.userEngines, name)
sm.CommandStore.UnregisterByScriptName(SourceUser, name)
for i, info := range sm.scriptInfos {
if info.Name == name && info.ScriptType == "user" {
sm.scriptInfos = append(sm.scriptInfos[:i], sm.scriptInfos[i+1:]...)
break
}
}
return nil
}
// /---
func (sm *ScriptManager) ListScripts() []ScriptInfo {
sm.mu.RLock()
defer sm.mu.RUnlock()
result := make([]ScriptInfo, len(sm.scriptInfos))
copy(result, sm.scriptInfos)
return result
}
func (sm *ScriptManager) ListProfileScriptsWithContent() []ScriptWithContent {
sm.mu.RLock()
defer sm.mu.RUnlock()
var result []ScriptWithContent
for _, info := range sm.scriptInfos {
if info.ScriptType == "axscript" && info.Path != "" {
engine, ok := sm.axscriptEngines[info.Path]
if !ok {
continue
}
var combined strings.Builder
importedFiles := engine.GetImportedFiles()
for _, importPath := range importedFiles {
importContent, err := os.ReadFile(importPath)
if err != nil {
combined.WriteString(fmt.Sprintf("/* import error: %s */\n", importPath))
continue
}
combined.WriteString(fmt.Sprintf("/* inlined: %s */\n", filepath.Base(importPath)))
combined.Write(importContent)
combined.WriteString(fmt.Sprintf("\n/* end: %s */\n\n", filepath.Base(importPath)))
}
mainContent, err := os.ReadFile(info.Path)
if err != nil {
continue
}
combined.Write(mainContent)
result = append(result, ScriptWithContent{
Name: info.Name,
Script: combined.String(),
})
}
}
return result
}
func (sm *ScriptManager) ResolveAndExecutePreHook(agentName string, agentId string, listenerRegName string, os int, cmdline string, args map[string]interface{}) (hookId string, handlerId string, preHookHandled bool, err error) {
resolved, resolveErr := sm.CommandStore.ResolveFromCmdline(agentName, listenerRegName, os, cmdline)
if resolveErr != nil {
return "", "", false, nil
}
cmdDef := resolved.GetEffectiveCommand()
if cmdDef.HasPreHook && cmdDef.PreHookFunc != nil && resolved.Engine != nil {
preHookErr := sm.executePreHook(resolved.Engine, cmdDef.PreHookFunc, agentId, cmdline, args)
if preHookErr != nil {
return "", "", true, preHookErr
}
return "", "", true, nil
}
if cmdDef.HasPostHook && cmdDef.PostHookFunc != nil && resolved.Engine != nil {
hookId = sm.HookStore.RegisterPostHook(resolved.Engine, cmdDef.PostHookFunc, agentId, "server")
}
if cmdDef.HasHandler && cmdDef.HandlerFunc != nil && resolved.Engine != nil {
handlerId = sm.HookStore.RegisterHandler(resolved.Engine, cmdDef.HandlerFunc, agentId, "server")
}
return hookId, handlerId, false, nil
}
// /---
func (sm *ScriptManager) ParseCommandPublic(cmdline string, resolved *ResolvedCommand) (*ParsedCommand, error) {
return ParseCommand(cmdline, resolved)
}
// /---
func (sm *ScriptManager) ExecutePreHookPublic(engine *ScriptEngine, fn goja.Callable, agentId string, cmdline string, args map[string]interface{}) error {
return sm.executePreHook(engine, fn, agentId, cmdline, args)
}
// /---
func (sm *ScriptManager) ResolveFileArgsPublic(engine *ScriptEngine, parsed *ParsedCommand) error {
return sm.resolveFileArgs(engine, parsed)
}
func (sm *ScriptManager) executePreHook(engine *ScriptEngine, fn goja.Callable, agentId string, cmdline string, args map[string]interface{}) error {
argsCopy := make(map[string]interface{}, len(args))
for k, v := range args {
argsCopy[k] = v
}
_, err := engine.CallCallable(fn,
engine.ToValue(agentId),
engine.ToValue(cmdline),
engine.ToValue(argsCopy),
)
return err
}
func (sm *ScriptManager) resolveFileArgs(engine *ScriptEngine, parsed *ParsedCommand) error {
if len(parsed.FileArgs) == 0 {
return nil
}
for _, fa := range parsed.FileArgs {
if fa.OriginalPath == "" {
if fa.Required {
return fmt.Errorf("missing required file argument: %s", fa.ArgName)
}
continue
}
data, err := sm.ReadFileSandboxed(engine, fa.OriginalPath)
if err != nil {
return fmt.Errorf("cannot read file for argument '%s': %w", fa.ArgName, err)
}
parsed.Args[fa.ArgName] = base64.StdEncoding.EncodeToString(data)
}
return nil
}
type agentCommandContext struct {
agentName string
resolved *ResolvedCommand
parsed *ParsedCommand
}
func (sm *ScriptManager) resolveAgentCommand(agentId string, cmdline string) (*agentCommandContext, error) {
if sm.teamserver == nil {
return nil, fmt.Errorf("teamserver not available")
}
agentName, listenerRegName, os, err := sm.teamserver.AxGetAgentContext(agentId)
if err != nil {
return nil, err
}
resolved, resolveErr := sm.CommandStore.ResolveFromCmdline(agentName, listenerRegName, os, cmdline)
if resolveErr != nil {
return nil, resolveErr
}
parsed, parseErr := ParseCommand(cmdline, resolved)
if parseErr != nil {
return nil, parseErr
}
return &agentCommandContext{
agentName: agentName,
resolved: resolved,
parsed: parsed,
}, nil
}
// /---
func (sm *ScriptManager) ExecuteCommand(fromEngine *ScriptEngine, agentId string, cmdline string, postHookFn goja.Callable, handlerFn goja.Callable) error {
ctx, err := sm.resolveAgentCommand(agentId, cmdline)
if err != nil {
return err
}
if fromEngine != nil {
if fileErr := sm.resolveFileArgs(fromEngine, ctx.parsed); fileErr != nil {
return fileErr
}
}
hookId := ""
handlerId := ""
if postHookFn != nil {
hookId = sm.HookStore.RegisterPostHook(fromEngine, postHookFn, agentId, "server")
}
if handlerFn != nil {
handlerId = sm.HookStore.RegisterHandler(fromEngine, handlerFn, agentId, "server")
}
return sm.teamserver.TsAgentCommand(ctx.agentName, agentId, "server", hookId, handlerId, cmdline, false, ctx.parsed.Args)
}
// /---
func (sm *ScriptManager) ExecuteAlias(fromEngine *ScriptEngine, agentId string, aliasCmdline string) error {
ctx, err := sm.resolveAgentCommand(agentId, aliasCmdline)
if err != nil {
return err
}
if fromEngine != nil {
if fileErr := sm.resolveFileArgs(fromEngine, ctx.parsed); fileErr != nil {
return fileErr
}
}
cmdDef := ctx.resolved.GetEffectiveCommand()
if cmdDef.HasPreHook && cmdDef.PreHookFunc != nil && ctx.resolved.Engine != nil {
preHookErr := sm.executePreHook(ctx.resolved.Engine, cmdDef.PreHookFunc, agentId, aliasCmdline, ctx.parsed.Args)
if preHookErr != nil {
return preHookErr
}
return nil
}
hookId := ""
handlerId := ""
if cmdDef.HasPostHook && cmdDef.PostHookFunc != nil && ctx.resolved.Engine != nil {
hookId = sm.HookStore.RegisterPostHook(ctx.resolved.Engine, cmdDef.PostHookFunc, agentId, "server")
}
if cmdDef.HasHandler && cmdDef.HandlerFunc != nil && ctx.resolved.Engine != nil {
handlerId = sm.HookStore.RegisterHandler(ctx.resolved.Engine, cmdDef.HandlerFunc, agentId, "server")
}
return sm.teamserver.TsAgentCommand(ctx.agentName, agentId, "server", hookId, handlerId, aliasCmdline, false, ctx.parsed.Args)
}
func (sm *ScriptManager) ExecuteAliasWithHooks(fromEngine *ScriptEngine, agentId string, displayCmdline string, aliasCmdline string, message string, postHookFn goja.Callable, handlerFn goja.Callable) error {
ctx, err := sm.resolveAgentCommand(agentId, aliasCmdline)
if err != nil {
return err
}
if fromEngine != nil {
if fileErr := sm.resolveFileArgs(fromEngine, ctx.parsed); fileErr != nil {
return fileErr
}
}
cmdDef := ctx.resolved.GetEffectiveCommand()
if cmdDef.HasPreHook && cmdDef.PreHookFunc != nil && ctx.resolved.Engine != nil {
preHookErr := sm.executePreHook(ctx.resolved.Engine, cmdDef.PreHookFunc, agentId, aliasCmdline, ctx.parsed.Args)
if preHookErr != nil {
return preHookErr
}
return nil
}
hookId := ""
handlerId := ""
if postHookFn != nil {
hookId = sm.HookStore.RegisterPostHook(fromEngine, postHookFn, agentId, "server")
} else if cmdDef.HasPostHook && cmdDef.PostHookFunc != nil && ctx.resolved.Engine != nil {
hookId = sm.HookStore.RegisterPostHook(ctx.resolved.Engine, cmdDef.PostHookFunc, agentId, "server")
}
if handlerFn != nil {
handlerId = sm.HookStore.RegisterHandler(fromEngine, handlerFn, agentId, "server")
} else if cmdDef.HasHandler && cmdDef.HandlerFunc != nil && ctx.resolved.Engine != nil {
handlerId = sm.HookStore.RegisterHandler(ctx.resolved.Engine, cmdDef.HandlerFunc, agentId, "server")
}
cmdlineForDisplay := displayCmdline
if cmdlineForDisplay == "" {
cmdlineForDisplay = aliasCmdline
}
if message != "" {
ctx.parsed.Args["message"] = message
}
return sm.teamserver.TsAgentCommand(ctx.agentName, agentId, "server", hookId, handlerId, cmdlineForDisplay, false, ctx.parsed.Args)
}
func (sm *ScriptManager) GetAgents() map[string]interface{} {
if sm.teamserver == nil {
return map[string]interface{}{}
}
return sm.teamserver.AxGetAgents()
}
func (sm *ScriptManager) GetAgentInfo(agentId string, property string) interface{} {
if sm.teamserver == nil {
return nil
}
return sm.teamserver.AxGetAgentInfo(agentId, property)
}
// /---
func (sm *ScriptManager) GetAgentIds() []string {
if sm.teamserver == nil {
return []string{}
}
return sm.teamserver.AxGetAgentIds()
}
// /---
func (sm *ScriptManager) GetCredentials() []interface{} {
if sm.teamserver == nil {
return []interface{}{}
}
return sm.teamserver.AxGetCredentials()
}
// /---
func (sm *ScriptManager) GetTargets() []interface{} {
if sm.teamserver == nil {
return []interface{}{}
}
return sm.teamserver.AxGetTargets()
}
func (sm *ScriptManager) ConsoleMessage(agentId string, msgType int, message string, clearText string) {
if sm.teamserver == nil {
return
}
sm.teamserver.TsAgentConsoleOutput(agentId, msgType, message, clearText, false) // todo underlaycopy
}
// /---
func (sm *ScriptManager) GetCommandsJSON() (string, error) {
allCommands := sm.CommandStore.GetAllCommandsOrdered()
data, err := json.Marshal(allCommands)
if err != nil {
return "", err
}
return string(data), nil
}
// /---
func (sm *ScriptManager) SetGlobalAllowedRoots(roots []string) {
sm.globalAllowedRoots = roots
}
func (sm *ScriptManager) ReadFileSandboxed(engine *ScriptEngine, path string) ([]byte, error) {
validated, err := engine.ValidatePath(path)
if err != nil {
return nil, err
}
return os.ReadFile(validated)
}
// /---
func (sm *ScriptManager) WriteFileSandboxed(engine *ScriptEngine, path string, data []byte, append_ bool) error {
validated, err := engine.ValidatePath(path)
if err != nil {
return err
}
flag := os.O_WRONLY | os.O_CREATE
if append_ {
flag |= os.O_APPEND
} else {
flag |= os.O_TRUNC
}
dir := filepath.Dir(validated)
if err := os.MkdirAll(dir, 0755); err != nil {
return err
}
f, err := os.OpenFile(validated, flag, 0644)
if err != nil {
return err
}
defer f.Close()
_, err = f.Write(data)
return err
}
// /---
func (sm *ScriptManager) GetDownloads() []interface{} {
if sm.teamserver == nil {
return []interface{}{}
}
return sm.teamserver.AxGetDownloads()
}
// /---
func (sm *ScriptManager) GetScreenshots() []interface{} {
if sm.teamserver == nil {
return []interface{}{}
}
return sm.teamserver.AxGetScreenshots()
}
// /---
func (sm *ScriptManager) GetTunnels() []interface{} {
if sm.teamserver == nil {
return []interface{}{}
}
return sm.teamserver.AxGetTunnels()
}
// /---
func (sm *ScriptManager) GetInterfaces() []string {
if sm.teamserver == nil {
return []string{}
}
return sm.teamserver.AxGetInterfaces()
}
// /---
func (sm *ScriptManager) GetAgentMark(agentId string) string {
if sm.teamserver == nil {
return ""
}
return sm.teamserver.AxGetAgentMark(agentId)
}
// /---
func (sm *ScriptManager) UnloadAxScript(name string) error {
if sm.teamserver == nil {
return fmt.Errorf("teamserver not available")
}
return sm.teamserver.AxUnloadAxScript(name)
}
// /---
func (sm *ScriptManager) ValidateCommand(agentId string, cmdline string) (map[string]interface{}, error) {
if sm.teamserver == nil {
return nil, fmt.Errorf("teamserver not available")
}
agentName, listenerRegName, osType, err := sm.teamserver.AxGetAgentContext(agentId)
if err != nil {
return map[string]interface{}{"valid": false, "message": "Agent not found"}, nil
}
resolved, resolveErr := sm.CommandStore.ResolveFromCmdline(agentName, listenerRegName, osType, cmdline)
if resolveErr != nil {
return map[string]interface{}{"valid": false, "message": resolveErr.Error()}, nil
}
parsed, parseErr := ParseCommand(cmdline, resolved)
if parseErr != nil {
return map[string]interface{}{"valid": false, "message": parseErr.Error()}, nil
}
cmdDef := resolved.GetEffectiveCommand()
result := map[string]interface{}{
"valid": true,
"message": "",
"is_pre_hook": cmdDef.HasPreHook,
"has_post_hook": cmdDef.HasPostHook,
"has_handler": cmdDef.HasHandler,
"parsed": parsed.Args,
}
return result, nil
}
// /---
func (sm *ScriptManager) GetCommandNames(agentId string) ([]string, error) {
if sm.teamserver == nil {
return nil, fmt.Errorf("teamserver not available")
}
agentName, listenerRegName, osType, err := sm.teamserver.AxGetAgentContext(agentId)
if err != nil {
return nil, err
}
groups := sm.CommandStore.GetCommandsForAgent(agentName, listenerRegName, osType)
var names []string
for _, g := range groups {
for _, cmd := range g.Commands {
names = append(names, cmd.Name)
}
}
return names, nil
}