diff options
author | terminaldweller <devi@terminaldweller.com> | 2025-08-17 22:06:33 +0000 |
---|---|---|
committer | terminaldweller <devi@terminaldweller.com> | 2025-08-17 22:06:33 +0000 |
commit | fe0fe6da38dbf2b19a6a294a66a01809b8d961c7 (patch) | |
tree | 6d04935d826d27c1694c207ebd251554245e9bc7 | |
parent | addes user agents. added aliases. (diff) | |
download | milla-main.tar.gz milla-main.zip |
-rw-r--r-- | ghost.go | 104 | ||||
-rw-r--r-- | go.mod | 4 | ||||
-rw-r--r-- | go.sum | 9 | ||||
-rw-r--r-- | main.go | 10 | ||||
-rw-r--r-- | plugins/euvd.lua | 72 | ||||
-rw-r--r-- | types.go | 28 | ||||
-rw-r--r-- | useragents.go | 3 |
7 files changed, 227 insertions, 3 deletions
diff --git a/ghost.go b/ghost.go new file mode 100644 index 0000000..d3f4396 --- /dev/null +++ b/ghost.go @@ -0,0 +1,104 @@ +package main + +import ( + "bufio" + "crypto/tls" + "io" + "log" + "net" + "sync" + + ircgomsg "github.com/ergochat/irc-go/ircmsg" +) + +func ghost(serverAddress, listenAddress string) { + listener, err := net.Listen("tcp", listenAddress) + if err != nil { + log.Fatalf("Failed to listen on %s: %v", listenAddress, err) + } + defer listener.Close() + + log.Printf("IRC Bouncer listening on %s", listenAddress) + log.Printf("Connecting clients to IRC server: %s", serverAddress) + + for { + clientConn, err := listener.Accept() + if err != nil { + log.Printf("Failed to accept client connection: %v", err) + + continue + } + + go handleClientConnection(clientConn, serverAddress) + } +} + +func handleClientConnection(clientConn net.Conn, serverAddress string) { + log.Printf("Client connected from: %s", clientConn.RemoteAddr()) + + // ircServerConn, err := net.Dial("tcp", serverAddress) + ircServerConn, err := tls.Dial("tcp", serverAddress, nil) + if err != nil { + log.Printf("Failed to connect to IRC server %s: %v", serverAddress, err) + clientConn.Close() + + return + } + + log.Printf("Successfully connected to IRC server: %s", serverAddress) + + done := make(chan struct{}) + + var once sync.Once + + closeConnections := func() { + once.Do(func() { + clientConn.Close() + ircServerConn.Close() + close(done) + }) + } + + go relay(clientConn, ircServerConn, closeConnections) + + go relay(ircServerConn, clientConn, closeConnections) + + <-done + log.Printf("Connection closed for client: %s", clientConn.RemoteAddr()) +} + +func relay(src, dest net.Conn, closer func()) { + reader := bufio.NewReader(src) + + for { + line, err := reader.ReadString('\n') + if err != nil { + if err != io.EOF { + log.Printf("Relay read error on: %v", err) + } + closer() + + return + } + + msg, err := ircgomsg.ParseLine(line) + if err != nil { + log.Printf("Failed to parse IRC message: %v", err) + } + + if msg.Command == "PRIVMSG" { + } + + if msg.Command == "MSG" { + } + + log.Println(msg) + + _, err = io.WriteString(dest, line) + if err != nil { + closer() + + return + } + } +} @@ -10,6 +10,8 @@ require ( github.com/alecthomas/chroma/v2 v2.16.0 github.com/cenkalti/backoff/v5 v5.0.2 github.com/cjoudrey/gluahttp v0.0.0-20201111170219-25003d9adfa9 + github.com/coyim/otr3 v0.0.0-20230314203300-86897a28af47 + github.com/ergochat/irc-go v0.4.0 github.com/jackc/pgx/v5 v5.7.4 github.com/kohkimakimoto/gluayaml v0.0.0-20160815032708-6fe413d49d73 github.com/layeh/gopher-json v0.0.0-20201124131017-552bb3c4c3bf @@ -29,6 +31,8 @@ require ( cloud.google.com/go/compute/metadata v0.6.0 // indirect github.com/PuerkitoBio/goquery v1.10.3 // indirect github.com/andybalholm/cascadia v1.3.3 // indirect + github.com/awnumar/memcall v0.1.2 // indirect + github.com/coyim/constbn v0.0.0-20230207191538-27f0129d98cd // indirect github.com/dlclark/regexp2 v1.11.5 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/logr v1.4.2 // indirect @@ -18,15 +18,23 @@ github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM= github.com/andybalholm/cascadia v1.3.3/go.mod h1:xNd9bqTn98Ln4DwST8/nG+H0yuB8Hmgu1YHNnWw0GeA= +github.com/awnumar/memcall v0.1.2 h1:7gOfDTL+BJ6nnbtAp9+HQzUFjtP1hEseRQq8eP055QY= +github.com/awnumar/memcall v0.1.2/go.mod h1:S911igBPR9CThzd/hYQQmTc9SWNu3ZHIlCGaWsWsoJo= github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/cjoudrey/gluahttp v0.0.0-20201111170219-25003d9adfa9 h1:rdWOzitWlNYeUsXmz+IQfa9NkGEq3gA/qQ3mOEqBU6o= github.com/cjoudrey/gluahttp v0.0.0-20201111170219-25003d9adfa9/go.mod h1:X97UjDTXp+7bayQSFZk2hPvCTmTZIicUjZQRtkwgAKY= +github.com/coyim/constbn v0.0.0-20230207191538-27f0129d98cd h1:tWNy3iPXxx5wmWH8qm7TuDM9vDLWWj18Pp7uxUQILpo= +github.com/coyim/constbn v0.0.0-20230207191538-27f0129d98cd/go.mod h1:3IbgUXKHr9lHYW0qRClJ+UiGNwcvWm5Ce1iOY2Pe/oA= +github.com/coyim/otr3 v0.0.0-20230314203300-86897a28af47 h1:mL+cP7RQUnuAhGW4+wPouDQEU1YuslV/4vjkcI4Ec2w= +github.com/coyim/otr3 v0.0.0-20230314203300-86897a28af47/go.mod h1:7iUG2JMfJTDx4XgHkrSsCtS3iLGCnuEjuZXoXO3lBrc= 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/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ= github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= +github.com/ergochat/irc-go v0.4.0 h1:0YibCKfAAtwxQdNjLQd9xpIEPisLcJ45f8FNsMHAuZc= +github.com/ergochat/irc-go v0.4.0/go.mod h1:2vi7KNpIPWnReB5hmLpl92eMywQvuIeIIGdt/FQCph0= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -147,6 +155,7 @@ golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -467,6 +467,14 @@ func runCommand( } appConfig.deleteLstate(args[1]) + case "list": + if !isFromAdmin(appConfig.Admins, event) { + break + } + + for key, value := range appConfig.LuaCommands { + client.Cmd.Reply(event, fmt.Sprintf("%s: %s", key, value.Path)) + } case "remind": if len(args) < 2 { //nolint: mnd,gomnd client.Cmd.Message(event.Source.Name, errNotEnoughArgs.Error()) @@ -555,7 +563,7 @@ func runCommand( query = strings.TrimPrefix(cmd, args[0]) } - log.Println(args[1], query) + log.Println("query:", query) response := UserAgentsGet(args[1], query, appConfig) // client.Cmd.Reply(event, response) diff --git a/plugins/euvd.lua b/plugins/euvd.lua new file mode 100644 index 0000000..9b67831 --- /dev/null +++ b/plugins/euvd.lua @@ -0,0 +1,72 @@ +local milla = require("milla") +local os = require("os") +local json = require("json") + +-- https://euvd.enisa.europa.eu/apidoc +function euvd(cli_args) + local args = {} + for i in string.gmatch(cli_args, "%S+") do table.insert(args, i) end + + os.setenv("http_proxy", "http://172.17.0.1:8120") + + local http = require("http") + local url + + local url_latest = + "https://euvdservices.enisa.europa.eu/api/lastvulnerabilities" + local url_exploited = + "https://euvdservices.enisa.europa.eu/api/exploitedvulnerabilities" + local url_critical = + "https://euvdservices.enisa.europa.eu/api/criticalvulnerabilities" + + if args[1] == "latest" then + url = url_latest + elseif args[1] == "exploited" then + url = url_exploited + elseif args[1] == "critical" then + url = url_critical + else + return "Invalid command" + end + + local response, err = http.request("GET", url, {timeout = "10s"}) + if err ~= nil then + print(err) + return err + end + print(response.body) + + local json_response, err = json.decode(response.body) + if err ~= nil then + print(err) + return err + end + + if response.status_code ~= 200 then + return "Error: " .. response.status_code + end + + local result = "" + for k, v in ipairs(json_response) do + result = result .. "id: " .. v["id"] .. "\n" + result = result .. "description: " .. v["description"] .. "\n" + result = result .. "datePublished: " .. v["datePublished"] .. "\n" + result = result .. "dateUpdated: " .. v["dateUpdated"] .. "\n" + result = result .. "baseScore: " .. v["baseScore"] .. "\n" + result = result .. "baseScoreVersion: " .. v["baseScoreVersion"] .. "\n" + result = result .. "baseScoreVector: " .. v["baseScoreVector"] .. "\n" + result = result .. "references: " .. v["references"] .. "\n" + result = result .. "aliases: " .. v["aliases"] .. "\n" + result = result .. "assigner: " .. v["assigner"] .. "\n" + result = result .. "epss: " .. v["epss"] .. "\n" + result = result .. + "----------------------------------------------------------------" .. + "\n" + end + + print(result) + + return result +end + +milla.register_cmd("/plugins/euvd.lua", "euvd", "euvd") @@ -207,7 +207,8 @@ func (config *TomlConfig) deleteTriggeredScript(name string) { } type AppConfig struct { - Ircd map[string]TomlConfig `toml:"ircd"` + Ircd map[string]TomlConfig `toml:"ircd"` + Ghost map[string]GhostNetwork `toml:"ghost"` } type OllamaRequestOptions struct { @@ -328,3 +329,28 @@ type UserAgentResponse struct { type Alias struct { Alias string `toml:"alias"` } + +type GhostRuleSet struct { + DisableAll bool `toml:"disableAll"` + WhiteList []string `toml:"whiteList"` + EnableAll bool `toml:"enableAll"` + BlackList []string `toml:"blackList"` + Outward bool `toml:"outward"` +} + +type GhostNetwork struct { + ServerAddress string `toml:"serverAddress"` + UseTLS bool `toml:"useTLS"` + SkipTLSVerify bool `toml:"skipTLSVerify"` + Nick string `toml:"nick"` + SaslUser string `toml:"saslUser"` + SaslPass string `toml:"saslPass"` + CertPath string `toml:"certPath"` + KeyPath string `toml:"keyPath"` + ListenAddress string `toml:"listenAddress"` + Rephrase bool `toml:"rephrase"` + OllamaEndpoint string `toml:"ollamaEndpoint"` + Instructions []string `toml:"instructions"` + Prompt string `toml:"prompt"` + GhostRuleSets []GhostRuleSet `toml:"ghostRuleSets"` +} diff --git a/useragents.go b/useragents.go index 0c51e61..fd2d3b8 100644 --- a/useragents.go +++ b/useragents.go @@ -29,10 +29,11 @@ func UserAgentsGet(uaActionName, query string, appConfig *TomlConfig) string { userAgentRequest.Agent_Name = appConfig.UserAgentActions[uaActionName].Agent_Name userAgentRequest.Instructions = appConfig.UserAgentActions[uaActionName].Instructions - userAgentRequest.Query = appConfig.UserAgentActions[uaActionName].Query if query != "" { userAgentRequest.Query = query + } else { + userAgentRequest.Query = appConfig.UserAgentActions[uaActionName].Query } log.Println("UserAgentRequest:", appConfig.UserAgentActions[uaActionName]) |