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

232 lines
6.3 KiB
Go

package extender
import (
"AdaptixServer/core/utils/logs"
"os"
"path/filepath"
"plugin"
"github.com/Adaptix-Framework/axc2"
"github.com/goccy/go-yaml"
)
func NewExtender(teamserver Teamserver) *AdaptixExtender {
return &AdaptixExtender{
ts: teamserver,
listenerModules: make(map[string]adaptix.PluginListener),
agentModules: make(map[string]adaptix.PluginAgent),
serviceModules: make(map[string]adaptix.PluginService),
activeListeners: make(map[string]adaptix.ExtenderListener),
}
}
func (ex *AdaptixExtender) LoadPlugins(extenderFiles []string) {
for _, path := range extenderFiles {
_, err := os.Stat(path)
if err != nil {
logs.Error("", "Config %s not found", path)
continue
}
config_data, err := os.ReadFile(path)
if err != nil {
logs.Error("", "Read file %s error: %s", path, err.Error())
continue
}
var config_map map[string]any
err = yaml.Unmarshal(config_data, &config_map)
if err != nil {
logs.Error("", "Error config %s parse: %s", path, err.Error())
continue
}
extender_type, ok_type := config_map["extender_type"].(string)
if !ok_type {
logs.Error("", "Error config %s parse: extender_type not found", path)
continue
}
if extender_type == "listener" {
ex.LoadPluginListener(path, config_data)
} else if extender_type == "agent" {
ex.LoadPluginAgent(path, config_data)
} else if extender_type == "service" {
ex.LoadPluginService(path, config_data)
} else {
logs.Error("", "Unknown extender_type in %s", path)
}
}
}
func (ex *AdaptixExtender) LoadPluginListener(config_path string, config_data []byte) {
var configListener ExConfigListener
err := yaml.Unmarshal(config_data, &configListener)
if err != nil {
logs.Error("", "Error config parse: %s", err.Error())
return
}
plugin_path := filepath.Dir(config_path) + "/" + configListener.ExtenderFile
plug, err := plugin.Open(plugin_path)
if err != nil {
logs.Error("", "failed to open plugin %s: %s", plugin_path, err.Error())
return
}
sym, err := plug.Lookup("InitPlugin")
if err != nil {
logs.Error("", "failed to find InitPlugin in %s: %s", plugin_path, err.Error())
return
}
pl_InitPlugin, ok := sym.(func(ts any, moduleDir string, listenerDir string) adaptix.PluginListener)
if !ok {
logs.Error("", "unexpected signature from InitPlugin in %s", plugin_path)
return
}
pl_listener := pl_InitPlugin(ex.ts, filepath.Dir(plugin_path), logs.RepoLogsInstance.ListenerPath)
if pl_listener == nil {
logs.Error("", "plugin %s returned nil", plugin_path)
return
}
ax_path := filepath.Dir(config_path) + "/" + configListener.AxFile
ax_content, err := os.ReadFile(ax_path)
if err != nil {
logs.Error("", "failed to read ax file %s: %s", ax_path, err.Error())
return
}
listenerInfo := ListenerInfo{
Name: configListener.ListenerName,
Type: configListener.ListenerType,
Protocol: configListener.Protocol,
AX: string(ax_content),
}
err = ex.ts.TsListenerReg(listenerInfo)
if err != nil {
logs.Error("", "plugin %s does not registered: %s", plugin_path, err.Error())
return
}
ex.listenerModules[listenerInfo.Name] = pl_listener
}
func (ex *AdaptixExtender) LoadPluginAgent(config_path string, config_data []byte) {
var configAgent ExConfigAgent
err := yaml.Unmarshal(config_data, &configAgent)
if err != nil {
logs.Error("", "Error config parse: %s", err.Error())
return
}
ax_path := filepath.Dir(config_path) + "/" + configAgent.AxFile
ax_content, err := os.ReadFile(ax_path)
if err != nil {
logs.Error("", "failed to read ax file %s: %s", ax_path, err.Error())
return
}
agentInfo := AgentInfo{
Name: configAgent.AgentName,
Watermark: configAgent.AgentWatermark,
AX: string(ax_content),
Listeners: configAgent.Listeners,
MultiListeners: configAgent.MultiListeners,
}
plugin_path := filepath.Dir(config_path) + "/" + configAgent.ExtenderFile
plug, err := plugin.Open(plugin_path)
if err != nil {
logs.Error("", "failed to open plugin %s: %s", plugin_path, err.Error())
return
}
sym, err := plug.Lookup("InitPlugin")
if err != nil {
logs.Error("", "failed to find InitPlugin in %s: %s", plugin_path, err.Error())
return
}
pl_InitPlugin, ok := sym.(func(ts any, moduleDir string, watermark string) adaptix.PluginAgent)
if !ok {
logs.Error("", "unexpected signature from InitPlugin in %s", plugin_path)
return
}
pl_agent := pl_InitPlugin(ex.ts, filepath.Dir(plugin_path), agentInfo.Watermark)
if pl_agent == nil {
logs.Error("", "plugin %s returned nil", plugin_path)
return
}
err = ex.ts.TsAgentReg(agentInfo)
if err != nil {
logs.Error("", "plugin %s does not registered: %s", plugin_path, err.Error())
return
}
ex.agentModules[agentInfo.Name] = pl_agent
}
func (ex *AdaptixExtender) LoadPluginService(config_path string, config_data []byte) {
var configService ExConfigService
err := yaml.Unmarshal(config_data, &configService)
if err != nil {
logs.Error("", "Error config parse: %s", err.Error())
return
}
plugin_path := filepath.Dir(config_path) + "/" + configService.ExtenderFile
plug, err := plugin.Open(plugin_path)
if err != nil {
logs.Error("", "failed to open plugin %s: %s", plugin_path, err.Error())
return
}
sym, err := plug.Lookup("InitPlugin")
if err != nil {
logs.Error("", "failed to find InitPlugin in %s: %s", plugin_path, err.Error())
return
}
pl_InitPlugin, ok := sym.(func(ts any, moduleDir string, serviceConfig string) adaptix.PluginService)
if !ok {
logs.Error("", "unexpected signature from InitPlugin in %s", plugin_path)
return
}
pl_service := pl_InitPlugin(ex.ts, filepath.Dir(plugin_path), configService.ServiceConfig)
if pl_service == nil {
logs.Error("", "plugin %s returned nil", plugin_path)
return
}
serviceInfo := ServiceInfo{
Name: configService.ServiceName,
}
if configService.AxFile != "" {
ax_path := filepath.Dir(config_path) + "/" + configService.AxFile
ax_content, err := os.ReadFile(ax_path)
if err != nil {
logs.Warn("", "failed to read ax file %s: %s", ax_path, err.Error())
} else {
serviceInfo.AX = string(ax_content)
}
}
err = ex.ts.TsServiceReg(serviceInfo)
if err != nil {
logs.Error("", "plugin %s does not registered: %s", plugin_path, err.Error())
return
}
ex.serviceModules[serviceInfo.Name] = pl_service
logs.Success("", "Service '%s' loaded", configService.ServiceName)
}