chore: basic working matrix interface
This commit is contained in:
parent
58d53eab76
commit
d129fc97a4
|
@ -4,7 +4,6 @@ import (
|
|||
"net/url"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"dev.l1qu1d.net/wraith-labs/wraith-module-pinecomms/internal/proto"
|
||||
|
@ -28,8 +27,8 @@ type Config struct {
|
|||
// The password to authenticate to the HS with.
|
||||
password string
|
||||
|
||||
// List of MXIDs with admin privileges over the C2.
|
||||
admins []string
|
||||
// The Matrix room where administration occurs.
|
||||
adminRoom string
|
||||
|
||||
// Private key to use as identity on the pinecone network.
|
||||
pineconeId string
|
||||
|
@ -68,7 +67,7 @@ func (c *Config) Setup() {
|
|||
c.homeserver = os.Getenv("WMP_HOMESERVER")
|
||||
c.username = os.Getenv("WMP_USERNAME")
|
||||
c.password = os.Getenv("WMP_PASSWORD")
|
||||
c.admins = strings.Split(os.Getenv("WMP_ADMINS"), " ")
|
||||
c.adminRoom = os.Getenv("WMP_ADMIN_ROOM")
|
||||
c.pineconeId = os.Getenv("WMP_ID_PINECONE")
|
||||
c.logPinecone = logPinecone
|
||||
c.pineconeInboundTcpAddr = os.Getenv("WMP_INBOUND_TCP_PINECONE")
|
||||
|
@ -87,6 +86,10 @@ func (c *Config) Setup() {
|
|||
}
|
||||
|
||||
if c.username == "" || c.password == "" {
|
||||
panic("please provide homeserver username and password")
|
||||
panic("please provide homeserver credentials")
|
||||
}
|
||||
|
||||
if c.adminRoom == "" {
|
||||
panic("please provide an admin room id")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"context"
|
||||
"crypto/ed25519"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
@ -16,14 +15,12 @@ import (
|
|||
|
||||
"dev.l1qu1d.net/wraith-labs/wraith-module-pinecomms/internal/proto"
|
||||
"dev.l1qu1d.net/wraith-labs/wraith-module-pinecomms/internal/radio"
|
||||
"maunium.net/go/mautrix"
|
||||
"maunium.net/go/mautrix/crypto/cryptohelper"
|
||||
"maunium.net/go/mautrix/event"
|
||||
_ "github.com/mattn/go-sqlite3"
|
||||
)
|
||||
|
||||
func main() {
|
||||
//
|
||||
// Create a struct to hold any config values.
|
||||
// Create a struct to hold config values.
|
||||
//
|
||||
|
||||
c := Config{}
|
||||
|
@ -48,13 +45,13 @@ func main() {
|
|||
}
|
||||
pineconeId := ed25519.PrivateKey(pineconeIdBytes)
|
||||
|
||||
// Get a struct for managing pinecone connections.
|
||||
pr := radio.GetInstance()
|
||||
|
||||
//
|
||||
// Configure pinecone manager.
|
||||
//
|
||||
|
||||
// Get a struct for managing pinecone connections.
|
||||
pr := radio.GetInstance()
|
||||
|
||||
pr.SetPineconeIdentity(pineconeId)
|
||||
if c.logPinecone {
|
||||
pr.SetLogger(log.Default())
|
||||
|
@ -74,6 +71,15 @@ func main() {
|
|||
sigchan := make(chan os.Signal, 2)
|
||||
signal.Notify(sigchan, syscall.SIGTERM, syscall.SIGINT)
|
||||
|
||||
//
|
||||
// Set up Matrix comms for C2.
|
||||
//
|
||||
matrixBotCtx, stopMatrixBot := context.WithCancel(context.Background())
|
||||
var matrixBotWait sync.WaitGroup
|
||||
client := MatrixBotInit(matrixBotCtx, c, &matrixBotWait)
|
||||
MatrixBotRunStartup(client, c)
|
||||
MatrixBotEventHandlerSetUp(client, c)
|
||||
|
||||
//
|
||||
// Main body.
|
||||
//
|
||||
|
@ -84,68 +90,9 @@ func main() {
|
|||
// Start pinecone.
|
||||
go pr.Start()
|
||||
|
||||
// Connect to Matrix homeserver.
|
||||
client, err := mautrix.NewClient(c.homeserver, "", "")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
syncer := client.Syncer.(*mautrix.DefaultSyncer)
|
||||
syncer.OnEventType(event.EventMessage, func(source mautrix.EventSource, evt *event.Event) {
|
||||
//
|
||||
})
|
||||
syncer.OnEventType(event.StateMember, func(source mautrix.EventSource, evt *event.Event) {
|
||||
if evt.GetStateKey() == client.UserID.String() && evt.Content.AsMember().Membership == event.MembershipInvite {
|
||||
_, err := client.JoinRoomByID(evt.RoomID)
|
||||
if err == nil {
|
||||
//
|
||||
} else {
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
cryptoHelper, err := cryptohelper.NewCryptoHelper(client, []byte("meow"), "file::memory:")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// You can also store the user/device IDs and access token and put them in the client beforehand instead of using LoginAs.
|
||||
//client.UserID = "..."
|
||||
//client.DeviceID = "..."
|
||||
//client.AccessToken = "..."
|
||||
// You don't need to set a device ID in LoginAs because the crypto helper will set it for you if necessary.
|
||||
cryptoHelper.LoginAs = &mautrix.ReqLogin{
|
||||
Type: mautrix.AuthTypePassword,
|
||||
Identifier: mautrix.UserIdentifier{Type: mautrix.IdentifierTypeUser, User: c.username},
|
||||
Password: c.password,
|
||||
}
|
||||
// If you want to use multiple clients with the same DB, you should set a distinct database account ID for each one.
|
||||
//cryptoHelper.DBAccountID = ""
|
||||
err = cryptoHelper.Init()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Set the client crypto helper in order to automatically encrypt outgoing messages
|
||||
client.Crypto = cryptoHelper
|
||||
|
||||
syncCtx, cancelSync := context.WithCancel(context.Background())
|
||||
var syncStopWait sync.WaitGroup
|
||||
syncStopWait.Add(1)
|
||||
|
||||
go func() {
|
||||
err = client.SyncWithContext(syncCtx)
|
||||
defer syncStopWait.Done()
|
||||
if err != nil && !errors.Is(err, context.Canceled) {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
cancelSync()
|
||||
syncStopWait.Wait()
|
||||
_ = cryptoHelper.Close()
|
||||
client.JoinedRooms()
|
||||
|
||||
// Start receiving messages.
|
||||
// Start receiving Wraith messages.
|
||||
// Background context is okay because the channel will be closed
|
||||
// when the manager exits further down anyway.
|
||||
recv := pr.RecvChan(context.Background())
|
||||
|
@ -204,7 +151,12 @@ mainloop:
|
|||
os.Exit(1)
|
||||
}()
|
||||
|
||||
// Stop pinecone.
|
||||
pr.Stop()
|
||||
|
||||
// Stop Matrix bot.
|
||||
stopMatrixBot()
|
||||
matrixBotWait.Wait()
|
||||
|
||||
os.Exit(0)
|
||||
}
|
||||
|
|
103
cmd/pc3/matrix.go
Normal file
103
cmd/pc3/matrix.go
Normal file
|
@ -0,0 +1,103 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"maunium.net/go/mautrix"
|
||||
"maunium.net/go/mautrix/crypto/cryptohelper"
|
||||
"maunium.net/go/mautrix/event"
|
||||
"maunium.net/go/mautrix/id"
|
||||
)
|
||||
|
||||
func MatrixBotRunStartup(client *mautrix.Client, c Config) {
|
||||
// Make sure we're only ever in the admin room.
|
||||
rooms, err := client.JoinedRooms()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
for _, room := range rooms.JoinedRooms {
|
||||
if room.String() != c.adminRoom {
|
||||
client.LeaveRoom(room)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func MatrixBotEventHandlerSetUp(client *mautrix.Client, c Config) {
|
||||
syncer := client.Syncer.(*mautrix.DefaultSyncer)
|
||||
|
||||
syncer.OnEventType(event.EventMessage, func(source mautrix.EventSource, evt *event.Event) {
|
||||
if evt.RoomID == id.RoomID(c.adminRoom) {
|
||||
client.SendMessageEvent(evt.RoomID, event.EventReaction, &map[string]any{
|
||||
"m.relates_to": map[string]any{
|
||||
"event_id": evt.ID,
|
||||
"key": "🌊",
|
||||
"rel_type": "m.annotation",
|
||||
},
|
||||
})
|
||||
}
|
||||
})
|
||||
syncer.OnEventType(event.StateMember, func(source mautrix.EventSource, evt *event.Event) {
|
||||
if evt.GetStateKey() == client.UserID.String() && evt.Content.AsMember().Membership == event.MembershipInvite {
|
||||
if evt.RoomID == id.RoomID(c.adminRoom) {
|
||||
client.JoinRoomByID(evt.RoomID)
|
||||
} else {
|
||||
client.LeaveRoom(evt.RoomID)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func MatrixBotInit(ctx context.Context, c Config, wg *sync.WaitGroup) *mautrix.Client {
|
||||
// Connect to Matrix homeserver.
|
||||
client, err := mautrix.NewClient(c.homeserver, "", "")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
pickleKey := make([]byte, 64)
|
||||
_, err = rand.Read(pickleKey)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
cryptoHelper, err := cryptohelper.NewCryptoHelper(client, pickleKey, "file::memory:")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
cryptoHelper.LoginAs = &mautrix.ReqLogin{
|
||||
Type: mautrix.AuthTypePassword,
|
||||
Identifier: mautrix.UserIdentifier{Type: mautrix.IdentifierTypeUser, User: c.username},
|
||||
InitialDeviceDisplayName: "WMP-" + fmt.Sprint(time.Now().Unix()),
|
||||
Password: c.password,
|
||||
StoreHomeserverURL: true,
|
||||
}
|
||||
|
||||
// Set the client crypto helper in order to automatically encrypt outgoing messages.
|
||||
err = cryptoHelper.Init()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
client.Crypto = cryptoHelper
|
||||
|
||||
wg.Add(1)
|
||||
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
defer cryptoHelper.Close()
|
||||
|
||||
for {
|
||||
err := client.SyncWithContext(ctx)
|
||||
if err == nil || errors.Is(err, context.Canceled) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
return client
|
||||
}
|
1
go.mod
1
go.mod
|
@ -9,6 +9,7 @@ require (
|
|||
github.com/gorilla/mux v1.8.0
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
github.com/matrix-org/pinecone v0.11.1-0.20230210171230-8c3b24f2649a
|
||||
github.com/mattn/go-sqlite3 v1.14.16
|
||||
maunium.net/go/mautrix v0.15.2
|
||||
)
|
||||
|
||||
|
|
1
go.sum
1
go.sum
|
@ -65,6 +65,7 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
|
|||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg=
|
||||
|
|
Loading…
Reference in New Issue
Block a user