From 0e8e81a6078a98803f1012882f8c176fd3b5204e Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 27 Apr 2020 00:38:04 +0300 Subject: Add support for decrypting messages --- matrix/rooms/room.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'matrix/rooms') diff --git a/matrix/rooms/room.go b/matrix/rooms/room.go index 0238cfb..45222e1 100644 --- a/matrix/rooms/room.go +++ b/matrix/rooms/room.go @@ -412,7 +412,7 @@ func (room *Room) UpdateState(evt *event.Event) { case *event.TopicEventContent: room.topicCache = content.Topic case *event.EncryptionEventContent: - if content.Algorithm == event.AlgorithmMegolmV1 { + if content.Algorithm == id.AlgorithmMegolmV1 { room.Encrypted = true } } -- cgit v1.2.3-70-g09d2 From 7d0d701c5014be43f993d34a52e122f41eedc18d Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 28 Apr 2020 00:58:26 +0300 Subject: Add initial support for encrypting messages --- config/config.go | 1 + go.mod | 2 +- go.sum | 2 ++ matrix/matrix.go | 22 +++++++++++++++++++++- matrix/rooms/room.go | 11 +++++++++++ matrix/sync.go | 9 +++++---- 6 files changed, 41 insertions(+), 6 deletions(-) (limited to 'matrix/rooms') diff --git a/config/config.go b/config/config.go index 8234edc..e9e1864 100644 --- a/config/config.go +++ b/config/config.go @@ -118,6 +118,7 @@ func (config *Config) DeleteSession() { config.AuthCache.NextBatch = "" config.AuthCache.InitialSyncDone = false config.AccessToken = "" + config.DeviceID = "" config.Rooms = rooms.NewRoomCache(config.RoomListPath, config.StateDir, config.RoomCacheSize, config.RoomCacheAge, config.GetUserID) config.PushRules = nil diff --git a/go.mod b/go.mod index 8564081..95879d3 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e gopkg.in/toast.v1 v1.0.0-20180812000517-0a84660828b2 gopkg.in/yaml.v2 v2.2.8 - maunium.net/go/mautrix v0.2.0-beta.4.0.20200426213554-b07cb6dc1f6b + maunium.net/go/mautrix v0.2.0-beta.4.0.20200427215704-fe82e2b914c8 maunium.net/go/mauview v0.1.0 maunium.net/go/tcell v0.1.0 ) diff --git a/go.sum b/go.sum index 9d0874b..f3ca71b 100644 --- a/go.sum +++ b/go.sum @@ -84,6 +84,8 @@ gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= maunium.net/go/mautrix v0.2.0-beta.4.0.20200426213554-b07cb6dc1f6b h1:s3+wlMmmtpPUoOGVyS5nyR62htnwD/TEfA0NVbDk7zc= maunium.net/go/mautrix v0.2.0-beta.4.0.20200426213554-b07cb6dc1f6b/go.mod h1:SkGZzch8CvU2qKtNpYxtzZ0sQxfVEJ3IsVVLSUBUx9Y= +maunium.net/go/mautrix v0.2.0-beta.4.0.20200427215704-fe82e2b914c8 h1:xflYDdpEonVTaw1Diq4z3ZK72Y8/TutiQgKOrHgfOCA= +maunium.net/go/mautrix v0.2.0-beta.4.0.20200427215704-fe82e2b914c8/go.mod h1:SkGZzch8CvU2qKtNpYxtzZ0sQxfVEJ3IsVVLSUBUx9Y= maunium.net/go/mauview v0.1.0 h1:x2WdkKI2zdriJuPAB0CKlwmnHGE7W9xfM5z6RgG+IIg= maunium.net/go/mauview v0.1.0/go.mod h1:og9WbzmWe9SNYNyOFlCv8qa9zMcOvG2nzRJ5vYyud9U= maunium.net/go/tcell v0.1.0 h1:XzsEoGCvOw5nac+tlkSLzQcliLYTN4PrtA7ar2ptjSM= diff --git a/matrix/matrix.go b/matrix/matrix.go index 8804103..3d1b279 100644 --- a/matrix/matrix.go +++ b/matrix/matrix.go @@ -870,8 +870,28 @@ func (c *Container) Redact(roomID id.RoomID, eventID id.EventID, reason string) func (c *Container) SendEvent(evt *muksevt.Event) (id.EventID, error) { defer debug.Recover() - c.client.UserTyping(evt.RoomID, false, 0) + _, _ = c.client.UserTyping(evt.RoomID, false, 0) c.typing = 0 + room := c.GetRoom(evt.RoomID) + if room != nil && room.Encrypted { + encrypted, err := c.crypto.EncryptMegolmEvent(evt.RoomID, evt.Type, evt.Content) + if err != nil { + if err != crypto.SessionExpired && err != crypto.SessionNotShared && err != crypto.NoGroupSession { + return "", err + } + debug.Print("Got", err, "while trying to encrypt message, sharing group session and trying again...") + err = c.crypto.ShareGroupSession(room.ID, room.GetMemberList()) + if err != nil { + return "", err + } + encrypted, err = c.crypto.EncryptMegolmEvent(evt.RoomID, evt.Type, evt.Content) + if err != nil { + return "", err + } + } + evt.Type = event.EventEncrypted + evt.Content = event.Content{Parsed: encrypted} + } resp, err := c.client.SendMessageEvent(evt.RoomID, evt.Type, &evt.Content, mautrix.ReqSendEvent{TransactionID: evt.Unsigned.TransactionID}) if err != nil { return "", err diff --git a/matrix/rooms/room.go b/matrix/rooms/room.go index 45222e1..d5d1d8f 100644 --- a/matrix/rooms/room.go +++ b/matrix/rooms/room.go @@ -650,6 +650,17 @@ func (room *Room) GetMembers() map[id.UserID]*Member { return room.memberCache } +func (room *Room) GetMemberList() []id.UserID { + members := room.GetMembers() + memberList := make([]id.UserID, len(members)) + index := 0 + for userID, _ := range members { + memberList[index] = userID + index++ + } + return memberList +} + // GetMember returns the member with the given MXID. // If the member doesn't exist, nil is returned. func (room *Room) GetMember(userID id.UserID) *Member { diff --git a/matrix/sync.go b/matrix/sync.go index 415748e..2136088 100644 --- a/matrix/sync.go +++ b/matrix/sync.go @@ -83,7 +83,7 @@ func (es EventSource) String() string { } type EventHandler func(source EventSource, event *event.Event) -type SyncHandler func(resp *mautrix.RespSync) +type SyncHandler func(resp *mautrix.RespSync, since string) type GomuksSyncer struct { rooms *rooms.RoomCache @@ -122,7 +122,7 @@ func (s *GomuksSyncer) ProcessResponse(res *mautrix.RespSync, since string) (err s.Progress.Step() } wait.Add(len(s.globalListeners)) - s.notifyGlobalListeners(res, callback) + s.notifyGlobalListeners(res, since, callback) wait.Wait() s.processSyncEvents(nil, res.Presence.Events, EventSourcePresence) @@ -158,10 +158,10 @@ func (s *GomuksSyncer) ProcessResponse(res *mautrix.RespSync, since string) (err return } -func (s *GomuksSyncer) notifyGlobalListeners(res *mautrix.RespSync, callback func()) { +func (s *GomuksSyncer) notifyGlobalListeners(res *mautrix.RespSync, since string, callback func()) { for _, listener := range s.globalListeners { go func(listener SyncHandler) { - listener(res) + listener(res, since) callback() }(listener) } @@ -288,6 +288,7 @@ func (s *GomuksSyncer) GetFilterJSON(_ id.UserID) *mautrix.Filter { event.StateCanonicalAlias, event.StatePowerLevels, event.StateTombstone, + event.StateEncryption, }, }, Timeline: mautrix.FilterPart{ -- cgit v1.2.3-70-g09d2 From 22681875f32fa97f65c9a52e2ee666932706ce95 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 5 May 2020 18:39:28 +0300 Subject: Update mautrix-go and give crypto module access to state store --- go.mod | 2 +- go.sum | 2 ++ matrix/matrix.go | 18 +++++++++++++++--- matrix/rooms/roomcache.go | 21 +++++++++++++++++++++ ui/messages/filemessage.go | 4 ++-- 5 files changed, 41 insertions(+), 6 deletions(-) (limited to 'matrix/rooms') diff --git a/go.mod b/go.mod index a3248dc..1cf74ae 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e gopkg.in/toast.v1 v1.0.0-20180812000517-0a84660828b2 gopkg.in/yaml.v2 v2.2.8 - maunium.net/go/mautrix v0.2.0-beta.4.0.20200429002157-8c3bc8eb8f22 + maunium.net/go/mautrix v0.2.0-beta.4.0.20200505153708-a120e7a70f5a maunium.net/go/mauview v0.1.0 maunium.net/go/tcell v0.1.0 ) diff --git a/go.sum b/go.sum index e9acded..03a0f71 100644 --- a/go.sum +++ b/go.sum @@ -92,6 +92,8 @@ maunium.net/go/mautrix v0.2.0-beta.4.0.20200428234424-a14b55c5445f h1:kYrIUjr2v6 maunium.net/go/mautrix v0.2.0-beta.4.0.20200428234424-a14b55c5445f/go.mod h1:SkGZzch8CvU2qKtNpYxtzZ0sQxfVEJ3IsVVLSUBUx9Y= maunium.net/go/mautrix v0.2.0-beta.4.0.20200429002157-8c3bc8eb8f22 h1:hN7gAmWJqII5aiTnVUHA/QM56ImYJvmQJEGwfMos0ts= maunium.net/go/mautrix v0.2.0-beta.4.0.20200429002157-8c3bc8eb8f22/go.mod h1:SkGZzch8CvU2qKtNpYxtzZ0sQxfVEJ3IsVVLSUBUx9Y= +maunium.net/go/mautrix v0.2.0-beta.4.0.20200505153708-a120e7a70f5a h1:5cXujK/NGwGDdllVebkfTfUq/yjfF+lc56Wjjikwl50= +maunium.net/go/mautrix v0.2.0-beta.4.0.20200505153708-a120e7a70f5a/go.mod h1:SkGZzch8CvU2qKtNpYxtzZ0sQxfVEJ3IsVVLSUBUx9Y= maunium.net/go/mauview v0.1.0 h1:x2WdkKI2zdriJuPAB0CKlwmnHGE7W9xfM5z6RgG+IIg= maunium.net/go/mauview v0.1.0/go.mod h1:og9WbzmWe9SNYNyOFlCv8qa9zMcOvG2nzRJ5vYyud9U= maunium.net/go/tcell v0.1.0 h1:XzsEoGCvOw5nac+tlkSLzQcliLYTN4PrtA7ar2ptjSM= diff --git a/matrix/matrix.go b/matrix/matrix.go index 27ed053..fe1aaa5 100644 --- a/matrix/matrix.go +++ b/matrix/matrix.go @@ -139,7 +139,7 @@ func (c *Container) InitClient() error { if err != nil { return err } - c.crypto = crypto.NewOlmMachine(c.client, cryptoLogger{}, cryptoStore) + c.crypto = crypto.NewOlmMachine(c.client, cryptoLogger{}, cryptoStore, c.config.Rooms) err = c.crypto.Load() if err != nil { return err @@ -301,7 +301,7 @@ func (c *Container) Stop() { } c.history = nil debug.Print("Flushing crypto store") - err = c.crypto.Store.Flush() + err = c.crypto.CryptoStore.Flush() if err != nil { debug.Print("Error flushing crypto store:", err) } @@ -356,6 +356,9 @@ func (c *Container) OnLogin() { debug.Print("Initializing syncer") c.syncer = NewGomuksSyncer(c.config.Rooms) c.syncer.OnSync(c.crypto.ProcessSyncResponse) + c.syncer.OnEventType(event.StateMember, func(source EventSource, evt *event.Event) { + c.crypto.HandleMemberEvent(evt) + }) c.syncer.OnEventType(event.EventMessage, c.HandleMessage) c.syncer.OnEventType(event.EventEncrypted, c.HandleEncrypted) c.syncer.OnEventType(event.EventSticker, c.HandleMessage) @@ -993,11 +996,20 @@ func (c *Container) GetHistory(room *rooms.Room, limit int) ([]*muksevt.Event, e return nil, err } debug.Printf("Loaded %d events for %s from server from %s to %s", len(resp.Chunk), room.ID, resp.Start, resp.End) - for _, evt := range resp.Chunk { + for i, evt := range resp.Chunk { err := evt.Content.ParseRaw(evt.Type) if err != nil { debug.Printf("Failed to unmarshal content of event %s (type %s) by %s in %s: %v\n%s", evt.ID, evt.Type.Repr(), evt.Sender, evt.RoomID, err, string(evt.Content.VeryRaw)) } + + if evt.Type == event.EventEncrypted { + decrypted, err := c.crypto.DecryptMegolmEvent(evt) + if err != nil { + debug.Print("Failed to decrypt event:", err) + } else { + resp.Chunk[i] = decrypted + } + } } for _, evt := range resp.State { room.UpdateState(evt) diff --git a/matrix/rooms/roomcache.go b/matrix/rooms/roomcache.go index ffdcad1..d66078c 100644 --- a/matrix/rooms/roomcache.go +++ b/matrix/rooms/roomcache.go @@ -27,6 +27,7 @@ import ( sync "github.com/sasha-s/go-deadlock" "maunium.net/go/gomuks/debug" + "maunium.net/go/mautrix/event" "maunium.net/go/mautrix/id" ) @@ -67,6 +68,26 @@ func (cache *RoomCache) EnableUnloading() { cache.noUnload = false } +func (cache *RoomCache) IsEncrypted(roomID id.RoomID) bool { + room := cache.Get(roomID) + return room != nil && room.Encrypted +} + +func (cache *RoomCache) FindSharedRooms(userID id.UserID) (shared []id.RoomID) { + cache.Lock() + for _, room := range cache.Map { + if !room.Encrypted { + continue + } + member, ok := room.GetMembers()[userID] + if ok && member.Membership == event.MembershipJoin { + shared = append(shared, room.ID) + } + } + cache.Unlock() + return +} + func (cache *RoomCache) LoadList() error { cache.Lock() defer cache.Unlock() diff --git a/ui/messages/filemessage.go b/ui/messages/filemessage.go index d2455ab..3d5e554 100644 --- a/ui/messages/filemessage.go +++ b/ui/messages/filemessage.go @@ -66,9 +66,9 @@ func NewFileMessage(matrix ifc.MatrixContainer, evt *muksevt.Event, displayname return newUIMessage(evt, displayname, &FileMessage{ Type: content.MsgType, Body: content.Body, - URL: content.URL, + URL: content.URL.ParseOrIgnore(), File: file, - Thumbnail: content.GetInfo().ThumbnailURL, + Thumbnail: content.GetInfo().ThumbnailURL.ParseOrIgnore(), ThumbnailFile: thumbnailFile, matrix: matrix, }) -- cgit v1.2.3-70-g09d2 From 4052ec532b7f963ef738f8c5fb0b32759571e8f5 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 6 May 2020 18:43:35 +0300 Subject: Fix potential double locking when finding shared rooms --- matrix/rooms/roomcache.go | 3 +++ 1 file changed, 3 insertions(+) (limited to 'matrix/rooms') diff --git a/matrix/rooms/roomcache.go b/matrix/rooms/roomcache.go index d66078c..067cbb6 100644 --- a/matrix/rooms/roomcache.go +++ b/matrix/rooms/roomcache.go @@ -74,6 +74,8 @@ func (cache *RoomCache) IsEncrypted(roomID id.RoomID) bool { } func (cache *RoomCache) FindSharedRooms(userID id.UserID) (shared []id.RoomID) { + // FIXME this disables unloading so TouchNode wouldn't try to double-lock + cache.DisableUnloading() cache.Lock() for _, room := range cache.Map { if !room.Encrypted { @@ -85,6 +87,7 @@ func (cache *RoomCache) FindSharedRooms(userID id.UserID) (shared []id.RoomID) { } } cache.Unlock() + cache.EnableUnloading() return } -- cgit v1.2.3-70-g09d2